Три уровня модели: conceptual, logical, physical
Когда говорят «модель данных», на самом деле имеют в виду одну из трёх разных вещей. Модель существует на трёх уровнях абстракции — conceptual, logical, physical — и каждый уровень отвечает на свой вопрос, рассчитан на свою аудиторию и содержит свой объём деталей. Путать их — частая ошибка новичка: показать бизнесу физическую модель с типами данных и индексами так же бесполезно, как отдать программисту conceptual-набросок без ключей.
Этот урок разбирает все три уровня и переходы между ними. Это базовый словарь профессии — на него опираются все следующие модули.
Зачем вообще три уровня
Идея трёх уровней — это применение принципа «разделяй ответственность». У модели данных три разные задачи:
- Договориться с бизнесом, ЧТО мы вообще моделируем.
- Спроектировать строгую структуру, не привязываясь к конкретной СУБД.
- Реализовать структуру в конкретной СУБД с учётом её особенностей.
Смешивать их в одном документе вредно. Обсуждая с менеджером, какие сущности есть в системе, не нужно спорить про VARCHAR(255) против TEXT. Реализуя таблицы в PostgreSQL, поздно выяснять, нужна ли вообще сущность «склад». Три уровня разводят эти разговоры по времени и по аудитории.
Движение всегда сверху вниз: от абстрактного к конкретному, каждый шаг добавляет деталей. Но на практике бывают и возвраты вверх — об этом в следующем уроке про итеративность.
Conceptual model: что мы моделируем
Conceptual-модель (концептуальная) отвечает на вопрос «ЧТО». Это самый высокий уровень: только главные бизнес-сущности и связи между ними.
Что в ней есть:
- сущности — крупные понятия предметной области: Клиент, Заказ, Товар;
- связи между ними — «Клиент делает Заказ», «Заказ содержит Товары».
Чего в ней НЕТ:
- атрибутов (никаких «email», «дата рождения»);
- типов данных;
- ключей;
- любых технических деталей.
Conceptual-модель технологически нейтральна полностью — она одинакова, реализуете вы потом PostgreSQL, MongoDB или вообще ничего. Её аудитория — бизнес: менеджеры, аналитики предметной области, заказчик. С ними на этом уровне сверяют понимание: «правильно ли мы понимаем, что у одного заказа всегда один клиент?»
Пример conceptual-модели проката автомобилей словами: есть Клиент, Автомобиль, Аренда, Платёж. Клиент берёт Автомобиль в Аренду. За Аренду делается Платёж. Всё. Четыре сущности, три связи, ни одной колонки.
Признак хорошей conceptual-модели — её можно обсудить с человеком, который не знает SQL. Если в обсуждении всплывает слово «колонка» или «тип данных» — вы соскользнули на уровень ниже. На conceptual-уровне словарь — это «сущность», «связь», «бизнес-правило».
Logical model: строгая структура без СУБД
Logical-модель (логическая) отвечает на вопрос «КАК это структурировано». Здесь модель становится строгой, но всё ещё не привязана к конкретной СУБД.
Что добавляется по сравнению с conceptual:
- все атрибуты каждой сущности: у Клиента появляются имя, email, телефон;
- первичные ключи (primary keys) — чем уникально идентифицируется строка;
- внешние ключи (foreign keys) — как связи выражаются через ключи;
- нормализация — структура приводится к нормальной форме, устраняются аномалии;
- типы атрибутов в общем виде: «целое число», «строка», «дата» — но не диалект конкретной СУБД.
Logical-модель — это уже инженерный документ. Её аудитория — разработчики, архитекторы данных. На этом уровне принимаются ключевые структурные решения: какие таблицы, какие ключи, до какой нормальной формы доводить. Большая часть этого курса (ключи, связи, нормализация) — работа именно на логическом уровне.
Logical-модель проката, в отличие от conceptual, уже содержит: у сущности Аренда есть атрибуты rental_id (первичный ключ), customer_id (внешний ключ на Клиента), car_id (внешний ключ на Автомобиль), start_date, end_date, total_cost. Но какого типа start_date в конкретной базе — ещё не решено.
Physical model: реализация в конкретной СУБД
Physical-модель (физическая) отвечает на вопрос «КАК это реализовано в конкретной СУБД». Это самый детальный уровень, готовый к исполнению.
Что добавляется по сравнению с logical:
- конкретные типы данных выбранной СУБД: не «строка», а
VARCHAR(255); не «дата», аTIMESTAMP WITH TIME ZONE(в PostgreSQL) илиTEXT(в SQLite, где нет отдельного типа даты); - индексы — на какие колонки и какого вида, для скорости запросов;
- партиционирование — разбиение больших таблиц на части;
- физические ограничения:
NOT NULL,CHECK,UNIQUE,DEFAULT; - решения, специфичные для движка: tablespaces, типы хранения, настройки.
Physical-модель — это, по сути, DDL-скрипт. Её аудитория — разработчики и DBA, которые этот код исполняют. На этом уровне важно знать конкретную СУБД: одна и та же logical-модель даст разные physical-модели для PostgreSQL и для MySQL.
CREATE TABLE: типы, NOT NULL, DEFAULT, IDENTITY в PostgreSQLВот фрагмент physical-модели сущности Аренда для PostgreSQL:
CREATE TABLE rentals (
rental_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id BIGINT NOT NULL REFERENCES customers(customer_id),
car_id BIGINT NOT NULL REFERENCES cars(car_id),
start_date DATE NOT NULL,
end_date DATE,
total_cost NUMERIC(10,2) CHECK (total_cost >= 0)
);
CREATE INDEX idx_rentals_customer ON rentals (customer_id);
Здесь видно всё, чего не было на логическом уровне: BIGINT вместо абстрактного «целое», NUMERIC(10,2) для денег, GENERATED ALWAYS AS IDENTITY (способ PostgreSQL генерировать суррогатный ключ), CHECK на неотрицательную сумму, отдельный индекс на внешний ключ для ускорения соединений.
Сравнение трёх уровней
| Аспект | Conceptual | Logical | Physical |
|---|---|---|---|
| Отвечает на вопрос | ЧТО моделируем | КАК структурировано | КАК реализовано в СУБД |
| Сущности | да | да (как таблицы) | да (как таблицы) |
| Атрибуты | нет | да, все | да, с типами |
| Ключи (PK/FK) | нет | да | да |
| Типы данных | нет | общие | конкретной СУБД |
| Индексы, партиции | нет | нет | да |
| Привязка к СУБД | нет | нет | да |
| Аудитория | бизнес | разработчики, архитекторы | разработчики, DBA |
Главная мысль таблицы — каждый следующий уровень это надмножество предыдущего плюс новый слой деталей. Conceptual ничего не теряет при переходе в logical — он обрастает атрибутами и ключами. Logical не теряет ничего при переходе в physical — он обрастает типами и индексами.
Как уровни переходят друг в друга
Переход conceptual -> logical:
- каждая сущность становится таблицей;
- к каждой добавляются атрибуты;
- выбирается первичный ключ;
- связи выражаются через внешние ключи;
- структура нормализуется.
Переход logical -> physical:
- абстрактные типы заменяются на типы выбранной СУБД;
- проектируются индексы под ожидаемые запросы;
- добавляются физические ограничения и значения по умолчанию;
- при необходимости — партиционирование, специфичные настройки.
Частая ошибка — прыгать из conceptual сразу в physical, минуя logical: «понял сущности — пишу CREATE TABLE». Без логического уровня вы пропускаете нормализацию и проектирование ключей, и аномалии из прошлого урока приходят прямо в продакшен. Логический уровень — это место, где модель становится корректной. Не пропускайте его.
Почему это разделение полезно на практике
Кроме «разных разговоров для разных аудиторий», три уровня дают ещё одно: переносимость. Если решили сменить СУБД — с PostgreSQL на что-то другое — переписывается только physical-модель. Conceptual и logical остаются: сущности, связи, ключи, нормальная форма от движка не зависят. Вся интеллектуальная работа по моделированию сохранена, меняется лишь техническая «упаковка».
И наоборот: одна logical-модель может породить несколько physical-моделей — например, одну для OLTP-базы и другую, денормализованную, для аналитики. Логический уровень — это устойчивое ядро, физический — сменная оболочка под конкретную задачу и движок.
Conceptual / Logical / Physical в контексте Data GovernanceПопробуй сам
Возьмите простую предметную область — например, библиотека: читатели, книги, выдачи книг. Пройдите все три уровня на бумаге. Conceptual: выпишите 3-4 сущности и связи между ними, без единой колонки. Logical: добавьте каждой сущности атрибуты, отметьте первичный ключ и внешние ключи (например, у «выдачи» — ссылки на читателя и книгу). Physical: для одной из таблиц напишите настоящий CREATE TABLE для PostgreSQL или SQLite — с конкретными типами, NOT NULL и хотя бы одним CHECK. Сравните три получившихся документа и проговорите, что именно добавил каждый переход. Это упражнение — модель в миниатюре всего, чем вы будете заниматься в курсе.