Tengo dos tablas de MySQL base de datos- parent
, child
. Estoy tratando de agregar referencias de clave externa a mi tabla secundaria en función de la tabla primaria. ¿Hay alguna diferencia significativa entre ON UPDATE CASCADE
yON DELETE CASCADE
My Parent Table
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Mi pregunta es: ¿Cuál es la diferencia entre las siguientes consultas sql?
ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=INNODB;
¿Hay algún error en las consultas? ¿Qué significan estas consultas (1,2 y 3)? ¿Son iguales?
mysql
innodb
mysql-5.5
foreign-key
Lobo solitario
fuente
fuente
Respuestas:
Un muy buen hilo sobre este tema se encuentra aquí y también aquí . La guía definitiva para MySQL es, por supuesto, la documentación que se encuentra aquí .
En el estándar SQL 2003 hay 5 acciones referenciales diferentes:
Para responder la pregunta:
CASCADA
ON DELETE CASCADE
significa que si se elimina el registro principal, también se eliminan los registros secundarios. Esta no es una buena idea en mi opinión. Debe realizar un seguimiento de todos los datos que han estado en una base de datos, aunque esto se puede hacer usandoTRIGGER
s. (Sin embargo, vea la advertencia en los comentarios a continuación).ON UPDATE CASCADE
significa que si se cambia la clave primaria principal, el valor secundario también cambiará para reflejar eso. De nuevo en mi opinión, no es una gran idea. Si está cambiandoPRIMARY KEY
s con alguna regularidad (¡o incluso con alguna!), Hay algo mal con su diseño. De nuevo, vea los comentarios.ON UPDATE CASCADE ON DELETE CASCADE
significa que si ustedUPDATE
oDELETE
el padre, el cambio se aplica en cascada al hijo. Esto es el equivalenteAND
a los resultados de las dos primeras declaraciones.RESTRINGIR
RESTRICT
significa que cualquier intento de eliminar y / o actualizar el padre fallará arrojando un error. Este es el comportamiento predeterminado en el caso de que una acción referencial no se especifique explícitamente.NO ACCION
NO ACTION
: Del manual . Una palabra clave del SQL estándar. En MySQL, equivalente aRESTRICT
. El servidor MySQL rechaza la operación de eliminación o actualización para la tabla primaria si hay un valor de clave externa relacionado en la tabla referenciada. Algunos sistemas de bases de datos tienen cheques diferidos, yNO ACTION
es un cheque diferido. En MySQL, las restricciones de clave externa se verifican de inmediato, por lo queNO ACTION
es lo mismo queRESTRICT
.SET NULL
SET NULL
- De nuevo del manual. Eliminar o actualizar la fila de la tabla primaria, y establecer la columna de clave externa o columnas de la tabla secundaria aNULL
. Esta no es la mejor de las ideas en mi humilde opinión, principalmente porque no hay forma de "viajar en el tiempo", es decir, mirar hacia atrás en las tablas secundarias y asociar registros conNULL
s con el registro principal relevante,CASCADE
o usarTRIGGER
s para llenar tablas de registro para realizar un seguimiento cambios (pero, ver comentarios).ESTABLECER PREDETERMINADO
SET DEFAULT
. ¡Otra parte (potencialmente muy útil) del estándar SQL que MySQL no se ha molestado en implementar! Permite al desarrollador especificar un valor para establecer las columnas de clave externa en una ACTUALIZACIÓN o SUPRIMIR. InnoDB y NDB rechazarán las definiciones de tabla con unaSET DEFAULT
cláusula.Como se mencionó anteriormente, debe pasar algún tiempo mirando la documentación, aquí .
fuente
Estas dos son acciones a realizar, respectivamente, cuando el registro referenciado en la tabla primaria cambia su identificación y cuando se elimina.
Si ejecuta:
Y hay al menos un registro
child
conparent_id = 1
, 1) fallará; en los casos 2) y 3), todos los registros con parent_id = 1 se actualizan a parent_id = -1.Si ejecuta:
Y hay al menos un registro
child
conparent_id = 1
, 2) fallará; en los casos 1) y 3), todos los registros conparent_id = 1
se eliminan.3) es sintácticamente correcto.
La documentación completa se puede encontrar en el manual .
fuente
No tengo suficiente reputación para comentar las respuestas anteriores. Así que pensé en elaborar un poco.
1) EN ELIMINAR CASCADA significa que si se elimina el registro primario, también se eliminan los registros secundarios que hacen referencia. ON UPDATE tiene como valor predeterminado RESTRICT, lo que significa que la ACTUALIZACIÓN en el registro primario fallará.
2) La acción ON DELETE por defecto es RESTRICT, lo que significa que el DELETE en el registro padre fallará. ON UPDATE CASCADE actualizará todos los registros secundarios de referencia cuando se actualice el registro primario.
3) Ver las acciones en CASCADA en 1) y 2) arriba.
Sobre el uso de ID de registros primarios como claves foráneas (en tablas secundarias): la experiencia dice a) si las ID son números de secuencia generados automáticamente, NO los use como claves foráneas. Use alguna otra clave principal única en su lugar. b) si los ID son GUID, entonces está bien usarlos como claves foráneas. Verá la sabiduría en esta sugerencia cuando exporte e importe los registros o copie registros a otra base de datos. Es demasiado engorroso lidiar con los números de secuencia generados automáticamente durante la migración de datos cuando se hace referencia a ellos como claves foráneas.
fuente