Воспроизводимый пример:
SET FOREIGN_KEY_CHECKS=1; -- удостоверимся, что fk должны проверяться
create table testbase (
id int auto_increment primary key
) engine=innodb;
create table testfk (
parent_id int not null references testbase(id)
) engine=innodb;
insert into testfk values(3); -- ошибки нет!
Insert явно нарушает целостность внешнего ключа, но не вызывает ошибку и сама запись создаётся тоже. Если очистить таблицу и внешний ключ создать через alter table вот так:
alter table testfk add foreign key testfk_parent_fk (parent_id)
references testbase(id);
то внешний ключ создаётся и впоследствии ограничение проверяется. Почему ограничения нет после create table?
К сожалению, объявление внешнего ключа непосредственно при объявлении колонки - это такая проверка на внимательность чтения документации:
MySQL parses but ignores “inline REFERENCES specifications” (as defined in the SQL standard) where the references are defined as part of the column specification.
Объявление references tablename(columnname) в объявление поля синтаксический парсер понимает - и просто игнорирует. Поэтому следующие два create table совершенно эквивалентны и не создают внешний ключ:
create table testfk (
parent_id int not null references testbase(id)
) engine=innodb;
create table testfk (
parent_id int not null
) engine=innodb;
Кстати, это поведение видно в результате запроса show create table testfk, объявление внешнего ключа теряется. Поэтому insert и может писать, внешнего ключа нет вообще.
Объявить внешний ключ сразу в create table возможно только отдельным блоком FOREIGN KEY:
create table testfk (
parent_id int not null,
foreign key testfk_parent_fk (parent_id) references testbase(id)
) engine=innodb;
В этом случае внешний ключ будет создан.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости