Какие виды отношений (связей) существуют в реляционных базах данных?

Ответ

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

  1. Один к одному (1:1)

    • Описание: Одна запись в таблице А связана максимум с одной записью в таблице Б, и наоборот.
    • Пример: Таблицы Пользователь и Паспортные данные. У каждого пользователя только один паспорт, и каждый паспорт принадлежит одному пользователю.
    • Реализация: Связь через внешний ключ с уникальным ограничением (UNIQUE).
  2. Один ко многим (1:N)

    • Описание: Одна запись в таблице А может быть связана с несколькими записями в таблице Б, но запись в таблице Б ссылается только на одну запись в А.
    • Пример: Таблицы Заказ и ПозицияЗаказа. Один заказ может содержать множество товарных позиций, но каждая позиция принадлежит только одному заказу.
    • Реализация: Самый распространённый тип. В таблице «многих» (Б) создаётся внешний ключ, ссылающийся на первичный ключ таблицы «одного» (А).
  3. Многие ко многим (M:N)

    • Описание: Одна запись в таблице А может быть связана с несколькими записями в таблице Б, и наоборот.
    • Пример: Таблицы Студент и Курс. Студент может записаться на несколько курсов, и на курс может быть записано несколько студентов.
    • Реализация: Требуется промежуточная таблица-связка (junction table), которая содержит составной первичный ключ из двух внешних ключей, ссылающихся на исходные таблицы.
-- Пример реализации связи M:N
CREATE TABLE Students (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE Courses (
    id INT PRIMARY KEY,
    title VARCHAR(100)
);

-- Промежуточная таблица-связка
CREATE TABLE StudentCourses (
    student_id INT REFERENCES Students(id) ON DELETE CASCADE,
    course_id INT REFERENCES Courses(id) ON DELETE CASCADE,
    PRIMARY KEY (student_id, course_id) -- Составной первичный ключ
);

Ответ 18+ 🔞

Э, слушай, а вот эти ваши реляционные базы, там же, блядь, не просто так всё устроено, а по каким-то там отношениям! И их, на самом деле, всего три вида, как три богатыря, только без коней, блядь.

Ну, первый — это типа «один к одному». Представь себе, сука, идеальную парочку, как в кино. Одна запись в одной таблице — и у неё, блядь, максимум одна парочка в другой. И наоборот, ёпта! Ну, например, Пользователь и его Паспортные данные. У тебя же, надеюсь, один паспорт на всю жизнь? Ну, если ты не какой-нибудь шпион, блядь. А паспорт этот привязан только к тебе, а не ко всему подъезду. В коде это делается через внешний ключ, но с припиской UNIQUE, чтобы второй паспорт на того же пользователя не прилепить, а то пиздец начнётся.

Дальше идёт, блядь, классика жанра — «один ко многим». Это когда одна запись — она как мать-героиня, блядь, плодит себе кучу потомков. Одна запись в таблице А может породить овердохуища записей в таблице Б. Но каждая из этих записей в Б знает только одного своего родителя! Ну, как Заказ и ПозицияЗаказа. Сделал один заказ — а в нём тебе и хлеб, и молоко, и, не дай бог, водка. Но каждая позиция в чеке привязана только к этому одному заказу, а не болтается сама по себе. Делается просто: в таблице «многих» ты лепишь внешний ключ, который тычет в «одного».

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

-- Вот смотри, как это выглядит, когда много студентов и много курсов
CREATE TABLE Students (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE Courses (
    id INT PRIMARY KEY,
    title VARCHAR(100)
);

-- А вот она, хитрая жопа, посредник!
CREATE TABLE StudentCourses (
    student_id INT REFERENCES Students(id) ON DELETE CASCADE,
    course_id INT REFERENCES Courses(id) ON DELETE CASCADE,
    PRIMARY KEY (student_id, course_id) -- Составной ключ, чтобы одну пару дважды не записать, а то будет пизда
);

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