sql >> Base de Datos >  >> RDS >> Mysql

Problema de Mysql y FK

La(s) columna(s) de la clave externa deben hacer referencia a la(s) columna(s) que comprenden un prefijo más a la izquierda de la clave principal o una clave única en la tabla principal.

En otras palabras, los siguientes ejemplos funcionan en InnoDB:

CREATE TABLE Foo ( a INT, b INT, c INT, PRIMARY KEY (a,b,c) );
CREATE TABLE Bar ( x INT, y INT );

ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(b,c); -- WRONG

ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,c); -- WRONG

ALTER TABLE Bar ADD FOREIGN KEY (x,y) REFERENCES Foo(a,b); -- RIGHT

ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(b); -- WRONG

ALTER TABLE Bar ADD FOREIGN KEY (x) REFERENCES Foo(a); -- RIGHT

Obtuvo un error porque está tratando de hacer el equivalente de (x) referencias Foo (b).
Su columna codmenuitem es la segunda de tres columnas en la clave principal del padre.

Funcionaría si smenuitememp.codemenuitem debían hacer referencia a smenuitem.codmodulo , porque esa columna es la columna más a la izquierda en la clave principal de la tabla principal.

Re su pregunta de seguimiento:

Tenga en cuenta la forma en que funcionan las claves externas. Cada vez que inserta o actualiza una fila en la tabla secundaria, debe buscar una fila en la tabla principal para verificar que el valor existe en la columna a la que se hace referencia. Si la columna no está indexada, tendrá que hacer un escaneo de tabla para lograr esta búsqueda, y eso sería muy costoso, suponiendo que su tabla principal crezca.

Si intenta buscar una fila basada en la columna del medio de un índice de varias columnas, el índice no le ayudará. Por analogía, es como buscar en una guía telefónica todas las personas con un segundo nombre determinado.

ANSI SQL estándar requiere que la columna a la que se hace referencia sea parte de una CLAVE PRINCIPAL o CLAVE ÚNICA, y requiere que las columnas de clave externa coincidan con todas las columnas de una restricción primaria o única en el padre.

Pero InnoDB es más permisivo. Todavía requiere que la columna a la que se hace referencia en la tabla principal esté indexada para que la búsqueda pueda ser eficiente, y que las columnas a las que se hace referencia sean las más a la izquierda en el índice. Pero un índice no único está bien; está permitido que una clave externa lo haga referencia.

Esto puede dar lugar a casos extraños, como una fila secundaria que hace referencia a más de una fila en la principal, pero se espera que maneje tales anomalías.

Siento la necesidad de enfatizar el último punto. Usted lo hará obtenga datos anómalos si define claves foráneas para columnas indexadas no únicas en el padre. Esto probablemente hará que sus consultas informen filas varias veces cuando se une. No debe usar este comportamiento de InnoDB; debe definir claves foráneas solo para las columnas principales que son únicas.