Внешние ключи в MySQL?

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

Камнем преткновения, с которым я столкнулся, являются внешние ключи в MySQL. Кажется, я не могу найти ничего другого, кроме того, что они существуют в схеме хранилища InnoDB, которая есть в 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;
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
26
0
20 648
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Этот имеет некоторый код, показывающий, как создавать внешние ключи сами по себе и в 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;
Ответ принят как подходящий

Предполагая, что ваши категории и таблица пользователей уже существуют и содержат 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;

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

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

SHOW CREATE TABLE posts;

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

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

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

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

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

Можете ли вы предоставить ссылку на свое утверждение относительно имен столбцов во внешнем ключе? Согласно синтаксису в (dev.mysql.com/doc/refman/5.0/en/…) это не необязательный параметр, и он не работает для меня, пока я не укажу его.

Robert Gamble 25.10.2008 22:29

Да, вы правы, теперь, когда я проверяю это более внимательно, я наблюдаю то же самое. Стандартный SQL должен разрешать неявное имя столбца, на которое указывает ссылка, если оно совпадает с основной таблицей, но InnoDB, к сожалению, не поддерживает это. Моя вина!

Bill Karwin 25.10.2008 22:52

Это зависит от вашей версии MySQL. В 5 не удается создать таблицу с полезным сообщением «Ошибка 150», что означает «не удалось создать таблицу» или какой-либо другой невероятно полезной вещью.

MBCook 25.10.2008 23:03

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

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

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

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

как вы думаете, вы могли бы еще немного объяснить, что это делает? Это просто соединение?

icco 26.10.2008 03:03

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