Ответ
В реляционных базах данных связи (relationships) определяют, как строки одной таблицы соотносятся со строками другой. Существует три фундаментальных типа связей, реализуемых через первичные (PK) и внешние ключи (FK).
1. Один к одному (One-to-One, 1:1)
Одна запись в таблице А связана не более чем с одной записью в таблице Б, и наоборот.
Зачем это нужно? Часто используется для разделения сущности на несколько таблиц по соображениям:
- Безопасности: Конфиденциальные данные (паспорт) отдельно от основных (пользователь).
- Производительности: Часто запрашиваемые поля — в одной таблице, редко используемые — в другой.
- Наследования (Table per Hierarchy): В ORM, например, для реализации наследования.
Реализация в БД: Внешний ключ создается в любой из таблиц, но должен быть также UNIQUE, чтобы гарантировать "один к одному".
CREATE TABLE Users (
UserId INT PRIMARY KEY,
Username NVARCHAR(50) NOT NULL
);
CREATE TABLE UserProfiles (
ProfileId INT PRIMARY KEY,
UserId INT UNIQUE NOT NULL, -- И FK, и UNIQUE!
Bio NVARCHAR(MAX),
CONSTRAINT FK_Profile_User FOREIGN KEY (UserId) REFERENCES Users(UserId)
);
2. Один ко многим (One-to-Many, 1:N)
Самая распространенная связь. Одна запись в таблице А может быть связана со многими записями в таблице Б, но запись в Б связана только с одной записью в А.
Примеры: Blog → Posts, Customer → Orders, Country → Cities.
Реализация в БД: Внешний ключ создается в таблице со стороны "многих" (таблица Б).
CREATE TABLE Blogs (
BlogId INT PRIMARY KEY,
Name NVARCHAR(100) NOT NULL
);
CREATE TABLE Posts (
PostId INT PRIMARY KEY,
Title NVARCHAR(200) NOT NULL,
BlogId INT NOT NULL, -- FK на стороне "многих"
CONSTRAINT FK_Post_Blog FOREIGN KEY (BlogId) REFERENCES Blogs(BlogId)
);
3. Многие ко многим (Many-to-Many, N:N)
Одна запись в А может быть связана со многими записями в Б, и наоборот.
Примеры: Students ↔ Courses, Products ↔ Orders, Books ↔ Authors.
Реализация в БД: Требуется промежуточная таблица-связка (junction/join table). Эта таблица содержит как минимум два внешних ключа, ссылающихся на первичные ключи связываемых таблиц. Ее составной ключ (PK1+PK2) уникален и предотвращает дублирование связей.
CREATE TABLE Students (
StudentId INT PRIMARY KEY,
Name NVARCHAR(100) NOT NULL
);
CREATE TABLE Courses (
CourseId INT PRIMARY KEY,
Title NVARCHAR(100) NOT NULL
);
-- Таблица-связка
CREATE TABLE StudentCourses (
StudentId INT NOT NULL,
CourseId INT NOT NULL,
EnrollmentDate DATE,
PRIMARY KEY (StudentId, CourseId), -- Составной первичный ключ
CONSTRAINT FK_StudentCourse_Student FOREIGN KEY (StudentId) REFERENCES Students(StudentId),
CONSTRAINT FK_StudentCourse_Course FOREIGN KEY (CourseId) REFERENCES Courses(CourseId)
);
Важно в ORM (Entity Framework Core): Для связи "многие ко многим" EF Core 5+ позволяет напрямую конфигурировать коллекции без явного создания класса для таблицы-связки, но под капотом она все равно создается.