Архитектура СУБД и независимость данных
Почему можно перестроить индексы на диске, и ни одна программа этого не заметит. Разбираем трёхуровневую архитектуру СУБД.
Независимость данных — способность менять схему на одном уровне архитектуры, не затрагивая уровень выше. Это главная инженерная ценность, ради которой придумана многоуровневая архитектура СУБД.
Зачем разделять уровни
В файловом подходе программа знала всё: и какие поля есть, и как они лежат на диске. Любое изменение хранения ломало код. Чтобы развязать этот узел, в 1975 году комитет ANSI/SPARC предложил разделить описание базы на три уровня абстракции. Идея в том, чтобы между «как пользователь видит данные», «что есть в базе на самом деле» и «как это физически хранится» стояли чёткие границы. Тогда изменения на нижних уровнях не будут просачиваться наверх.
Эта архитектура — прямой ответ на боль из первого урока. Вспомните проблему зависимости данных: программы знали физическую раскладку файлов, и любое изменение хранения требовало переписывать код. Трёхуровневая модель устраняет эту зависимость по построению, разводя «логику» и «физику» по разным уровням с чёткой границей между ними. Можно сказать, что вся история СУБД — это история повышения уровня абстракции: от байтов на диске к таблицам, а от таблиц — к представлениям, удобным конкретному приложению.
Три уровня архитектуры ANSI/SPARC
Внутренний (физический) уровень
Описывает, как данные реально хранятся: файлы, страницы, индексы, способы сжатия, расположение на диске. Это территория СУБД и администратора. Здесь решается, держать ли таблицу как кучу (heap), какой индекс построить, как разбить данные по разделам. Обычный разработчик сюда почти не заглядывает.
Концептуальный (логический) уровень
Это полная логическая схема всей базы: какие есть таблицы, какие у них столбцы и типы, какие связи и ограничения целостности. Один на всю базу, не зависит от физики хранения. Именно его проектирует архитектор данных. Для нашего магазина — это таблицы clients, orders, products со всеми их полями, ключами и связями.
Внешний уровень (представления)
Это то, как видят данные конкретные пользователи и приложения. Внешних схем много — по одной на роль или приложение. Бухгалтер видит «представление» (view) с суммами, но без паролей; служба доставки — заказы с адресами, но без сумм. Каждое представление — это отфильтрованный и преобразованный взгляд на концептуальную схему.
Важно, что представление может не только скрывать часть данных, но и преобразовывать их: соединять несколько таблиц в одну удобную «виртуальную», переименовывать столбцы, вычислять производные значения. Для приложения такое представление выглядит как обычная таблица, хотя физически за ним стоит запрос к нескольким реальным таблицам. Это даёт мощный приём проектирования: предоставлять каждому потребителю ровно ту «форму» данных, которая ему удобна, не дублируя сами данные.
| Уровень | Что описывает | Кто работает |
| Внешний | Представления для приложений и ролей | Пользователи, приложения |
| Концептуальный | Полная логическая схема (таблицы, связи, ограничения) | Архитектор данных |
| Внутренний | Физическое хранение: файлы, страницы, индексы | СУБД, администратор |
Аналогия: ресторан
Чтобы три уровня улеглись интуитивно, представьте ресторан. Меню, которое видит гость, — это внешний уровень: красиво оформленный, понятный, скрывающий детали. У разных гостей могут быть разные меню (детское, винная карта) — как разные представления. Рецептура и список блюд на кухне — это концептуальный уровень: полное логическое описание того, что ресторан умеет готовить, без привязки к тому, на какой плите. А как именно устроена кухня — где стоят холодильники, какие плиты, как разложены продукты — это внутренний уровень. Можно поменять плиту (внутренний уровень), и ни меню, ни рецептура не изменятся: гость ничего не заметит. Это и есть физическая независимость. Можно добавить блюдо в рецептуру (концептуальный уровень), и старые меню, где его нет, останутся валидными — логическая независимость.
Два вида независимости данных
Границы между уровнями дают два уровня независимости.
Физическая независимость данных
Можно менять внутренний уровень, не трогая концептуальный. Администратор построил новый индекс, переразбил таблицу по разделам, перенёс её на другой диск — концептуальная схема не изменилась, запросы приложений работают как прежде, только, возможно, быстрее. Это и есть исполнение мечты, ради которой ушли от файлов: физика хранения больше не диктует структуру кода.
Логическая независимость данных
Можно менять концептуальный уровень, не ломая внешний. Добавили в таблицу clients новый столбец loyalty_points — старые представления, которые его не используют, продолжают работать без изменений. Логическая независимость достигается труднее физической: если меняется именно то, что видит представление, обойтись без правок невозможно.
Живой пример: представление как внешний уровень
Представление (VIEW) — практическое воплощение внешнего уровня. Оно прячет часть концептуальной схемы. Запустите и посмотрите, как одно и то же отношение можно показать разным ролям по-разному.
CREATE TABLE clients (
id INTEGER PRIMARY KEY, name TEXT, phone TEXT, balance INTEGER
);
INSERT INTO clients VALUES
(1, 'Анна', '+7-900-111', 5000),
(2, 'Борис', '+7-900-222', 1200);
-- внешний уровень для службы поддержки: без баланса
CREATE VIEW support_view AS
SELECT id, name, phone FROM clients;
SELECT * FROM support_view;
Служба поддержки работает с support_view и не видит баланс. Если завтра в таблицу clients добавят столбец, это представление не сломается — вот логическая независимость в действии.
Представления решают и задачу безопасности (внешний уровень = «что разрешено видеть этой роли»), и задачу стабильности интерфейса. Приложение может зависеть не от таблицы напрямую, а от представления — тогда вы вольны перестраивать таблицы под капотом, лишь бы представление выдавало те же столбцы. Это практический способ добиться логической независимости там, где она иначе недостижима: представление становится «контрактом» между базой и приложением.
Почему логическая независимость даётся труднее
Стоит честно сказать, почему физическая независимость достигается почти всегда, а логическая — лишь отчасти. Физика хранения по определению невидима логике: какой бы индекс мы ни построили, множество кортежей отношения от этого не меняется, а запросы оперируют именно кортежами. Поэтому СУБД почти всегда может спрятать изменения хранения. С логической схемой иначе: если меняется ровно то, что приложение использует (удалили столбец, который оно читает; разбили таблицу, из которой оно выбирает), скрыть это невозможно — представление-«прослойка» тоже придётся менять. Логическая независимость защищает от добавлений и многих преобразований, но не от удаления того, на что опираются. Понимание этой границы помогает проектировать схемы, которые не больно эволюционировать.
Зачем нужны отображения между уровнями
Уровни не висят в воздухе — между ними есть отображения (mappings), которые СУБД хранит и поддерживает. Отображение «внешний ↔ концептуальный» описывает, как из логической схемы получается каждое представление; отображение «концептуальный ↔ внутренний» — как логические таблицы превращаются в физические файлы и индексы. Именно эти отображения и есть «клей», обеспечивающий независимость данных. Когда администратор меняет физику, СУБД достаточно обновить нижнее отображение — концептуальная схема и все представления остаются нетронутыми. Когда меняется логическая схема, обновляется верхнее отображение, а не использующие его представления.
Эта идея — почему многоуровневость вообще ценна. Без чётких границ и отображений любое изменение на одном уровне волной расходилось бы вверх, ровно как в файловом подходе, от которого мы ушли. Граница плюс отображение = локализованное изменение.
Схема и состояние базы данных
Полезно различать два понятия. Схема — это описание структуры (определения таблиц, типов, ограничений); она меняется редко. Состояние (или экземпляр) — это конкретные данные в базе в данный момент; оно меняется при каждом INSERT или UPDATE. Схема — как чертёж, состояние — как конкретное здание, построенное по нему сегодня. Концептуальный уровень — это схема; строки в таблицах — это состояние.
Различение схемы и состояния пронизывает весь курс. Например, функциональная зависимость (раздел про нормализацию) — это утверждение о схеме (правило для всех состояний), а не о текущих данных. А целостность — это требование, чтобы каждое состояние удовлетворяло ограничениям схемы. Держа эти два уровня раздельно, вы избегаете типичной путаницы «в данных сейчас так, значит, это правило».
Типичные заблуждения
- «Представление хранит свою копию данных». Обычное представление данных не хранит — это сохранённый запрос поверх таблиц; данные берутся из концептуального уровня в момент обращения.
- «Физическая и логическая независимость — это одно и то же». Физическая защищает от изменений хранения, логическая — от изменений логической схемы; вторая достигается сложнее.
- «Схема и данные — это одно». Схема описывает форму, данные её наполняют; они меняются с совершенно разной частотой.
Итог
- Архитектура ANSI/SPARC делит описание базы на три уровня: внешний (представления), концептуальный (логическая схема), внутренний (физика).
- Физическая независимость позволяет менять хранение, не трогая логическую схему.
- Логическая независимость позволяет менять логическую схему, не ломая представления приложений.
- Представления (VIEW) — практическое воплощение внешнего уровня; схема и состояние базы — разные понятия.