Cuándo usar "EN ACTUALIZACIÓN EN CASCADA"

420

Uso "ON DELETE CASCADE" regularmente pero nunca uso "ON ACTUALIZAR CASCADE" ya que no estoy tan seguro de en qué situación será útil.

En aras de la discusión, veamos un código.

CREATE TABLE parent (
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
);

CREATE TABLE child (
    id INT NOT NULL AUTO_INCREMENT, parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id)
        REFERENCES parent(id)
        ON DELETE CASCADE
);

Para "EN ELIMINAR CASCADA", si idse elimina un padre con un, se eliminará parent_id = parent.idautomáticamente un registro en hijo con . Esto no debería ser un problema.

  1. ¿Esto significa que "EN ACTUALIZACIÓN EN CASCADA" hará lo mismo cuando idse actualice el padre?

  2. Si (1) es verdadero, significa que no hay necesidad de usar "EN ACTUALIZACIÓN EN CASCADA" si parent.idno es actualizable (o nunca se actualizará) como cuando está AUTO_INCREMENTo siempre está configurado TIMESTAMP. ¿Está bien?

  3. Si (2) no es cierto, ¿en qué otro tipo de situación deberíamos usar "EN ACTUALIZACIÓN EN CASCADA"?

  4. ¿Qué sucede si (por alguna razón) actualizo child.parent_idpara que sea algo que no existe, entonces se eliminará automáticamente?

Bueno, lo sé, algunas de las preguntas anteriores se pueden probar mediante programación para comprender, pero también quiero saber si algo de esto depende del proveedor de la base de datos o no.

Por favor, arroja algo de luz.

NawaMan
fuente
1
Ver también: stackoverflow.com/questions/6894162/…
Xiè Jìléi

Respuestas:

468

Es cierto que si su clave principal es solo un valor de identidad autoincrementado, no tendría un uso real para ON UPDATE CASCADE.

Sin embargo, supongamos que su clave principal es un código de barras UPC de 10 dígitos y, debido a la expansión, debe cambiarlo a un código de barras UPC de 13 dígitos. En ese caso, ON UPDATE CASCADE le permitiría cambiar el valor de la clave primaria y cualquier tabla que tenga referencias de clave externa al valor se cambiará en consecuencia.

En referencia al n. ° 4, si cambia la ID secundaria a algo que no existe en la tabla primaria (y tiene integridad referencial), debería obtener un error de clave externa.

C-Pound Guru
fuente
66
Solo tuve que ON UPDATE CASCADEusarme para actualizar las claves primarias en una tabla antigua que no usa una clave de incremento automático
BlueRaja - Danny Pflughoeft
86
  1. Sí, significa que, por ejemplo, si hace UPDATE parent SET id = 20 WHERE id = 10todos los hijos, los parent_id de 10 también se actualizarán a 20

  2. Si no actualiza el campo al que se refiere la clave externa, esta configuración no es necesaria

  3. No se me ocurre ningún otro uso.

  4. No puede hacerlo, ya que la restricción de clave externa fallará.

Zed
fuente
29

¡Creo que prácticamente has clavado los puntos!

Si sigue las mejores prácticas de diseño de bases de datos y su clave principal nunca es actualizable (lo cual creo que siempre debería ser el caso de todos modos), entonces realmente nunca necesita la ON UPDATE CASCADEcláusula.

Zed hizo un buen punto, que si usa una clave natural (por ejemplo, un campo regular de su tabla de base de datos) como su clave principal, entonces puede haber ciertas situaciones en las que necesite actualizar sus claves primarias. Otro ejemplo reciente sería el ISBN (International Standard Book Numbers) que cambió de 10 a 13 dígitos + caracteres no hace mucho tiempo.

Este no es el caso si elige utilizar las claves sustitutas (por ejemplo, generadas artificialmente por el sistema) como su clave principal (que sería mi opción preferida en todas las ocasiones, excepto en las más raras).

Entonces, al final: si su clave principal nunca cambia, entonces nunca necesita la ON UPDATE CASCADEcláusula.

Bagazo

marc_s
fuente
¿Qué son las claves "generadas artificialmente por el sistema"? UUID?
HPWD
1
@HPWD: solo una clave "artificial" (un valor que no se basa o no se deriva de sus datos reales) que genera el sistema; puede ser un GUID o un INT, o un BIGINT, o cualquier cosa realmente, no No importa El punto es: ese valor no está relacionado de ninguna manera con sus propios datos reales, y el sistema está generando ese valor automáticamente para usted.
marc_s
@ Marc-s gracias por tomarse el tiempo para escribir eso. Tu respuesta tiene mucho sentido.
HPWD
2
Una tabla de una sola columna con claves naturales es una alternativa buena y limpia a las enumeraciones en mi opinión (al menos en sabores de base de datos MySQL). Por ejemplo, considere una tabla colorscon filas blue, purple, yellow, y una mesa productscon una product_colorcolumna, siendo FK'ed a la colorsmesa. Eso restringe las opciones como una enumeración, pero a diferencia de un entero de incremento automático, no requiere una combinación para obtener el nombre del color. En tal caso, on update cascadees una buena idea, si decide que purpledebería llamarse en su violetlugar.
okdewit
18

Hace unos días tuve un problema con los desencadenantes, y descubrí que ON UPDATE CASCADEpuede ser útil. Eche un vistazo a este ejemplo (PostgreSQL):

CREATE TABLE club
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE band
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE concert
(
    key SERIAL PRIMARY KEY,
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE,
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE,
    concert_date DATE
);

En mi problema, tuve que definir algunas operaciones adicionales (disparador) para actualizar la mesa del concierto. Esas operaciones tuvieron que modificar club_name y band_name. No pude hacerlo, por referencia. No pude modificar el concierto y luego lidiar con las mesas de clubes y bandas. No podría hacerlo de otra manera. ON UPDATE CASCADEfue la clave para resolver el problema.

Ariel Grabijas
fuente
3
Buen comentario. Encuentro en la cascada de actualizaciones también útil, en cualquier caso, tiene que cambiar su ID. También estoy de acuerdo con otros en que este cambio no debería ser tan típico. Por ejemplo, en el caso de que cite, creo que en grandes volúmenes de datos, tal vez relacionar claves externas usando campos de texto podría no resultar en el rendimiento más rápido del motor de base de datos. Observe que si la relación extranjera en la mesa de conciertos usa club.SERIAL y la banda.SERIAL, los cambios en el nombre no afectarían la relación entre las mesas. Sin embargo, creo que ON UPDATE CASCADE es una gran herramienta para resolver emergencias. Saludos
David L
44
Sin embargo, este es un diseño cuestionable que lo convierte en un ejemplo bastante artificial. ¿Cuál es el punto de mantener dos SERIALcolumnas en cluby bandcomo claves principales si hace referencia a names en lugar de la clave principal de cada tabla?
sm
En resumen, esto es útil si está duplicando el campo de otra tabla y necesita que esté actualizado.
Kamil Tomšík
4

Mi comentario se refiere principalmente al punto n. ° 3: ¿en qué circunstancias es aplicable ON ACTUALIZAR CASCADA si suponemos que la clave principal no es actualizable? Aquí hay un caso.

Estoy lidiando con un escenario de replicación en el que varias bases de datos satelitales deben fusionarse con un maestro. Cada satélite está generando datos en las mismas tablas, por lo que la fusión de las tablas con el maestro conduce a violaciones de la restricción de unicidad. Estoy tratando de usar ON UPDATE CASCADE como parte de una solución en la que vuelvo a incrementar las claves durante cada fusión. ON UPDATE CASCADE debería simplificar este proceso al automatizar parte del proceso.

ted.strauss
fuente
3

Es una excelente pregunta, ayer tuve la misma pregunta. Pensé en este problema, BÚSQUEDA específicamente si existía algo así como "EN ACTUALIZACIÓN EN CASCADA" y afortunadamente los diseñadores de SQL también habían pensado en eso. Estoy de acuerdo con Ted.strauss, y también comenté el caso de Noran.

¿Cuándo lo usé? Como señaló Ted, cuando está tratando varias bases de datos al mismo tiempo, y la modificación en una de ellas, en una tabla, tiene algún tipo de reproducción en lo que Ted llama "base de datos satelital", no se puede guardar con el original ID, y por cualquier motivo debe crear uno nuevo, en caso de que no pueda actualizar los datos del anterior (por ejemplo, debido a permisos, o en caso de que esté buscando solidez en un caso que es tan efímero que no merece el respeto absoluto y absoluto por las reglas totales de normalización, simplemente porque será una utilidad de muy corta duración)

Entonces, estoy de acuerdo en dos puntos:

(A.) Sí, en muchas ocasiones un mejor diseño puede evitarlo; PERO

(B.) En casos de migraciones, replicar bases de datos o resolver emergencias, es una GRAN HERRAMIENTA que afortunadamente estaba allí cuando fui a buscar si existía.

David L
fuente