Столбцы с внешними ключами должны ссылаться на столбцы, содержащие крайний левый префикс первичного ключа или уникальный ключ в родительской таблице.
Другими словами, следующие примеры работают в 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
Вы получили ошибку, потому что пытаетесь сделать эквивалент (x) ссылок Foo (b).
Ваш столбец codmenuitem является вторым из трех столбцов в первичном ключе родителя.
Это сработало бы, если бы smenuitememp.codemenuitem
ссылалось на smenuitem.codmodulo
, поскольку этот столбец является крайним левым столбцом в родительской таблице.первичный ключ.
Повторяйте свой следующий вопрос:
Имейте в виду, как работают внешние ключи.Каждый раз, когда вы вставляете или обновляете строку в дочерней таблице, он должен искать строку в родительской таблице, чтобы убедиться, что значение существует в указанном столбце.Если столбец не проиндексирован, для этого поиска потребуется выполнить сканирование таблицы, и это будет очень дорого, если предположить, что ваша родительская таблица увеличивается.
Если вы попытаетесь найти строкуна основе среднего столбца многостолбцового индекса индекс вам не поможет.По аналогии это похоже на поиск в телефонной книге всех людей с определенным отчеством.
Стандартный ANSI SQL требует, чтобы указанный столбец был частью PRIMARY KEY или UNIQUE KEY, а также чтобы столбцы внешнего ключасопоставьте все столбцы первичного или уникального ограничения в родительском элементе.
Но InnoDB является более допустимым.Все еще требуется, чтобы указанный столбец в родительской таблице был проиндексирован, чтобы поиск мог быть эффективным, и , чтобы указанные столбцы были самыми левыми в индексе.Но неуникальный индекс в порядке;разрешено ссылаться на внешний ключ.
Это может привести к странным случаям, таким как дочерняя строка, которая ссылается на более чем одну строку в родительском элементе, но ожидается, что вы будете обрабатывать такие аномалии.
Я чувствую необходимостьподчеркните последний пункт.Вы получите аномальные данные, если вы определите внешние ключи для столбцов с уникальной индексацией в родительском элементе.Это, вероятно, приведет к тому, что ваши запросы будут сообщать о строках несколько раз, когда вы выполняете соединения.Вы не должны использовать это поведение InnoDB;Вы должны определять внешние ключи только для родительских столбцов, которые являются уникальными.