2012-08-29 16 views
24

Me pregunto acerca de esta pregunta de prueba. Preparé el ejemplo y lo probé, pero todavía no estoy seguro de la respuesta.MySQL en eliminar cascada. Ejemplo de prueba

Con el siguiente:

CREATE TABLE foo (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    name INT 
) 

CREATE TABLE foo2 (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    foo_id INT REFERENCES foo(id) ON DELETE CASCADE 
) 

Por lo que yo puedo ver la respuesta es:

a. Dos tablas se crean

Aunque también hay:

b. Si se elimina una fila en foo2 mesa, con un foo_id de 2, entonces la fila con id = 2 en el foo tabla se elimina automáticamente

D. Si una fila con id = 2 en la tabla se elimina foo, todas las filas con foo_id = 2 en foo2 tabla se eliminan

en mi ejemplo, yo habría usado la sintaxis de borrado:

DELETE FROM foo WHERE id = 2; 
DELETE FROM foo2 WHERE foo_id = 2; 

Por alguna razón he podido encontrar ninguna relación entre las tablas aunque parece como debería haber uno. Tal vez hay alguna configuración de MySQL o tal vez ON DELETE CASCADE no se utiliza correctamente en las consultas de creación de la tabla? Me pregunto ...

Respuesta

37

Respuesta d. es correcto, si y solo si el motor de almacenamiento en realidad admite y aplica restricciones de clave externa.

Si las tablas se crean con Engine=MyISAM, entonces ninguna b. o d. es correcto.

Si las tablas se crean con Engine=InnoDB, entonces d. es correcto.

NOTA:

Esto es cierto para InnoDB si y sólo si FOREIGN_KEY_CHECKS = 1; si FOREIGN_KEY_CHECKS = 0, un DELETE de la tabla padre (foo) no eliminará las filas de la tabla secundaria (foo2) que hacen referencia a una fila eliminada de la tabla padre.

verificar esto con la salida de SHOW VARIABLES LIKE 'foreign_key_checks' (1 = ON, 0 = OFF) (El valor predeterminado normal es para que esto sea ON.)

La salida de SHOW CREATE TABLE foo mostrará qué motor se utiliza la tabla.

La salida de SHOW VARIABLES LIKE 'storage_engine' mostrará el motor predeterminado utilizado cuando se crea una tabla y el motor no está especificado.

+0

notable diferencia entre 'MyISAM' y' InnoDB' para la corrección de ** b ** – JalalJaberi

+0

Tienes razón. Fue ** d **. lo siento por eso. – JalalJaberi

14

Tienes una relación entre dos tablas, está en el comando de creación foo2: ... foo_id int references foo(id) on delete cascade.

De acuerdo con la MySQL Foreign Key Constraints reference:

CASCADE: Eliminar o actualizar la fila de la tabla primaria, y automáticamente eliminar o actualizar las filas coincidentes en la tabla secundaria. Tanto ON DELETE CASCADE como ON UPDATE CASCADE son compatibles.

También, de acuerdo a la MySQL Foreign Keys reference:

Para motores de almacenamiento que no sean InnoDB, es posible la hora de definir una columna de usar un tbl_name la cláusula (col_name), que no tiene ningún efecto real, Referencias y sirve solo como una nota o comentario que la columna que está definiendo actualmente está destinada a referirse a una columna en otra tabla.

Así que ya que la clave externa es de la tabla secundaria a la tabla primaria, se hace foo una tabla padre y foo2 una tabla secundaria, por lo que suprimir una fila de foo caerá en cascada eliminaciones a foo2, siempre que utilice InnoDB o algún otro motor de almacenamiento que lo soporte.

+1

Sería d. (no b.) eso sería correcto. La clave externa es de la tabla secundaria a la tabla principal. Eliminar una fila de la tabla secundaria no tendrá efecto (a través de la clave externa) en la tabla primaria. Es cuando se borra una fila de la tabla principal que la clave externa entra en juego. – spencer7593

+1

@ spencer7593 - Tienes razón, lo editaré, gracias – Vic

Cuestiones relacionadas