Как реализуется связь «многие ко многим» в реляционных базах данных?

«Как реализуется связь «многие ко многим» в реляционных базах данных?» — вопрос из категории Базы данных и SQL, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Связь «многие ко многим» (many-to-many) означает, что множество записей в таблице A может быть связано с множеством записей в таблице B, и наоборот. Прямая реализация в реляционной модели невозможна, поэтому используется промежуточная таблица (junction/association table).

Ключевые принципы:

  1. Промежуточная таблица содержит как минимум два внешних ключа, ссылающихся на первичные ключи связанных таблиц.
  2. Комбинация этих внешних ключей часто образует составной первичный ключ промежуточной таблицы.
  3. Промежуточная таблица может содержать дополнительные атрибуты, описывающие саму связь (например, дату зачисления).

Пример SQL:

-- Основные таблицы
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,
    enrolled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (student_id, course_id) -- Составной ключ
);

Как это работает:

  • Чтобы добавить студента на курс, в StudentCourses вставляется запись (student_id, course_id).
  • Запрос для поиска всех курсов студента:
    SELECT c.* FROM Courses c
    JOIN StudentCourses sc ON c.id = sc.course_id
    WHERE sc.student_id = 123;
  • Связь обеспечивается через JOIN-операции с промежуточной таблицей.