Связь ключей в одной таблице SQL: self-join и join

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

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

SQL
Скопировать код
CREATE TABLE Employees (
  ID INT PRIMARY KEY,
  ManagerID INT REFERENCES Employees(ID),
  Name VARCHAR(100)
);

В данном коде ManagerID выступает в качестве внешнего ключа, указывающего на ID, являющийся первичным ключом. Это позволяет нам устанавливать взаимосвязи между сотрудниками внутри одной организации, как в виртуальном офисе.

Зачем нужны самоссылочные ключи?

Моделирование иерархических данных

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

Организация древовидных данных

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

Поддержка структурированности и целостности.

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

Управление ключевыми отношениями

Каскадирование: польза или вред?

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

Самоссылочность: как в меню ресторана

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

SQL
Скопировать код
-- Моделирование иерархии в ресторане по SQL Server
CREATE TABLE RestaurantStaff (
  StaffID INT PRIMARY KEY,
  SupervisorID INT,
  Name VARCHAR(100),
  CONSTRAINT fk_supervisor
    FOREIGN KEY (SupervisorID)
    REFERENCES RestaurantStaff(StaffID)
    ON DELETE SET NULL -- Официант остается без присмотра после увольнения супервайзера.
);

Здесь StaffID – это ПК, а SupervisorIDВК.

Внимание: активная база данных живет динамической жизнью!

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

Визуализация

Можно представить самоссылочный внешний ключ в виде следующей картинки:

Markdown
Скопировать код
      +-----------+
      |   Таблица |
      |-----------|
      | ПК  |  ВК |
      +-----------+
        🌳  |  🔄
           \|/
        +-----------+
        | Дочерняя |
        |   строка |
        |-----------|
        | ПК  |  ВК |
        +-----------+

Каждый "родительский" ПК может породить "дочернюю" строку с соответствующим ВК. Картинка дерева носит упрощенный характер.

Подробности самоприсоединений

Извлечение связанных данных

Важно не только хранить, но и умело извлекать информацию, а самоприсоединения идеально подходят для этого:

SQL
Скопировать код
-- Взглянем на иерархию сотрудников без корпоративных интриг
SELECT e1.Name AS Сотрудник, COALESCE(e2.Name, 'Топ-менеджмент') AS Руководитель
FROM RestaurantStaff e1
LEFT JOIN RestaurantStaff e2 ON e1.SupervisorID = e2.StaffID;

Такое присоединение позволяет отобразить структуру корпоративной иерархии.

Разбор вложенных отношений

SQL может провести исправительную работу, подобно строгому начальнику, выстраивая вложенные данные:

SQL
Скопировать код
-- Что происходит за кулисами ресторана
WITH RECURSIVE subordinates AS (
  SELECT StaffID, Name, SupervisorID
  FROM RestaurantStaff
  WHERE SupervisorID IS NULL -- Здесь начинается топ-менеджмент
  UNION ALL
  SELECT e.StaffID, e.Name, e.SupervisorID 
  FROM RestaurantStaff e
  INNER JOIN subordinates s ON e.SupervisorID = s.StaffID 
) 
SELECT * FROM subordinates;

Данный рекурсивный запрос связывает SupervisorID и StaffID, таким образом строя иерархическую структуру прямо в таблице.

Советы от мастера

«С большими возможностями приходят большие ответственности». Не забывайте об этом, чтобы избежать бесконечных циклов и неожиданных массовых обновлений. Всё проверяйте вдвое до начала реализации.

Полезные материалы

  1. SQL Self Join — Изучение тонкостей самоприсоединений.
  2. SQL FOREIGN KEY Constraint — Все, что нужно знать о внешних ключах, включая использование в рамках одной таблицы.
  3. Self-referencing constraint in MS SQL – Stack Overflow — Примеры и дискуссии о самоссылочных ключевых отношениях.
  4. MySQL :: MySQL 8.0 Reference Manual :: FOREIGN KEY ConstraintsОфициальная документация MySQL по внешним ключам.
  5. Managing Hierarchical Data in MySQL — Mike Hillyer's Personal Webspace — Глубокое погружение в вопрос работы с иерархическими данными.
  6. PostgreSQL: Documentation: Foreign Key Constraints — Детальное руководство по ключевым связям в PostgreSQL.
  7. A Quick Look at Self-referencing Relationships in an ERD – Vertabelo — Подробное руководство по самоссылочным отношениям в ER-диаграммах.