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


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

Por el bien de la discusión veamos algún 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 "ON DELETE CASCADE", si se elimina un padre con un id, se eliminará automáticamente un registro en hijo con parent_id = parent.id. Esto no debería ser un problema.

  1. Esto significa que "ON UPDATE CASCADE" hará lo mismo cuando id del padre sea actualizado?

  2. Si (1) es true, significa que no hay necesidad de usar "ON UPDATE CASCADE" si parent.id no es actualizable (o nunca se actualizará) como cuando es AUTO_INCREMENT o siempre se establece como TIMESTAMP. ¿Es eso cierto?

  3. Si (2) no es verdadero, ¿en qué otro tipo de situación deberíamos usar "ON UPDATE CASCADE"?

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

Bueno, yo saber, algunas de las preguntas anteriores se pueden probar programáticamente para entender pero también quiero saber si cualquiera de esto es dependiente del proveedor de base de datos o no.

Por favor arroje algo de luz.

Author: Gray, 2009-09-26

6 answers

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

Sin embargo, digamos 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, EN LA ACTUALIZACIÓN EN CASCADA le permitiría cambiar el valor de la clave primaria y cualquier tabla que tenga referencias de clave foránea al valor se cambiará en consecuencia.

En referencia a #4, si cambie el ID hijo a algo que no existe en la tabla padre (y tenga integridad referencial), debería obtener un error de clave foránea.

 391
Author: C-Pound Guru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-06 22:16:02
  1. Sí, significa que, por ejemplo, si lo hace UPDATE parent SET id = 20 WHERE id = 10 todos los niños parent_id de 10 también se actualizarán a 20

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

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

  4. No puede hacer eso, ya que la restricción de clave externa fallaría.

 71
Author: Zed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-06 22:15:38

¡Creo que 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 que creo que siempre debería ser el caso de todos modos), entonces realmente nunca necesita la cláusula ON UPDATE CASCADE.

Zed hizo un buen punto, que si usa una clave natural (por ejemplo, un campo regular de la tabla de su base de datos) como su clave principal, entonces puede haber ciertas situaciones en las que necesite actualizar sus claves principales. Otro reciente ejemplo 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 usar subrogadas (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).

Así que al final: si su clave primaria nunca cambia, entonces nunca necesita la cláusula ON UPDATE CASCADE.

Marc

 25
Author: marc_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-09 09:28:36

Hace unos días he tenido un problema con los disparadores, y me he dado cuenta de que ON UPDATE CASCADE puede ser útil. Echa 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 edición tuve que definir algunas operaciones adicionales (trigger) para actualizar la tabla de concert. Esas operaciones tenían que modificar club_name y band_name. No pude hacerlo, por referencia. No podía modificar el concierto y luego tratar con las mesas de club y banda. Yo tampoco podía hacerlo al revés. ON UPDATE CASCADE fue la clave para resolver el problema.

 14
Author: Ariel Grabijas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-09 15:13:17

Mi comentario se refiere principalmente al punto #3: ¿bajo qué circunstancias se aplica LA CASCADA DE ACTUALIZACIÓN si asumimos que la clave padre no se puede actualizar? Aquí hay un caso.

Estoy tratando con un escenario de replicación en el que múltiples 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 al maestro conduce a violaciones de la restricción de singularidad. Estoy tratando de utilizar EN CASCADA ACTUALIZACIÓN como parte de una solución en la que re-incremento las claves durante cada fusión. ON UPDATE CASCADE debería simplificar este proceso automatizando parte del proceso.

 4
Author: ted.strauss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-20 18:15:52

Es una pregunta excelente, tuve la misma pregunta ayer. Pensé en este problema, específicamente buscado si existía algo como "ON UPDATE CASCADE" y afortunadamente los diseñadores de SQL también habían pensado en eso. Estoy de acuerdo con Ted.strauss y yo también comentamos el caso de Noran.

¿Cuándo lo usé? Como Ted señaló, cuando estás tratando varias bases de datos a la vez, y la modificación en una de ellas, en una tabla, tiene cualquier tipo de reproducción en lo que Ted llama "base de datos satelital", no se puede mantener con el ID muy original, y por cualquier razón tienes que crear uno nuevo, en caso de que no puedas actualizar los datos del anterior (por ejemplo, debido a permisos, o en caso de que estés 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)

Por lo tanto, estoy de acuerdo en dos puntos:

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

(B.) En casos de migraciones, replicación de bases de datos, o resolución de emergencias, es una GRAN HERRAMIENTA que afortunadamente estaba ahí cuando fui a buscar si existía.

 3
Author: David L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-27 18:36:39