2009-09-26 19 views
311

Utilizo "ON DELETE CASCADE" con regularidad pero nunca utilizo "ON UPDATE CASCADE" ya que no estoy seguro de en qué situación será útil.Cuándo utilizar "ON UPDATE CASCADE"

En aras de la discusión, deja ver el 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 
); 

Por "ON DELETE CASCADE", si se elimina un padre con un id, un registro en el niño con parent_id = parent.id se eliminarán de forma automática. Esto no debería ser un problema.

  1. Esto significa que "ON UPDATE CASCADE" va a hacer lo mismo cuando id de la matriz se actualiza?

  2. Si (1) es verdadera, significa que no hay necesidad de usar "ON UPDATE CASCADE" si parent.id no es actualizable (o nunca serán actualizados) como cuando es AUTO_INCREMENT o siempre dispuesto a ser TIMESTAMP. ¿Está bien?

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

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

Bueno, lo sé, algunos de la pregunta anterior puede estar la prueba programmically de entender pero quiero también saber si algo de esto es proveedor de base de datos dependiente o no.

Por favor, arroja algo de luz.

+1

Ver también: http://stackoverflow.com/questions/6894162/postgresql-how-to-compact-renumber-id-for-all-tables-and-reset-sequences-to-max –

Respuesta

352

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

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

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

+4

Sólo tenía que usar 'ON UPDATE CASCADE' mismo para actualizar claves primarias en una tabla anterior que no usa una clave autoincrementada –

63
  1. Sí, esto significa que, por ejemplo, si lo hace UPDATE parent SET id = 20 WHERE id = 10 todos los niños parent_id de de 10 también serán actualizados a 20

  2. Si no actualiza el campo de la clave externa se refiere, este ajuste no es necesario

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

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

20

¡Creo que ya casi ha clavado los puntos!

Si sigue el diseño de bases de datos mejores prácticas y su clave primaria no es actualizable (que creo que siempre debe ser el caso de todos modos), entonces nunca la necesidad realmente la cláusula ON UPDATE CASCADE.

Zed hizo un buen punto, que si se utiliza una clave naturales (por ejemplo, un campo regular de su tabla de base de datos) como clave primaria, es posible que haya ciertas situaciones en las que es necesario 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 sustituto (por ejemplo, generadas artificialmente por el sistema) claves como su clave principal (que sería mi elección preferida en todas las ocasiones menos excepcionales).

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

Marc

+0

¿Qué son las claves" artificialmente generadas por el sistema "? UUIDs? – HPWD

+0

@HPWD: solo una clave "artificial" (un valor que no se basa en sus datos reales ni se deriva de ellos) que genera el sistema; * puede ser * un GUID, o un INT, o un BIGINT - o cualquier cosa realmente - no importa. El punto es que ese valor no está de ninguna manera relacionado con los datos reales, y el sistema genera ese valor automáticamente para usted. –

+0

@ marc-s gracias por tomarse el tiempo para escribir eso. Tu respuesta tiene perfecto sentido. – HPWD

4

Mi comentario es sobre todo en referencia al punto # 3: ¿en qué circunstancias es EN Actualizar en cascada aplicable si estamos asumiendo que la clave principal no es actualizable? Aquí hay un caso.

estoy tratando con un escenario de replicación en el que múltiples bases de datos del satélite necesitan ser fusionado 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 genera violaciones de la restricción de exclusividad. Intento utilizar ON UPDATE CASCADE como parte de una solución en la que vuelvo a aumentar las claves durante cada fusión. ON UPDATE CASCADE debería simplificar este proceso al automatizar parte del proceso. Hace

11

pocos días he tenido un problema con los factores desencadenantes, y he descubierto que ON UPDATE CASCADE pueden ser útiles. Echar un vistazo en 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 que tuve para definir algunas operaciones adicionales (disparador) para actualizar la tabla de 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 tablas del club y de la banda. Yo tampoco podría hacerlo a la inversa. ON UPDATE CASCADE fue la clave para resolver el problema.

+2

Buen comentario. Encuentro que en la cascada de actualización también es útil, en cualquier caso, debe 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 que cita, creo que en grandes volúmenes de datos, quizás relacionar claves externas usando campos de texto podría no dar como resultado el rendimiento más rápido del motor de base de datos. Observe, que si la relación extranjera en la mesa de conciertos utiliza club.SERIAL y la banda.SERIAL, los cambios en el nombre no afectarían la relación entre las tablas. Sin embargo, me parece que ON UPDATE CASCADE es una gran herramienta para resolver emergencias. Saludos –

+3

Este es un diseño cuestionable que hace un ejemplo bastante artificial. ¿De qué sirve mantener dos columnas 'SERIAL' en 'club' y' band' como claves principales si hace referencia a 'name's en lugar de a la clave principal de cada tabla? –

3

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

¿Cuándo lo uso? Como Ted señaló, cuando se tratan 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 la original ID, y por alguna razón debe crear una nueva, en caso de que no pueda actualizar los datos en la 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 total de las normas totales de normalización, simplemente porque habrá una vida muy corta utilidad)

por lo tanto, estoy de acuerdo en dos puntos:

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

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

Cuestiones relacionadas