Ответ
В реляционных базах данных существует три основных типа связей, которые реализуются с помощью внешних ключей (FOREIGN KEY):
-
Один к одному (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) ); -
Один ко многим (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 ); -
Многие ко многим (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, эти связи определяются в моделях, что упрощает запросы с джойнами.
Ответ 18+ 🔞
Э, слушай, давай про связи в базах данных поговорим, а то у некоторых в голове после JOIN'ов каша, хуй с горы. В реляционках, блядь, всего три основных типа связей через эти самые внешние ключи. Не овердохуища, всего три, запомнить можно.
Первый тип — один к одному. Это когда одной записи в одной таблице соответствует ровно одна хуйня в другой, и наоборот. Как паспорт у человека — один. Часто так делают, когда какие-то данные редко нужны или особо секретные, чтобы основную таблицу не засирать. Смотри, как это выглядит:
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)
);
Видишь UNIQUE на user_id? Вот это и есть вся магия, ёпта. Без него уже будет пиздец, а не связь.
Дальше идёт один ко многим — это, блядь, хлеб насущный, основа основ. Встречается на каждом шагу. Одна запись влечёт за собой кучу других. Как автор, который написал дохуя книг, а каждая книга имеет только одного автора. Проще пареной репы:
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
);
Вот тут author_id в books — это и есть та самая плодотворная связь, ядрёна вошь. Удали автора — и книги останутся сиротами, NULL станет.
А теперь, блядь, приготовься для самого интересного — многие ко многим. Тут уже без третьей, связующей таблицы не обойтись, хитрая жопа. Как студенты и курсы: один студент ходит на много курсов, на один курс записано много студентов. Реализуется через промежуточную таблицу-сводник, вот эту самую мартышлюшку:
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, тебе эту всю хуйню с джойнами руками писать не надо. Объявил связи в моделях — и потом просто include делаешь, как будто так и надо. Волнение ебать, как же это упрощает жизнь, чувак. Главное — понять, какая связь где нужна, а то можно такой пиздопроебибны наворотить, что потом сам от себя охуеешь.