2012-06-24 9 views
5

¿Cuál es la diferencia en las siguientes dos declaraciones CREATE TABLE? (El primero utiliza KEY y el segundo no lo hace.)Diferencia en la creación de FOREIGN KEY

CREATE TABLE `title` (
    `title` VARCHAR(255) NOT NULL, 
    `order_number` VARCHAR(35) NOT NULL, 
    KEY `order_number` (`order_number`), 
    CONSTRAINT `order_number_fk` FOREIGN KEY (`order_number`) 
     REFERENCES `order` (`order_number`) ON DELETE CASCADE 
) 

CREATE TABLE `title` (
    `title` VARCHAR(255) NOT NULL, 
    `order_number` VARCHAR(35) NOT NULL, 
    CONSTRAINT `order_number_fk` FOREIGN KEY (`order_number`) 
     REFERENCES `order` (`order_number`) ON DELETE CASCADE 
) 

Ambos crear tablas válidos. ¿En qué se diferencian y cuál sería el que quiero usar?

Respuesta

7

Son (casi *) lo mismo.

Cuando crea una restricción de clave externa, se crea un índice en la (s) columna (s) relevante (s) de la tabla de referencia automáticamente si ya no existe un índice adecuado.

Desde la página del manual sobre FOREIGN KEY Constraints:

InnoDB requiere índices de claves ajenas y claves referenciadas, así las claves foráneas pueden ser rápido y no requiere un recorrido de tabla. En la tabla de referencia, debe haber un índice donde las columnas de clave externa se enumeran como las primeras columnas en el mismo orden. Dicho índice se crea automáticamente en la tabla de referencia si no existe. Este índice se puede eliminar silenciosamente más adelante, si crea otro índice que se pueda usar para aplicar la restricción de clave externa. index_name, si se proporciona, se usa como se describió anteriormente.

Énfasis mío.


(*) Digo casi el mismo porque hay algunas diferencias sutiles.

El nombre del índice

En la primera versión que ha dado el índice de un nombre explícito, pero en la segunda versión del nombre del índice es el mismo que el nombre de la restricción (si está especificado).

comparar la salida de SHOW INDEX en ambos casos:

Versión 1:

 
Table Non_unique Key_name   Seq_in_index Column_name ... 
title 1   order_number  1    order_number ... 

Versión 2:

 
Table Non_unique Key_name   Seq_in_index Column_name ... 
title 1   order_number_fk 1    order_number ... 

Como se puede ver, la única diferencia aquí es el nombre de El índice.

silencioso caer

Otra sutil diferencia es que en el segundo caso, ya que la documentación menciona, el índice creado de forma automática podría ser en silencio caído cuando se añaden nuevos índices:

Este índice podría se descartará más tarde, si crea otro índice que pueda usarse para aplicar la restricción de clave externa.

esto significa es que si más adelante crear un índice de varias columnas, por ejemplo, (order_number, title):

CREATE INDEX ix_order_number_title ON title (order_number, title); 

A continuación, ejecute SHOW INDEX nuevo:

Versión 1:

 
Table Non_unique Key_name    Seq_in_index Column_name ... 
title 1   order_number   1    order_number ... 
title 1   ix_order_number_title 1    order_number ... 
title 1   ix_order_number_title 2    title   ... 

Versión 2:

 
Table Non_unique Key_name    Seq_in_index Column_name ... 
title 1   ix_order_number_title 1    order_number ... 
title 1   ix_order_number_title 2    title   ... 

Ahora puede ver que la primera versión tiene dos índices, pero la segunda versión tiene solo uno. Con la segunda versión, el índice que se creó automáticamente por la restricción de clave externa se retiró automáticamente cuando se agregó el índice de varias columnas. Normalmente, este no es un problema grave porque el nuevo índice hace que el índice original sea en gran parte redundante.

¿Qué desea usar?

Normalmente no necesita preocuparse de crear explícitamente el índice en la tabla de referencia de una restricción de clave externa.

Pero es posible que desee crear un índice de forma explícita si:

  • prefiere darle un nombre que es diferente del nombre de la restricción, o
  • no desea que el índice desaparecen silenciosamente cuando se agregan otros índices.
+0

¿Es esto cierto para MyISAM también? – lee

+1

@lee MyISAM no admite restricciones de clave externa. – David542

+0

¡Gran respuesta, gracias! – David542

Cuestiones relacionadas