Связи между таблицами базы данных
Связи — это довольна важная тема, которую следует понимать при проектировании баз данных. По своему личному опыту скажу, что осознав связи, мне намного легче далось понимание нормализации базы данных.
1.1. Для кого эта статья?
Эта статья будет полезна тем, кто хочет разобраться со связями между таблицами базы данных. В ней я постарался рассказать на понятном языке, что это такое. Для лучшего понимания темы, я чередую теоретический материал с практическими примерами, представленными в виде диаграммы и запроса, создающего нужные нам таблицы. Я использую СУБД Microsoft SQL Server и запросы пишу на T-SQL. Написанный мною код должен работать и на других СУБД, поскольку запросы являются универсальными и не используют специфических конструкций языка T-SQL.
1.2. Как вы можете применить эти знания?
- Процесс создания баз данных станет для вас легче и понятнее.
- Понимание связей между таблицами поможет вам легче освоить нормализацию, что является очень важным при проектировании базы данных.
- Разобраться с чужой базой данных будет значительно проще.
- На собеседовании это будет очень хорошим плюсом.
2. Благодарности
Учтены были советы и критика авторов jobgemws, unfilled, firnind, Hamaruba.
Спасибо!
3.1. Как организовываются связи?
Связи создаются с помощью внешних ключей (foreign key).
Внешний ключ — это атрибут или набор атрибутов, которые ссылаются на primary key или unique другой таблицы. Другими словами, это что-то вроде указателя на строку другой таблицы.
3.2. Виды связей
Связи делятся на:
- Многие ко многим.
- Один ко многим.
- с обязательной связью;
- с необязательной связью;
- Один к одному.
- с обязательной связью;
- с необязательной связью;
4. Многие ко многим
Представим, что нам нужно написать БД, которая будет хранить работником IT-компании. При этом существует некий стандартный набор должностей. При этом:
- Работник может иметь одну и более должностей. Например, некий работник может быть и админом, и программистом.
- Должность может «владеть» одним и более работников. Например, админами является определенный набор работников. Другими словами, к админам относятся некие работники.
4.1. Как построить такие таблицы?
Мы уже имеем две таблицы, описывающие работника и профессию. Теперь нам нужно установить между ними связь многие ко многим. Для реализации такой связи нам нужен некий посредник между таблицами «Employee» и «Position». В нашем случае это будет некая таблица «EmployeesPositions» (работники и должности). Эта таблица-посредник связывает между собой работника и должность следующим образом:
| EmployeeId | PositionId |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 3 | 3 |
Слева указаны работники (их id), справа — должности (их id). Работники и должности на этой таблице указываются с помощью id’шников.
На эту таблицу можно посмотреть с двух сторон:
- Таким образом, мы говорим, что работник с id 1 находится на должность с id 1. При этом обратите внимание на то, что в этой таблице работник с id 1 имеет две должности: 1 и 2. Т.е., каждому работнику слева соответствует некая должность справа.
- Мы также можем сказать, что должности с id 3 принадлежат пользователи с id 2 и 3. Т.е., каждой роли справа принадлежит некий работник слева.
4.2. Реализация
Диаграмма
Код на T-SQL
create table dbo.Employee ( EmployeeId int primary key, EmployeeName nvarchar(128) not null, EmployeeAge int not null ) -- Заполним таблицу Employee данными. insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (1, N'John Smith', 22) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (2, N'Hilary White', 22) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (3, N'Emily Brown', 22) create table dbo.Position ( PositionId int primary key, PositionName nvarchar(64) not null ) -- Заполним таблицу Position данными. insert into dbo.Position(PositionId, PositionName) values(1, N'IT-director') insert into dbo.Position(PositionId, PositionName) values(2, N'Programmer') insert into dbo.Position(PositionId, PositionName) values(3, N'Engineer') -- Заполним таблицу EmployeesPositions данными. create table dbo.EmployeesPositions ( PositionId int foreign key references dbo.Position(PositionId), EmployeeId int foreign key references dbo.Employee(EmployeeId), primary key(PositionId, EmployeeId) ) insert into dbo.EmployeesPositions(EmployeeId, PositionId) values (1, 1) insert into dbo.EmployeesPositions(EmployeeId, PositionId) values (1, 2) insert into dbo.EmployeesPositions(EmployeeId, PositionId) values (2, 3) insert into dbo.EmployeesPositions(EmployeeId, PositionId) values (3, 3)
Объяснения
С помощью ограничения foreign key мы можем ссылаться на primary key или unique другой таблицы. В этом примере мы
- ссылаемся атрибутом PositionId таблицы EmployeesPositions на атрибут PositionId таблицы Position;
- атрибутом EmployeeId таблицы EmployeesPositions — на атрибут EmployeeId таблицы Employee;
4.3. Вывод
Для реализации связи многие ко многим нам нужен некий посредник между двумя рассматриваемыми таблицами. Он должен хранить два внешних ключа, первый из которых ссылается на первую таблицу, а второй — на вторую.
5. Один ко многим
Эта самая распространенная связь между базами данных. Мы рассматриваем ее после связи многие ко многим для сравнения.
Предположим, нам нужно реализовать некую БД, которая ведет учет данных о пользователях. У пользователя есть: имя, фамилия, возраст, номера телефонов. При этом у каждого пользователя может быть от одного и больше номеров телефонов (многие номера телефонов).
В этом случае мы наблюдаем следующее: пользователь может иметь многие номера телефонов, но нельзя сказать, что номеру телефона принадлежит определенный пользователь.
Другими словами, телефон принадлежит только одному пользователю. А пользователю могут принадлежать 1 и более телефонов (многие).
Как мы видим, это отношение один ко многим.
5.1. Как построить такие таблицы?
Пользователей будет представлять некая таблица «Person» (id, имя, фамилия, возраст), номера телефонов будет представлять таблица «Phone». Она будет выглядеть так:
| PhoneId | PersonId | PhoneNumber |
|---|---|---|
| 1 | 5 | 11 091-10 |
| 2 | 5 | 19 124-66 |
| 3 | 17 | 21 972-02 |
Данная таблица представляет три номера телефона. При этом номера телефона с id 1 и 2 принадлежат пользователю с id 5. А вот номер с id 3 принадлежит пользователю с id 17.
Заметка. Если бы у таблицы «Phones» было бы больше атрибутов, то мы смело бы их добавляли в эту таблицу.
5.2. Почему мы не делаем тут таблицу-посредника?
Таблица-посредник нужна только в том случае, если мы имеем связь многие-ко-многим. По той простой причине, что мы можем рассматривать ее с двух сторон. Как, например, таблицу EmployeesPositions ранее:
- Каждому работнику принадлежат несколько должностей (многие).
- Каждой должности принадлежит несколько работников (многие).
5.3. Реализация
Диаграмма
Код на T-SQL
create table dbo.Person ( PersonId int primary key, FirstName nvarchar(64) not null, LastName nvarchar(64) not null, PersonAge int not null ) insert into dbo.Person(PersonId, FirstName, LastName, PersonAge) values (5, N'John', N'Doe', 25) insert into dbo.Person(PersonId, FirstName, LastName, PersonAge) values (17, N'Izabella', N'MacMillan', 19) create table dbo.Phone ( PhoneId int primary key, PersonId int foreign key references dbo.Person(PersonId), PhoneNumber varchar(64) not null ) insert into dbo.Phone(PhoneId, PersonId, PhoneNumber) values (1, 5, '11 091-10') insert into dbo.Phone(PhoneId, PersonId, PhoneNumber) values (2, 5, '19 124-66') insert into dbo.Phone(PhoneId, PersonId, PhoneNumber) values (3, 17, '21 972-02')
Объяснения
Наша таблица Phone хранит всего один внешний ключ. Он ссылается на некого пользователя (на строку из таблицы Person). Таким образом, мы как бы говорим: «этот пользователь является владельцем данного телефона». Другими словами, телефон знает id своего владельца.
6. Один к одному
Представим, что на работе вам дали задание написать БД для учета всех работников для HR. Начальник уверял, что компании нужно знать только об имени, возрасте и телефоне работника. Вы разработали такую БД и поместили в нее всю 1000 работников компании. И тут начальник говорит, что им зачем-то нужно знать о том, является ли работник инвалидом или нет. Наиболее простое, что приходит в голову — это добавить новый столбец типа bool в вашу таблицу. Но это слишком долго вписывать 1000 значений и ведь true вы будете вписывать намного реже, чем false (2% будут true, например).
Более простым решением будет создать новую таблицу, назовем ее «DisabledEmployee». Она будет выглядеть так:
| DisabledPersonId | EmployeeId |
|---|---|
| 1 | 159 |
| 2 | 722 |
| 3 | 937 |
Но это еще не связь один к одному. Дело в том, что в такую таблицу работник может быть вписан более одного раза, соответственно, мы получили отношение один ко многим: работник может быть несколько раз инвалидом. Нужно сделать так, чтобы работник мог быть вписан в таблицу только один раз, соответственно, мог быть инвалидом только один раз. Для этого нам нужно указать, что столбец EmployeeId может хранить только уникальные значения. Нам нужно просто наложить на столбец EmloyeeId ограничение unique. Это ограничение сообщает, что атрибут может принимать только уникальные значения.
Выполнив это мы получили связь один к одному.
Заметка. Обратите внимание на то, что мы могли также наложить на атрибут EmloyeeId ограничение primary key. Оно отличается от ограничения unique лишь тем, что не может принимать значения null.
6.1. Вывод
Можно сказать, что отношение один к одному — это разделение одной и той же таблицы на две.
6.2. Реализация
Диаграмма
Код на T-SQL
create table dbo.Employee ( EmployeeId int primary key, EmployeeName nvarchar(128) not null, EmployeeAge int not null ) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (159, N'John Smith', 22) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (722, N'Hilary White', 29) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (937, N'Emily Brown', 19) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (100, N'Frederic Miller', 16) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (99, N'Henry Lorens', 20) insert into dbo.Employee(EmployeeId, EmployeeName, EmployeeAge) values (189, N'Bob Red', 25) create table dbo.DisabledEmployee ( DisabledPersonId int primary key, EmployeeId int unique foreign key references dbo.Employee(EmployeeId) ) insert into dbo.DisabledEmployee(DisabledPersonId, EmployeeId) values (1, 159) insert into dbo.DisabledEmployee(DisabledPersonId, EmployeeId) values (2, 722) insert into dbo.DisabledEmployee(DisabledPersonId, EmployeeId) values (3, 937)
Объяснения
Таблица DisabledEmployee имеет атрибут EmployeeId, что является внешним ключом. Он ссылается на атрибут EmployeeId таблицы Employee. Кроме того, этот атрибут имеет ограничение unique, что говорит о том, что в него могут быть записаны только уникальные значения. Соответственно, работник может быть записан в эту таблицу не более одного раза.
7. Обязательные и необязательные связи
Связи можно поделить на обязательные и необязательные.
7.1. Один ко многим
- Один ко многим с обязательной связью:
К одному полку относятся многие бойцы. Один боец относится только к одному полку. Обратите внимание, что любой солдат обязательно принадлежит к одному полку, а полк не может существовать без солдат. - Один ко многим с необязательной связью:
На планете Земля живут все люди. Каждый человек живет только на Земле. При этом планета может существовать и без человечества. Соответственно, нахождение нас на Земле не является обязательным
У одной биологической матери может быть много детей. У ребенка есть только одна биологическая мать.
А) У женщины необязательно есть свои дети. Соответственно, связь необязательна.
Б) У ребенка обязательно есть только одна биологическая мать – в таком случае, связь обязательна.
7.2. Один к одному
- Один к одному с обязательной связью:
У одного гражданина определенной страны обязательно есть только один паспорт этой страны. У одного паспорта есть только один владелец. - Один к одному с необязательной связью:
У одной страны может быть только одна конституция. Одна конституция принадлежит только одной стране. Но конституция не является обязательной. У страны она может быть, а может и не быть, как, например, у Израиля и Великобритании.
У одного человека может быть только один загранпаспорт. У одного загранпаспорта есть только один владелец.
А) Наличие загранпаспорта необязательно – его может и не быть у гражданина. Это необязательная связь.
Б) У загранпаспорта обязательно есть только один владелец. В этом случае, это уже обязательная связь.
7.3. Многие ко многим
Любая связь многие ко многим является необязательной. Например:
Человек может инвестировать в акции разных компаний (многих). Инвесторами какой-то компании являются определенные люди (многие).
А) Человек может вообще не инвестировать свои деньги в акции.
Б) Акции компании мог никто не купить.
8. Как читать диаграммы?
Выше я приводил диаграммы созданных нами таблиц. Но для того, чтобы их понимать, нужно знать, как их «читать». Разберемся в этом на примере диаграммы из пункта 5.3.

Мы видим отношение один ко многим. Одной персоне принадлежит много телефонов.
- Возле таблицы Person находится золотой ключик. Он обозначает слово «один».
- Возле таблицы Phone находится знак бесконечности. Он обозначает слово «многие».
9. Итоги
- Связи бывают:
- Многие ко многим.
- Один ко многим.
1) с обязательной связью;
2) с необязательной связью. - Один к одному.
1) с обязательной связью;
2) с необязательной связью.
- Связи организовываются с помощью внешних ключей.
- Foreign key (внешний ключ) — это атрибут или набор атрибутов, которые ссылаются на primary key или unique другой таблицы. Другими словами, это что-то вроде указателя на строку другой таблицы.
10. Задачи
Для лучшего усвоения материала предлагаю вам решить следующие задачи:
- Описать таблицу фильм: id, название, длительность, режиссер, жанр фильма. Обратите внимание на то, что у фильма может быть более одного жанра, а к одному жанру может относится более, чем один фильм.
- Описать таблицу песня: id, название, длительность, певец. При этом у песни может быть более одного певца, а певец мог записать более одной песни.
- Реализовать таблицу машина: модель, производитель, цвет, цена
- Описать отдельную таблицу производитель: id, название, рейтинг.
- Описать отдельную таблицу цвета: id, название.
У одной машины может быть только один производитель, а у производителя — много машин. У одной машины может быть много цветов, а у одного цвета может быть много машин.
- Добавить в БД из пункта 6.2. таблицу военно-обязанных по типу того, как мы описали отдельную таблицу DisabledEmployee.
- SQL
- Microsoft SQL Server
Виды связей в базах данных
MySQL — это реляционная база данных. Это означает, что данные в базе могут быть распределены в нескольких таблицах, и связаны друг с другом с помощью отношений (relation). Отсюда и название — реляционные.
Связи между таблицами происходят с помощью ключей. К примеру, в созданной нами ранее таблице пользователей есть первичный ключ — поле id. Если мы захотим сделать таблицу со статьями и хранить в ней авторов этих статей, то мы можем добавить новый столбец author_id и хранить в нём id пользователей из таблицы users.
Это был лишь один из примеров. Всего же типов подобных связей может быть 3:
- один-к-одному;
- один-ко-многим;
- многие-ко-многим.
Давайте же рассмотрим пример каждой из этих связей.
- Курс HTML для начинающих
- Курс PHP для начинающих
- Курс MySQL для начинающих
- Курс ООП в PHP
Один-к-одному
При связи один-к-одному каждой записи таблицы соответствует только одна запись в другой таблице.
Давайте заведем ещё одну таблицу, в которой будет храниться профиль пользователя. В нём можно будет указать информацию о себе и ссылку на профиль в VKontakte.
CREATE TABLE `profiles` ( `id` INT NOT NULL , `about` TEXT NULL , `vk_link` VARCHAR(255) NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Добавим для каждого пользователя профиль:
INSERT INTO profiles (id, about, vk_link) SELECT id, "Стрессоустойчивость, коммуникабельность", CONCAT("https://vk.com/id", id) FROM users;
Посмотрим на получившиеся профили:
SELECT * FROM profiles;

Теперь каждой записи из таблицы users соответствует только одна запись из таблицы users_profiles и наоборот.
INNER JOIN
Прежде чем идти дальше и рассматривать другие типы связей, стоит изучить ещё один оператор SQL — INNER JOIN. Он используется для объединения строк из двух и более таблиц, основываясь на отношениях между ними. Для запроса используется следующий синтаксис:
SELECT столбцы FROM таблица1 INNER JOIN таблица2 ON условие_для_связи
Чтобы получить всех пользователей вместе с их профилями нам нужно выполнить следующий запрос:
SELECT * FROM users INNER JOIN profiles ON users.id = profiles.id;

Каждая строка из левой таблицы, сопоставляется с каждой строкой из правой таблицы, после этого проверяется условие.
Если мы хотим выбрать только некоторые столбцы, то после оператора SELECT нужно перед именем поля явно указать название таблицы, из которой оно берется:
SELECT users.id, users.name, profiles.vk_link FROM users INNER JOIN profiles ON users.id = profiles.id;

Алиасы
Согласитесь, в прошлом примере пришлось довольно много букв написать. Чтобы этого избежать, в запросах можно использовать алиасы для имён таблиц. Для этого после имени таблицы можно написать AS alias. Давайте для таблицы users зададим алиас — u, а для таблицы profiles — p. Эти алиасы теперь можно использовать в любой части запроса:
SELECT u.id, u.name, p.vk_link FROM users AS u INNER JOIN profiles as p ON u.id = p.id;
Заметьте, запрос сократился. Писать запрос с использованием алиаса быстрее.
Как уже говорилось выше, алиас можно использовать в любой части запроса, в том числе и в условии WHERE:
SELECT u.id, u.name, p.vk_link FROM users AS u INNER JOIN profiles as p ON u.id = p.id WHERE u.id=2;

Один-ко-многим
При такой связи одной записи в одной таблице соответствует несколько записей в другой. В начале этого урока мы рассмотрели как раз такой пример, когда говорили о добавлении в таблицу с новостями поля author_id. Таким образом, у каждой статьи есть один автор. В то же время у одного автора может быть несколько статей.
Давайте создадим таблицу для статей. Пусть в ней будет идентификатор статьи, её название, текст, и идентификатор автора.
CREATE TABLE `my_db`.`articles` ( `id` INT NOT NULL AUTO_INCREMENT , `author_id` INT NOT NULL , `name` TEXT NOT NULL , `text` TEXT NOT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Добавим несколько статей:
INSERT INTO `articles`(`author_id`, `name`, `text`) VALUES (1, "Пингвины научились летать", "Шокирующая новость поразила общественность!"); INSERT INTO `articles`(`author_id`, `name`, `text`) VALUES (1, "В городе N обнаружен зомби-вирус", "Шокирующая новость поразила общественность!"); INSERT INTO `articles`(`author_id`, `name`, `text`) VALUES (2, "Котики снижают уровень стресса", "Успокаивающая новость расслабила общественность");
Запросим теперь эти записи, чтобы убедиться, что всё ок
SELECT * FROM articles;

Давайте теперь выведем имена статей вместе с авторами. Для этого снова воспользуемся оператором INNER JOIN.
SELECT a.name, u.name FROM articles AS a INNER JOIN users AS u ON a.author_id=u.id;

Как видим, у Ивана две статьи, и ещё одна у Ольги.
Если бы мы захотели на странице со статьей выводить рядом с автором краткую информацию о нем, нам нужно было бы сделать ещё один JOIN на табличку profiles.
SELECT a.name, u.name, p.about FROM articles AS a INNER JOIN users AS u ON a.author_id=u.id INNER JOIN profiles AS p ON u.id=p.id;

LEFT JOIN
Помимо INNER JOIN, есть ещё несколько операторов класса JOIN. Один из самых частоиспользуемых — LEFT JOIN. Он позволяет сделать запрос к двум таблицам, между которыми есть связь, и при этом для одной из таблиц вернуть записи, даже если они не соответствуют записям в другой таблице.
Как например, если бы мы хотели вывести не только пользователей, у которых есть статьи, но и тех, кто «халтурит» 🙂
Давайте для начала сделаем запрос с использованием INNER JOIN, который выведет пользователей и написанные ими статьи:
SELECT u.id, u.name, a.name FROM users AS u INNER JOIN articles AS a ON u.id=a.author_id;

Теперь заменим INNER JOIN на LEFT JOIN:
SELECT u.id, u.name, a.name FROM users AS u LEFT JOIN articles AS a ON u.id=a.author_id;

Видите, вывелись записи из левой таблицы (users), которым не соответствует при этом ни одна запись из правой таблицы (articles).
Многие-ко-многим
Такая связь возникает, когда множество строк одной таблицы соответствуют множеству строк другой таблицы. Чтобы связать их между собой, нужно создать третью таблицу, создав с каждой из первых двух связь один-ко-многим.
В качестве примера такой связи можно привести рубрики статей. Каждая статья может иметь несколько рубрик. И одновременно с этим, каждая рубрика может содержать в себе несколько статей. Давайте добавим таблицу для рубрик.
CREATE TABLE `categories` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
И сразу добавим в неё несколько рубрик.
INSERT INTO `categories`(`name`) VALUES ("Хорошие новости"); INSERT INTO `categories`(`name`) VALUES ("Плохие новости"); INSERT INTO `categories`(`name`) VALUES ("Новости о животных");
Проверим, что они добавились.
SELECT * FROM categories;

Теперь нам нужно добавить ещё одну таблицу, в которой будут храниться связи между article.id и category.id. Создаём:
CREATE TABLE `articles_categories` ( `article_id` INT NOT NULL , `category_id` INT NOT NULL , PRIMARY KEY (`article_id`, `category_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Обратите внимание на составной первичный ключ. Здесь нам требуется, чтобы именно пара (id_статьи — id_рубрики) была уникальной. А сами по себе значения в отдельных колонок могут повторяться.
И давайте добавим нашу новость о котиках в категории:
- Новости о животных
- Хорошие новости
INSERT INTO `articles_categories`(`article_id`, `category_id`) VALUES (3, 1); INSERT INTO `articles_categories`(`article_id`, `category_id`) VALUES (3, 3);
Добавим также новость о вирусе в «Плохие новости».
INSERT INTO `articles_categories`(`article_id`, `category_id`) VALUES (2, 2);
а новость про пингвинах в «Новости о животных».
INSERT INTO `articles_categories`(`article_id`, `category_id`) VALUES (1, 3);
Посмотрим что у нас получилось:
SELECT * FROM articles_categories;

Теперь давайте выведем рубрики новости о котиках:
SELECT c.name FROM categories AS c INNER JOIN articles_categories AS ac ON ac.category_id=c.id INNER JOIN articles AS a ON a.id=ac.article_id WHERE a.name="Котики снижают уровень стресса";

Таким образом реализуется связь многие-ко-многим.
phpMyAdmin — создание связей между таблицами

phpMyAdmin содержит инструмент под названием Дизайнер. Этот инструмент позволяет упростить работу по созданию таблиц в базе данных и связей между таблицами.
Внимание Тип хранилища MyISAM не поддерживает внешние ключи (Foreign key). Оригинал статьи
Для начала создайте базу данных и войдите с полученными данными пользователя в phpMyAdmin.
Этап I. Создание хранилища конфигурации
- В левом поле со списком баз данных выберите вновь созданную

- Перейдите по ссылке меню Операции

- Вы увидите надпись Хранилище конфигурации phpMyAdmin неактивно. Для определения причины. Вам необходимо перейти по ссылке Для определения причины.

- Далее по ссылке Создать
Этап II. Работа с Дизайнером
- В левом поле со списком баз данных выберите вновь созданную

- Переходим в меню Ещё и подменю Дизайнер


- В панели инструмента справа выбираем Показать/Скрыть список таблиц

- Слева откроется панель со списком таблиц. Скрыть/показать ненужные таблицы, относящиеся к Хранилищу настроек (pma), можно снятием/установкой соответствующей галочки

Создание связи
- Выбираем таблицы, между которыми необходимо настроить связи

- Нажимаем Создать связь в панели инструментов

- Далее у стрелки появится надпись Выберите ссылочный ключ. Необходимо нажать на первичный ключ таблицы. В нашем случае это ключ tbl1_id в таблице table1
- Стрелка поменяет надпись на Выберите внешний ключ. Необходимо кликнуть на соответствующее поле связанной таблицы. В нашем случае это поле tbl1_id в таблице table2
- В диалоговом окне выбираем ОК


Поделиться ссылкой:
- Нажмите, чтобы поделиться на Twitter (Открывается в новом окне)
- Нажмите, чтобы открыть на Facebook (Открывается в новом окне)
Как сделать связь в MySQL?
Здравствуйте!
В интернете почитал статье и смотрел видео уроки но у меня никак не получается создать связь между таблицам
итак допустим есть два таблица
1 — post (id, status, date)
2 — post_content (id, parent_id, language, name, content)
при удаления поста нужно удалить его все контенты которые в разных языках
как можно это сделать?
у меня версия MySQL 5.7
в phpMyAdmin как сделать? или нужен запрос
по моему я не очень хорошо понял связать их
- Вопрос задан более трёх лет назад
- 2945 просмотров
Комментировать
Решения вопроса 1

Для правильного вопроса надо знать половину ответа
Если я правильно понял, то здесь у вас связь один-ко многим, поле `post_content`.`parent_id` указывает на `post`.`id`.
Для того, чтобы создать такую связь (внешний ключ, FOREIGN KEY) в MySQL сначала необходимо убедиться, что оба этих поля имеют одинаковый тип и размер и в колонке `post_content`.`parent_id` нет значений, отсутствующих в `post`.`id`.
Затем надо создать саму связь
ALTER TABLE `post_content` ADD CONSTRAINT FOREIGN KEY `fk_parent_id` (`parent_id`) REFERENCES `post` (`id`) ON DELETE CASCADE;
Этот запрос добавляет внешний ключ `fk_parent_id` с поля `parent_id` на `post`.`id` и говорит, что при удалении записи из таблицы `post` будут удалены связанные записи из `post_content`.
Ответ написан более трёх лет назад
Нравится 2 3 комментария

Дилик Пулатов @dilikpulatov Автор вопроса
спасибо большой. я точно такое делал но в место CASCADE использовал RESTRICT, поэтому у меня не получилось. просто не понимал зачем это)

Дилик Пулатов @dilikpulatov Автор вопроса
есть ещё один вопрос..
есть таблица категории
id, parent_id, status
а когда удаляю категорию, можно удалить её под категории с помощью связь?

Дилик Пулатов, Удалить можно, но не более 15 уровней вложенности. И записи верхнего уровня в такой таблице должны будут иметь `parent_id` = NULL.