Логотип Workflow

Article

Updated at:

Relational Model

Stage 1. Реляционные базы данных и реляционная модель

Реляционная база данных — это база, которая хранит структурированные данные в таблицах и позволяет связывать записи, относящиеся друг к другу. Модель называется реляционной, потому что данные не складываются в один огромный объект или один длинный файл. Вместо этого связанные факты разделяются по таблицам, а отношения между строками выражаются через ключи.

Реляционная модель — это способ организовать данные так, чтобы база оставалась понятной и надежной даже при росте проекта. В таблице есть столбцы, которые описывают хранимые поля, и строки, которые содержат конкретные записи. Главная польза модели: вы заранее задаете структуру, связи и ограничения, а база помогает не допускать хаос в данных.

Relational model overview

Базовые термины без перегруза

ТерминЧто это значит на практикеПример
ТаблицаНабор однотипных объектовusers, orders
СтолбецПоле объекта с типом данныхemail, created_at
СтрокаОдин конкретный объектОдин заказ
Primary keyУникальный идентификатор строкиorders.id
Foreign keyСсылка на строку другой таблицыorders.user_id -> users.id
RDBMS/СУБДПрограмма, которая управляет реляционной базойPostgreSQL, MySQL, Oracle Database
ОграничениеПравило, которое проверяет сама базаNOT NULL, UNIQUE

Ключевая идея: одна таблица должна хранить один тип сущности. Пользователь — в users, заказ — в orders, оплата — в payments. Если дублировать данные пользователя в каждой строке заказа, рано или поздно возникнут расхождения.

RDBMS, или реляционная система управления базами данных, — это программный слой, который хранит таблицы, проверяет правила, выполняет SQL-запросы, управляет доступом и делает данные устойчивыми к сбоям. Когда разработчики говорят “мы используем PostgreSQL” или “приложение пишет в MySQL”, обычно имеется в виду, что приложение обращается к СУБД, а СУБД управляет реальными файлами и операциями реляционной базы.

Почему таблицы разделяют, а не дублируют

Представьте небольшой магазин с клиентами и заказами. Простое, но слабое решение — хранить имя клиента, телефон, адрес и все детали заказа в одной большой таблице orders. Сначала это кажется удобным, но быстро появляются проблемы. Если клиент меняет адрес, нужно обновить много строк. Если одну строку забыли, в базе уже есть несколько противоречащих версий одного клиента.

Реляционный подход хранит данные клиента один раз в users, а данные заказа — в orders. Колонка orders.user_id указывает на нужную строку в users. Общий ключ позволяет приложению найти адрес доставки клиента при обработке заказа без копирования этих данных в каждую строку заказа. На этой идее строятся следующие темы: joins, нормализация и ограничения внешних ключей.

Простая схема для старта

CREATE TABLE users (
  id BIGSERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL
);

CREATE TABLE orders (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT NOT NULL REFERENCES users(id),
  amount NUMERIC(10,2) NOT NULL,
  status TEXT NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

Что обеспечивается этой схемой:

  • PRIMARY KEY гарантирует уникальность строки;
  • FOREIGN KEY запрещает заказ без существующего пользователя;
  • NOT NULL защищает обязательные поля;
  • UNIQUE не даст два одинаковых email.

Эти гарантии — примеры целостности данных. Целостность означает, что база не просто хранит байты, а применяет правила, которые сохраняют смысл данных. Таблица может отклонить пустое обязательное значение, повторяющийся идентификатор, ссылку на несуществующую строку или значение неправильного типа. Это важно, потому что в реальных системах данные часто записывает не только основной код приложения. Импорты, админки, фоновые задачи и несколько сервисов могут работать с одной базой. Правила на уровне базы защищают данные даже тогда, когда у одного из клиентов есть ошибка.

Логическая модель и физическое хранение

Реляционная база отделяет логическую структуру от физического хранения. Логическая структура — это то, с чем работает разработчик: таблицы, колонки, представления, индексы, ключи и ограничения. Физическое хранение — это то, как СУБД размещает данные на диске или в памяти, делит файлы, кэширует страницы и эффективно ищет строки.

Это разделение важно. Разработчик может написать SELECT * FROM orders и не знать, в каком файле лежат строки и сколько страниц диска прочитает СУБД. Администратор базы может переносить файлы, настраивать хранение, добавлять индексы или менять внутреннюю организацию данных без переименования таблицы orders в приложении. SQL описывает, какие данные нужны; СУБД решает, как к ним обратиться.

Пошаговый разбор запроса (строка за строкой)

SELECT id, user_id, amount, status, created_at
FROM orders
WHERE status = 'PAID'
ORDER BY created_at DESC
LIMIT 5;

Разбираем каждую строку:

  1. SELECT id, user_id, amount, status, created_at: Какие колонки вернуть в ответ. Здесь мы явно выбираем только нужные поля, а не *.
  2. FROM orders: Из какой таблицы брать данные. Источник выборки — таблица заказов.
  3. WHERE status = 'PAID': Условие фильтрации. В результат попадут только оплаченные заказы.
  4. ORDER BY created_at DESC: Сортировка результата. DESC означает от новых к старым.
  5. LIMIT 5: Ограничение количества строк. Возьмем только 5 записей после фильтра и сортировки.

Итоговый смысл всего запроса: “Покажи 5 последних оплаченных заказов”.

SQL, транзакции и согласованность

SQL — стандартный язык для определения, чтения и изменения данных в реляционных базах. CREATE TABLE задает структуру, INSERT добавляет строки, SELECT читает строки, а в следующих уроках появятся UPDATE, DELETE, joins, группировка, индексы и транзакции. SQL декларативен: обычно вы описываете нужный результат, а СУБД строит план выполнения.

Реляционные базы часто выбирают там, где особенно важна корректность. Например, если банковское пополнение сохранено, обновленный баланс должен быть виден согласованно. Если интернет-магазин резервирует несколько товаров, которые должны уйти вместе, то должны зафиксироваться все изменения остатков или ни одно из них. Такое поведение “все или ничего” называется атомарностью.

Атомарность входит в ACID — набор свойств транзакций, с которыми обычно ассоциируют реляционные базы:

СвойствоПрактический смысл
Atomicity / атомарностьТранзакция выполняется полностью или не применяется вообще
Consistency / согласованностьДанные остаются валидными по правилам базы
Isolation / изоляцияНезавершенные изменения не должны сбивать другие параллельные операции
Durability / долговечностьЗафиксированные изменения переживают сбои, например перезапуск

На первом уроке не нужно подробно разбираться с транзакциями, но важно понять: реляционная модель — это не только таблицы. Она также дает базе способ поддерживать точность данных по правилам, пока с ними одновременно работают многие пользователи и программы.

Параллельный доступ и блокировки

Реальные базы используются совместно. Несколько пользователей, API-запросов, фоновых обработчиков и отчетов могут читать или менять данные одновременно. Конкурентность — это способность базы обслуживать такую параллельную активность и при этом сохранять корректность.

Когда две операции пытаются изменить одну и ту же строку, СУБД может использовать блокировки или версионность, чтобы итоговое состояние осталось валидным. Блокировка временно защищает данные, которые сейчас изменяются. Хорошие реляционные базы стараются блокировать только необходимое, часто одну строку, а не всю таблицу, потому что широкие блокировки ухудшают производительность. Уровни изоляции будут отдельной темой позже, но базовая идея простая: база должна сочетать скорость с безопасным доступом к общим данным.

Что важно понять до следующей темы

Реляционная модель — это не сложная теория, а практический каркас для хранения связанных фактов с понятными правилами. Если таблицы разделены по сущностям, ключи заданы, связи корректны, а ограничения защищают важные поля, то SQL-запросы становятся предсказуемыми и намного проще для поддержки.

При выборе или использовании СУБД команды обычно смотрят на точность данных, масштабируемость, конкурентность, производительность, надежность и удобство эксплуатации. У разных продуктов разные сильные стороны, но базовые реляционные идеи остаются общими: таблицы представляют структурированные факты, ключи связывают эти факты, ограничения защищают их, а SQL дает приложениям общий способ с ними работать.

Практика перед следующим уроком

Скопируйте команды ниже и выполните их по шагам.

Шаг 1. Добавьте пользователей:

INSERT INTO users(name, email) VALUES
('Anna', '[email protected]'),
('Ivan', '[email protected]'),
('Olga', '[email protected]');

Шаг 2. Добавьте заказы:

INSERT INTO orders(user_id, amount, status, created_at) VALUES
(1, 1200.00, 'PAID', '2026-05-10 12:00:00'),
(1, 300.00,  'NEW',  '2026-05-10 11:00:00'),
(2, 700.00,  'PAID', '2026-05-10 10:00:00'),
(3, 450.00,  'CANCELLED', '2026-05-10 09:00:00'),
(2, 900.00,  'PAID', '2026-05-10 08:00:00'),
(1, 150.00,  'PAID', '2026-05-10 07:00:00'),
(3, 510.00,  'NEW',  '2026-05-10 06:00:00'),
(2, 810.00,  'PAID', '2026-05-10 05:00:00');

Шаг 3. Запустите запрос:

SELECT id, user_id, amount, status, created_at
FROM orders
WHERE status = 'PAID'
ORDER BY created_at DESC
LIMIT 5;

Шаг 4. Сверьте результат:

  • должны остаться только строки со статусом PAID;
  • первая строка должна быть самой новой по created_at;
  • строк должно быть не больше 5.

Если у вас вышло иначе, значит ошибка в одном из блоков: WHERE, ORDER BY или LIMIT.