Не проверяется foreign key, объявленный в create table

255
26 ноября 2016, 20:08

Воспроизводимый пример:

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?

Answer 1

К сожалению, объявление внешнего ключа непосредственно при объявлении колонки - это такая проверка на внимательность чтения документации:

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;

В этом случае внешний ключ будет создан.

READ ALSO
Сборка Qt5 из исходников на Linux

Сборка Qt5 из исходников на Linux

Имеется Ubuntu 1610 x64, необходимо создать статическую сборку Qt5 с MySQL для этой ОС

346
Не удается записать данные в mysql

Не удается записать данные в mysql

Я создала простую форму регистрацииИспользую struts2 и хочу чтобы когда пользователь кликает на submit -> данные отобразились в mysql database

289
Реализация drop-down(Back-End) [требует правки]

Реализация drop-down(Back-End) [требует правки]

Зачем это нужно? Чтобы скрыть треки, которые не нравятся пользователюКак реализовать? Создать таблицу tracks_hide с полями user_id,owner_id,track_id

243
React: Unexpected token <

React: Unexpected token <

Ругается на закрывающий h1, соответственно ничего не выводитсяВ чем дело?

378