Реляционная модель: таблицы, ключи, связи
Реляционная модель: таблицы, ключи, связи
Чтобы грамотно читать и писать SQL-запросы, нужно понимать, как устроена реляционная база данных. В этом уроке разберём структуру таблиц, типы данных, ключи и связи между таблицами.
Таблица: основной элемент
Реляционная БД хранит данные в таблицах. Каждая таблица — это сетка из строк и столбцов.
Таблица users:
+----+----------+---------------------+---------------------+-----------+
| id | name | email | created_at | is_active |
+----+----------+---------------------+---------------------+-----------+
| 1 | Анна | anna@example.com | 2024-01-15 10:00:00 | true |
| 2 | Пётр | petr@example.com | 2024-01-20 14:30:00 | true |
| 3 | Мария | maria@example.com | 2024-02-01 09:00:00 | false |
+----+----------+---------------------+---------------------+-----------+
- Строка (row / record) — одна запись, один объект
- Столбец (column / field) — атрибут с определённым типом данных
- Схема таблицы — набор столбцов с типами и ограничениями
Типы данных
Каждый столбец хранит данные строго определённого типа.
| Тип | Описание | Пример значения |
|---|---|---|
INTEGER / INT | Целое число | 42, -5, 0 |
BIGINT | Большое целое | 9999999999 |
DECIMAL(10,2) | Число с фиксированной точностью | 1234.56 |
VARCHAR(255) | Строка ограниченной длины | 'Анна' |
TEXT | Строка неограниченной длины | Длинный текст |
BOOLEAN | Булево значение | true / false |
TIMESTAMP | Дата и время | 2024-01-15 10:00:00 |
DATE | Только дата | 2024-01-15 |
UUID | Уникальный идентификатор | 550e8400-e29b-... |
SERIAL | Автоинкремент (PostgreSQL) | 1, 2, 3, ... |
Первичный ключ (Primary Key)
Первичный ключ (PK) — столбец или набор столбцов, который уникально идентифицирует каждую строку таблицы.
Свойства:
- Уникален — нет двух строк с одинаковым PK
- NOT NULL — всегда имеет значение
- Неизменяем — не меняется за время жизни записи
CREATE TABLE users (
id SERIAL PRIMARY KEY, -- автоинкремент: 1, 2, 3 ...
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL
);
Обычно PK — это
SERIAL(автоинкремент) илиUUID.
Внешний ключ (Foreign Key)
Внешний ключ (FK) — столбец, который ссылается на первичный ключ другой таблицы. Обеспечивает ссылочную целостность: нельзя создать заказ для несуществующего пользователя.
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id), -- FK → users.id
status VARCHAR(20) NOT NULL,
total DECIMAL(10,2),
created_at TIMESTAMP DEFAULT NOW()
);
Попытка вставить заказ с несуществующим user_id вызовет ошибку:
ERROR: insert or update on table "orders" violates foreign key constraint
DETAIL: Key (user_id)=(999) is not present in table "users".
Типы связей

Один ко многим (1:N) — самая распространённая
Один пользователь → много заказов. FK находится на стороне «многих».
users orders
| id | name | | id | user_id | total |
|----|------| |----|---------|-------|
| 1 | Анна |←-| 1 | 1 | 5000 |
| 2 | Пётр | | 2 | 1 | 1200 |
←-| 3 | 2 | 800 |
Один к одному (1:1)
Каждой записи в таблице A соответствует ровно одна в таблице B. Например, пользователь и его профиль.
CREATE TABLE user_profiles (
user_id INT PRIMARY KEY REFERENCES users(id),
avatar_url TEXT,
bio TEXT
);
Многие ко многим (M:N)
Один заказ включает много товаров, и один товар может быть в многих заказах. Реализуется через промежуточную таблицу.
CREATE TABLE order_items (
id SERIAL PRIMARY KEY,
order_id INT REFERENCES orders(id),
product_id INT REFERENCES products(id),
quantity INT NOT NULL,
price DECIMAL(10,2) NOT NULL
);
Ограничения (Constraints)
Ограничения — правила, которые база проверяет при каждом изменении данных.
| Constraint | Назначение | Пример |
|---|---|---|
PRIMARY KEY | Уникальный непустой идентификатор | id SERIAL PRIMARY KEY |
FOREIGN KEY | Ссылочная целостность | REFERENCES users(id) |
NOT NULL | Столбец не может быть NULL | name VARCHAR(100) NOT NULL |
UNIQUE | Все значения уникальны | email VARCHAR(255) UNIQUE |
CHECK | Произвольное условие | CHECK (price > 0) |
DEFAULT | Значение по умолчанию | DEFAULT NOW() |
NULL: отсутствие значения
NULL — это не пустая строка и не ноль. Это отсутствие значения. Любое сравнение с NULL через = возвращает NULL (не true и не false).
-- Неверно: никогда не сработает как ожидается
SELECT * FROM users WHERE phone = NULL;
-- Верно: используйте IS NULL / IS NOT NULL
SELECT * FROM users WHERE phone IS NULL;
SELECT * FROM users WHERE phone IS NOT NULL;
Учебная схема модуля
Все примеры в модуле используют эту схему интернет-магазина:
users (id, name, email, created_at, is_active)
orders (id, user_id→users, status, total, created_at)
products (id, name, category, price, stock)
order_items (id, order_id→orders, product_id→products, quantity, price)
Итоги
- Таблица состоит из строк (записей) и столбцов (полей с типами)
- Primary Key — уникальный идентификатор строки, никогда не NULL
- Foreign Key — ссылка на PK другой таблицы, обеспечивает целостность
- Связи: 1:1, 1:N (самая частая), M:N (через промежуточную таблицу)
- Constraints — правила данных: NOT NULL, UNIQUE, CHECK, DEFAULT
- NULL — отсутствие значения; проверяйте через
IS NULL, не через= NULL