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

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

Ответ

В реляционных базах данных существует три основных типа связей, которые реализуются с помощью внешних ключей (FOREIGN KEY):

  1. Один к одному (One-to-One, 1:1) Одна запись в таблице А связана максимум с одной записью в таблице Б, и наоборот. Часто используется для разделения редко используемых или чувствительных данных.

    -- Пример: Пользователь и его паспортные данные
    CREATE TABLE users (
        id SERIAL PRIMARY KEY,
        email VARCHAR(255) UNIQUE NOT NULL
    );
    CREATE TABLE user_profiles (
        id SERIAL PRIMARY KEY,
        user_id INT UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,
        passport_number VARCHAR(50)
    );
  2. Один ко многим (One-to-Many, 1:N) Наиболее распространенный тип. Одна запись в таблице А может быть связана со многими записями в таблице Б, но запись в Б ссылается только на одну запись в А.

    -- Пример: Автор и его книги
    CREATE TABLE authors (
        id SERIAL PRIMARY KEY,
        name VARCHAR(255) NOT NULL
    );
    CREATE TABLE books (
        id SERIAL PRIMARY KEY,
        title VARCHAR(255) NOT NULL,
        author_id INT NOT NULL REFERENCES authors(id) ON DELETE SET NULL
    );
  3. Многие ко многим (Many-to-Many, N:M) Реализуется через третью, связующую таблицу (junction table). Одна запись в А может быть связана со многими записями в Б, и наоборот.

    -- Пример: Студенты и курсы
    CREATE TABLE students (
        id SERIAL PRIMARY KEY,
        name VARCHAR(255) NOT NULL
    );
    CREATE TABLE courses (
        id SERIAL PRIMARY KEY,
        title VARCHAR(255) NOT NULL
    );
    CREATE TABLE enrollments ( -- Связующая таблица
        student_id INT NOT NULL REFERENCES students(id) ON DELETE CASCADE,
        course_id INT NOT NULL REFERENCES courses(id) ON DELETE CASCADE,
        enrolled_at TIMESTAMP DEFAULT NOW(),
        PRIMARY KEY (student_id, course_id)
    );

В Node.js приложениях, использующих ORM вроде Sequelize или TypeORM, эти связи определяются в моделях, что упрощает запросы с джойнами.