Вопросы и ответы с собеседования по базам данных и SQL
1. Какие есть типы связей таблиц?
Базы данных могут содержать таблицы, которые связаны между собой различными связями. Связь (relationship) представляет ассоциацию между сущностями разных типов. При выделении связи выделяют главную или родительскую таблицу (primary key table / master table) и зависимую, дочернюю таблицу (foreign key table / child table). Дочерняя таблица зависит от родительской. Для организации связи используются внешние ключи. Внешний ключ представляет один или несколько столбцов из одной таблицы, который одновременно является потенциальным ключом из другой таблицы. Внешний ключ необязательно должен соответствовать первичному ключу из главной таблицы. Хотя, как правило, внешний ключ из зависимой таблицы указывает на первичный ключ из главной таблицы. Связи между таблицами бывают следующих типов: - Один к одному (One to one) - Один к многим (One to many) - Многие ко многим (Many to many)
2. Что такое связь "один к одному"?
Данный тип связей встречается не часто. В этом случае объекту одной сущности можно сопоставить только один объект другой сущности. Например, на некоторых сайтах пользователь может иметь только один блог. То есть возникает отношение один пользователь - один блог.
Нередко этот тип связей предполагает разбиение одной большой таблицы на несколько маленьких. Основная родительская таблица в этом случае продолжает содержать часто используемые данные, а дочерняя зависимая таблица обычно хранит данные, которые используются реже.
В этом отношении первичный ключ зависимой таблицы в то же время является внешним ключом, который ссылается на первичный ключ из главной таблицы.
Например, таблица Users
представляет пользователей и имеет следующие столбцы:
- UserId
(идентификатор, первичный ключ)
- Name
(имя пользователя)
И таблица Blogs
представляет блоги пользователей и имеет следующие столбцы:
- BlogId
(идентификатор, первичный и внешний ключ)
- Name
(название блога)
В этом случае столбец BlogId
будет хранить значение из столбца UserId
из таблицы пользователей. То есть столбец BlogId
будет выступать одновременно первичным и внешним ключом.
3. Что такое связь "один ко многим"?
Это наиболее часто встречаемый тип связей. В этом типе связей несколько строк из дочерний таблицы зависят от одной строки в родительской таблице. Например, в одном блоге может быть несколько статей. В этом случае таблица блогов является родительской, а таблица статей - дочерней. То есть один блог - много статей. Или другой пример, в футбольной команде может играть несколько футболистов. И в то же время один футболист одновременно может играть только в одной команде. То есть одна команда - много футболистов.
К примеру, пусть будет таблица Articles
, которая представляет статьи блога и которая имеет следующие столбцы:
- ArticleId
(идентификатор, первичный ключ)
- BlogId
(внешний ключ)
- Title
(название статьи)
- Text
(текст статьи)
В этом случае столбец BlogId
из таблицы статей будет хранить значение из столбца BlogId
из таблицы блогов.
4. Что такое связь "многие ко многим"?
При этом типе связей одна строка из таблицы А
может быть связана с множеством строк из таблицы В
. В свою очередь одна строка из таблицы В
может быть связана с множеством строк из таблицы А
. Типичный пример - студенты и курсы: один студент может посещать несколько курсов, и соответственно на один курс могут записаться несколько студентов.
Другой пример - статьи и теги: для одной статьи можно определить несколько тегов, а один тег может быть определен для нескольких статей.
Но на уровне базы данных мы не можем установить прямую связь многие ко многим между двумя таблицами. Это делается посредством вспомогательной промежуточной таблицы. Иногда данные из этой промежуточной таблицы представляют отдельную сущность.
Например, в случае со статьями и тегами пусть будет таблица Tags
, которая имеет два столбца:
- TagId
(идентификатор, первичный ключ)
- Text
(текст тега)
Также пусть будет промежуточная таблица ArticleTags
со следующими полями:
- TagId
(идентификатор, первичный и внешний ключ)
- ArticleIdId
(идентификатор, первичный и внешний ключ)
Технически мы получим две связи один-ко-многим. Столбец TagId
из таблицы ArticleTags
будет ссылаться на столбец TagId
из таблицы Tags
. А столбец ArticleId
из таблицы ArticleTags
будет ссылаться на столбец ArticleId
из таблицы Articles
.
То есть столбцы TagId
и ArticleId
в таблице ArticleTags
представляют составной первичный ключ и одновременно являются внешними ключами для связи с таблицами Articles
и Tags
.