Виды связей между таблицами

Виды связей между таблицами

В данном посте будут рассмотрены различные связи между таблицами базы данных.

Понятие базы данных

База данных — это совокупность таблиц и других структурных элементов, предназначенных для хранения и управления данными. Таким структурными элементами могут быть триггеры, хранимые процедуры и даже формы ввода и отчеты, если, например, речь идет о базах данных MS Access, где все структурные элементы хранятся в одном файле.

В классическом же понимании базы данных формы и отчеты в ее понятие не входят.

Понятие связей между таблицами

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

Таблица базы данных представляет из себя обычную таблицу, состоящую из строк и столбцов. Столбцы называются полями, а строки — записями таблицы.

Понятие таблицы базы данных
Таблица базы данных

Как видно из рисунка, каждый столбец таблицы называется ее полем, а каждая строка есть запись.

В базе данных обычно бывает несколько таблиц. Эти таблицы объединяются между собой связями по ключевым полям. Для чего это нужно?

Данные не могут храниться только в одной таблице как минимум по двум причинам:

  • хранить таким образом данные неудобно;
  • все хранящиеся данных таким образом будут задвоены, затроены и так далее. На языке информатике это называется излишними данными или избыточными.

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


Группа Товар Единица измерения Дата Количество
Напитки CocaCola шт. 01.06.2024 100
Напитки PepsiCola шт. 01.062024 200
Напитки Mirinda шт. 03.06.2024 150
Овощи Картофель кг. 04.06.2024 200
Овощи Помидоры кг. 04.06.2024 150
Овощи Огурцы кг. 05.06.2024 150
Овощи Морковь кг. 06.06.2024 250
Овощи Картофель кг. 07.06.2024 400
Фрукты Мандарины кг. 07.06.2024 300
Фрукты Персики кг. 07.06.2024 200

В данной таблице совершенно очевидно, что столбец «Группа» содержит дублирующие значения. Тоже самое можно сказать и о столбце «Единица измерения».

Основная цель при проектировании базы данных заключается в том, чтобы разбить такую общую таблицу на несколько более мелких таблиц. Таким образом будут образованы справочные таблицы, информация, в которых меняется редко. Оставшаяся таблица за минусом справочных таблиц будет называться оперативной или учетной и в нее будут подставляться вместо реальных значений лишь коды строк из справочников. Это называется четвертой нормальной формой (если простым языком), при которой не допускается никакое дублирование данных. И сейчас мы обратимся к примеру, который покажет, как мы можем разбить нашу таблицу.

Ну если быть более точным, то давайте называть вещи своими именами. Пока это не таблица, а сущность. Таблицей она станет тогда, когда мы начнем ее проектировать как физическую модель данных.

Разобьем имеющуюся таблицу на четыре таблицы и назовем их: «Группы», «Товары», «Единицы измерения» и «Поступления». Так вот справочниками у нас будут как раз первые три таблицы, а «Поступления» будет учетной таблицей.

Теперь таблица «Группы» будет выглядеть так:


Код группы Группа
1 Напитки
2 Овощи
3 Фрукты

Вторая таблица «Единица измерения» будет выглядеть так:


Код единицы измерения Единица измерения
1 шт.
2 кг.

Причем стоит отметить, что первые столбцы обоих таблиц представляют из себя так уникальное поле или как его еще называют — первичный ключ (Primary key) или PK. То есть, он не должен повторяться.

Третья таблица «Товары» будет выглядеть следующим образом:


Код товара Код группы Код единицы измерения Товар
1 1 1 CocaCola
2 1 1 PepsiCola
3 1 1 Mirinda
4 2 2 Картофель
5 2 2 Помидоры
6 2 2 Огурцы
7 2 2 Морковь
8 3 2 Мандарины
9 3 2 Персики

Здесь мы видим, что второй столбец содержит коды групп, к которым принадлежит тот или иной товар. Такой столбец называется внешним ключом или Foreign Key (FK).

Четвертая же таблица «Поступления» будет выглядеть следующим образом:


Код поступления Код товара Дата Количество
1 1 01.06.2024 100
2 2 01.06.2024 200
3 3 03.06.2024 150
4 4 04.06.2024 200
5 5 04.06.2024 150
6 6 05.06.2024 150
7 7 06.06.2024 150
8 4 07.06.2024 400
9 8 07.06.2024 300
10 9 07.06.2024 200

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

Итак, перейдем к вопросам, касающихся типов связи между таблицами.

Виды связей между таблицами

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

Главные таблицы могут еще называться родительскими, а подчиненные — дочерними. Более того, таблицы бывают справочные (учетно-постоянные), в которых информация меняется крайне редко и оперативные (учетные), в которых информация меняется регулярно.

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

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

Далее мы рассмотрим типы связей между таблицами и в процессе этого на примерах станет понятно, что такое главные (родительские) таблицы и что такое подчиненные (дочерние) таблицы.

В базе данных существует несколько видов связей между таблицами:

  • один-к-одному. Такая связь устанавливается, когда одна запись родительской таблицы соответствует одной записи из дочерней таблицы;
  • один-ко-многим. Когда одна запись из родительской таблицы соответствует множеству записей из дочерней таблицы;
  • много-к-одному. Когда множество записей из родительской таблицы соответствует одной записи из дочерней таблицы;
  • много-ко-многим. Когда множество записей из родительской таблицы соответствует множеству записей из дочерней.

На практике нужны будут в 99% случаев два вида связи: один-ко-многим и много-ко-многим. Связь по типу один-к-одному, как правило, не нужна и такие две таблицы можно объединить в одну. Поэтому давайте подробнее рассмотрим два следующих типа связи: один-ко-многим и много-к одному:

Вид связи между таблицами один-ко-многим

Ну и конечно обратимся при рассмотрении к нашему вышеописанному примеру. Давайте возьмем из этого примера две таблицы: Группы и Товары.

Смотрите... В таблице «Группы» мы возьмем, например запись с кодом группы «1». Название этой группы у нас «Напитки». Эта таблица у нас будет родительской. Теперь давайте возьмем таблицу «Товары». Она у нас будет дочерней по отношению к таблице «Группы». В этой таблице, как и в таблице «Группы» есть поле «Код группы». И посмотрите на его значения. Они повторяются у некоторых товаров. Это значит, что мы эти товары отнесли к первой группе. Это и есть связь один-ко-многим, когда одно значение поля «Код группы» из таблице «Группы» несколько раз встречается в таком же поле, но в таблице «Товары».

Так вот, поле «Код группы» родительской таблицы «Группы» называется первичным ключом. Такой ключ не может повторяться в таблице «Группы». Это как справочник.

А вот в таблице «Товары» значение данного ключа может повторяться сколь угодно много. И здесь, в таблице «Товары» это поле называется внешний ключом. То есть, это значит, что поле связано с внешней (родительской) таблицей.

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

Тип связи один-ко-многим
Тип связи один-ко-многим

Отлично. Но у нас есть еще один справочник, который называется «Единицы измерения». И он у нас тоже является родительской таблицей по отношению к таблице «Товары» и тоже связан с ней видом связи один-ко-многим. Давайте добавим предыдущую картинку еще одной таблицей и получим:

Вид связи "один-ко-многим"
Один-ко-многим с тремя таблицами

Теперь у нас две родительские таблицы соединены с третьей и каждая из этих родительских таблиц соединена с дочерней (Товары) связью один-ко-многим.

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

Четвертая нормальная форма
Четвертая нормальная форма

Таким образом, мы из одной таблицы получили четыре таблицы. Теперь база данных соответствует четвертой нормальной форме. Не путать с количеством таблиц (просто так совпало).

Четвертая нормальная форма (4NF) — представляет из себя уровень нормализации базы данных, отсутствуют нетривиальные многозначные зависимости, отличные от ключа-кандидата. Иными словами обеспечена ссылочная целостностью и уменьшено дублирование данных до максимально возможного.

Но перед тем, как перейти к рассмотрению другого вида связи, хочется еще упомянуть об одной разновидности связи один-ко-многим. Но для этого мы обратимся к другому примеру. (пример расписания, когда к одной таблице подходят две связи от одной таблицы)

Разновидность связи один-ко-многим
Разновидность связи один-ко-многим

Посмотрите на эту схему. Таблицы «Регионы», «Районы» и «Пункты» имеют связь один-ко-многим. Родительская таблица «Регионы» связана такой связью с таблицей «Районы», поскольку в каждом регионе может быть от одного до нескольких районов. А таблица «Районы» являясь дочерней для таблицы «Регионы», является родительской для таблицы «Пункты» и также объединена с ней в связь один-ко-многим, потому что в каждом районе множество населенных пунктов.

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

При такой связи в таблицу «Направления» будут подставляться из справочника id пункта отправления и id пункта прибытия.

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

Давайте перейдем теперь к рассмотрению еще одного интересного вида связи «много-ко-многим».

Вид связи между таблицами много-ко-многим

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

Допустим, что у нас есть две таблицы: «Учителя» и «Предметы». Конечно же, такие таблицы можно объединить связью один-ко-многим, где таблица «Учителя» будет родительской, так как один учитель может вести несколько предметов.

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

Связь много-ко-многим
Связь много-ко-многим

Да, абсолютно верно! Такая связь состоит из двух связей один-к-одному. У нас есть два справочник «Учителя» и «Предметы». А в третьей таблице мы добавляем их различные комбинации и получаем результат, при котором один и тот же учитель может вести разные предметы, а также один и тот же предмет могут преподавать разные учителя.

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

    Понравилась статья? Поделиться с друзьями:
    Блог Алексея Иванкова
    Добавить комментарий

    ;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: