Вопрос

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

Камнем преткновения, с которым я столкнулся при этом, являются внешние ключи в MySQL.Кажется, я не могу найти ничего о другом, кроме того, что они существуют в ИнноДБ схема хранения, которую имеет MySQL.

Каков простой пример внешних ключей, реализованных в MySQL?

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

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
Это было полезно?

Решение

Предполагая, что ваши категории и таблица пользователей уже существуют и содержат cID и uID соответственно в качестве первичных ключей, это должно работать:

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;

Имя столбца требуется в предложении reference .

Другие советы

Отредактировано: Роберт и Винко заявляют, что вам необходимо объявить имя столбца, на который ссылаются, в ограничении внешнего ключа.Это необходимо в InnoDB, хотя в стандартном SQL разрешено опускать имя столбца, на который ссылаются, если оно имеет то же имя в родительской таблице.

Одна особенность, с которой я столкнулся в MySQL, заключается в том, что объявление внешнего ключа не работает автоматически в нескольких случаях:

  • Ваша установка MySQL не включает движок innodb.
  • Ваш файл конфигурации MySQL не включает движок innodb.
  • Вы не объявляете свою таблицу с модификатором таблицы ENGINE=InnoDB.
  • Столбец внешнего ключа не имеет точно такого же типа данных, как столбец первичного ключа в указанной таблице.

К сожалению, MySQL не выдает сообщения о том, что ему не удалось создать ограничение внешнего ключа.Он просто игнорирует запрос и создает таблицу без внешнего ключа (если вы ПОКАЗЫВАЕТЕ сообщения CREATE TABLE, вы можете не увидеть объявления внешнего ключа).Я всегда считал, что это плохая особенность MySQL!

Кончик: целочисленный аргумент для целочисленных типов данных (например,BIGINT(20)) не требуется.Это не имеет никакого отношения к размеру хранилища или диапазону столбца.BIGINT всегда имеет один и тот же размер независимо от аргумента, который вы ему передаете.Число означает, сколько цифр MySQL дополнит столбец, если вы используете модификатор столбца ZEROFILL.

Это имеет некоторые код, показывающий, как создавать внешние ключи самостоятельно и в CREATE TABLE.

Вот один из простых примеров из этого:

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child (
    id INT, 
    parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id) REFERENCES parent(id)
    ON DELETE CASCADE
) ENGINE=INNODB;

Я согласен с Робертом. Вам не хватает названия столбца в разделе ссылок (и вы должны получить ошибку 150). Я добавлю, что вы можете проверить, как таблицы создавались в реальности с помощью:

SHOW CREATE TABLE posts;

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

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

select *
from 
   Students
inner join
   StudentCourses
on Students.StudentId = StudentCourses.StudentId

StudentCourses.StudentId - это внешний ключ, ссылающийся на Students.StudentId.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top