MySQL: Broken внешнего ключа implementaion?

голоса
4

Встроенный синтаксис для определения внешних ключей в MySQL, кажется, не делать ничего, в то время как больше синтаксис CONSTRAINT, кажется, работает, как ожидалось. Мне очень интересно, почему это происходит.

Недавно я обнаружил , что встроенный синтаксис для определения внешних ключей, которые я думал , что будет нормально работать, не делает каких - либо фактических проверки ссылочной целостности. Это не имеет значения , что определяется в ON DELETE / UPDATE положения.
Я, конечно , пытался это с InnoDB , так как я знаю , что MyISAM не поддерживает внешние ключи проверки.

Пожалуйста, посмотрите на примеры / скрипками, и вы увидите, что я имею в виду.

Инлайн Синтаксис

Это правильный способ определения внешних ключей в соответствии с документацией, которую я использовал в течение многих лет.

-- Create a basic foreign key relationship.
CREATE TABLE `parent` (
  `id` INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  `a` VARCHAR(255) NOT NULL
)ENGINE=InnoDB; -- Just to be sure.

CREATE TABLE `child` (
  `id` INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  -- Short legitimate syntax, frequently used.
  `parent_id` INTEGER UNSIGNED NOT NULL REFERENCES `parent` (`id`)
    ON DELETE RESTRICT
)ENGINE=InnoDB; -- Just to be sure.

Теперь , если удалить строку из родительской таблицы, которая ссылается на ребенок таблице, он удаляется так же , как я никогда не определен внешний ключ. Попробуйте сами: скрипку

CONSTRAINT синтаксис

Чем дольше синтаксис, используя ключевое слово CONSTRAINT более громоздким писать, но, кажется, работает, как ожидается, в отличие от определения инлайн.

-- `parent` table has been omitted, since it is the same as above.
CREATE TABLE `child` (
  `id` INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  `parent_id` INTEGER UNSIGNED NOT NULL,
  -- Longer, more cumbersome syntax.
  CONSTRAINT `fk_child_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
    ON DELETE RESTRICT
)ENGINE=InnoDB; -- Just to be sure.

Если я пытаюсь удалить строки в ссылке из родителей он не как ожидалось. Попробуйте сами: скрипку (Вы должны раскомментировать последнее утверждение на левой стороне , чтобы она не в состоянии )

Заключение / Актуальна

Как вы уже видели для себя в скрипках, рядный синтаксис для создания внешних ключей, кажется, не делать ничего, в то время как более синтаксис CONSTRAINT работает отлично.

Кто - нибудь знает , почему это так? Есть ли какая - либо причина , или это просто еще одна причуды MySQL мы должны работать вокруг?
Пожалуйста , поделитесь своими знаниями, я очень любопытный.

Обновление / SHOW CREATE TABLE Проверка

Вот выход SHOW CREATE TABLEкак отметил @MikePurcell.

«Короткий» Синтаксис

CREATE TABLE `child`(
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

CONSTRAINT Синтаксис

CREATE TABLE `child` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_child_parent` (`parent_id`),
  CONSTRAINT `fk_child_parent` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

Теперь ясно , что анализатор просто игнорирует REFERENCESположение в определении таблицы , используя «короткий» синтаксис. По крайней мере , обновление документации , было бы полезно. Спасибо за помощь, ребята!

FYI: Это уже было подано , как ошибка еще в 2004 году ( Bug # 4919 ) и , кажется, известно еще некоторое время. Я действительно надеюсь , что они будут по крайней мере обновить документацию , касающуюся этого, потому что я не думаю , что это будет исправлено в ближайшее время.

Задан 26/03/2015 в 15:01
пользователем
На других языках...                            


1 ответов

голоса
2

Только «короткий синтаксис» Раньше я не знаю был:

create_definition: 
    col_name  column_definition
...
    | [CONSTRAINT [ символ ]] FOREIGN KEY 
      [ index_name ] ( index_col_name , ...) reference_definition

reference_definition: 
    ЛИТЕРАТУРЫ tbl_name ( index_col_name , ...)
      [МАТЧ ПОЛНЫЙ | MATCH PARTIAL | MATCH SIMPLE]
      [ON DELETE reference_option ]
      [ON UPDATE reference_option ]

Обратите внимание на обязательное FOREIGN KEYусловие.

Однако, анализатор делает принимает « короткий синтаксис» вы использовали, в соответствии с инструкцией :

column_definition: 
    тип_данный [NOT NULL | NULL] [ИСХОДНЫЕ значение_по_умолчанию ]
...
      [ Reference_definition ]

Обратите внимание на отсутствие FOREIGN KEYпункта.

По сути, это странное поведение документировано на той же странице:

MySQL разбирает , но игнорирует «встроенные REFERENCESхарактеристики» (как определено в стандарте SQL) , где ссылки определены как часть спецификации столбца. MySQL принимает REFERENCESтолько пункты , если это указано в рамках отдельной FOREIGN KEYспецификации.

Ограничение также обсуждается более подробно в учебнике .

Является ли это ошибка или отсутствует функция уже давно обсуждается , так что кажется.

Ответил 26/03/2015 в 15:35
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more