Логическая и физическая независимость данных
1. Доисторическая эпоха: файловый ад 1960-х
До изобретения СУБД приложения писались с жесткой привязкой к байтам на магнитном носителе:
- Программа знала точное смещение полей: «Байты 0..19 — ФИО, байты 20..27 — Оклад».
- Порядок сортировки определялся физическим порядком перфокарт или дорожек диска.
Главный кошмар: стоит изменить структуру записи (добавить код подразделения), как все программы компании перестают компилироваться и работать!
2. Спасение: Трехуровневая архитектура ANSI/SPARC
Три уровня абстракции
- Внешний уровень: формы ввода, API, специализированные витрины (Бухгалтерия, Касса).
- Концептуальный уровень: полная логическая модель данных (таблицы, связи, ограничения).
- Внутренний уровень: дисковые страницы, структуры B-Tree, сжатие, пути к файлам.
Две границы изоляции
1. Логическая независимость:
Внешний уровень ↔ Концептуальный уровень
2. Физическая независимость:
Концептуальный уровень ↔ Внутренний уровень
3. Что такое логическая независимость данных?
Логическая независимость (Logical Data Independence) — это способность изменять концептуальную схему БД (разбивать, объединять таблицы, добавлять атрибуты) без изменения внешних прикладных программ.
Бизнес меняется каждый день: появляются новые требования регуляторов, рефакторятся схемы. Приложения при этом не должны падать.
4. Защитный экран: Представления (VIEW)
Представление (VIEW) — виртуальная именованная выборка. Клиентский код считает ее обычной таблицей:
-- Разбиваем монолитную таблицу Клиенты на ЮрЛица и ФизЛица.
-- Создаем VIEW для старого софта:
CREATE OR REPLACE VIEW Clients AS
SELECT client_id, company_name AS name, inn, 'LEGAL' AS type FROM Legal_Entities
UNION ALL
SELECT client_id, full_name AS name, inn, 'INDIVIDUAL' AS type FROM Individuals;
Старая программа выполняет SELECT * FROM Clients и получает идентичный результат!
5. Как обновлять разделенные данные: Триггеры INSTEAD OF
Представления с UNION ALL по умолчанию не поддерживают прямую запись (INSERT). Решение — триггер перехвата:
CREATE OR REPLACE TRIGGER trg_clients_insert
INSTEAD OF INSERT ON Clients
FOR EACH ROW
BEGIN
IF :NEW.type = 'LEGAL' THEN
INSERT INTO Legal_Entities(company_name, inn) VALUES (:NEW.name, :NEW.inn);
ELSE
INSERT INTO Individuals(full_name, inn) VALUES (:NEW.name, :NEW.inn);
END IF;
END;
Устаревшее приложение по-прежнему думает, что делает INSERT INTO Clients, а СУБД прозрачно раскладывает строки по нужным таблицам.
6. Что такое физическая независимость данных?
Физическая независимость (Physical Data Independence) — это способность изменять физические структуры хранения (индексы, таблицы размещения, дисковые накопители, сжатие) без изменения концептуальной схемы и SQL-кода приложений.
Разработчику приложений не нужно знать, лежит ли таблица на SSD, HDD или в облачном хранилище, и какой индекс используется для ускорения выборки.
7. Индексы: ускорение поиска на физическом уровне
Действие администратора
-- Добавляем B-Tree индекс:
CREATE INDEX idx_orders_user
ON Orders USING btree(user_id);
Время поиска сокращается с 3500 мс до 2 мс.
Что видит приложение?
SELECT * FROM Orders
WHERE user_id = 1042;
Запрос не изменился ни на символ. Оптимизатор СУБД сам переключил Seq Scan на Index Scan.
8. Секционирование: миллиарды строк без боли
Когда таблица заказов вырастает до сотен миллионов строк, СУБД делит ее на секции (партиции) по годам:
orders_2024, orders_2025, orders_2026.
- Partition Pruning: при запросе за 2026 год СУБД читает с диска только одну секцию, игнорируя терабайты архива.
Приложение обращается к родительской таблице Orders. Физическое разбиение по файлам скрыто от прикладного разработчика!
9. Табличные пространства (Tablespaces) и Tiered Storage
Горячие данные (Hot Storage)
Свежие заказы за текущий месяц размещаются в tablespace fast_ssd (быстрый NVMe SSD RAID-10).
Холодный архив (Cold Storage)
Заказы пятилетней давности прозрачно переносятся в tablespace slow_hdd (дешевый емкий массив).
Клиентские отчеты выполняют одинаковые запросы. Перенос данных по физическим дисковым томам полностью изолирован от прикладных сервисов.
10. Сравнение видов независимости данных
Логическая независимость
- Изолирует внешние схемы от концептуальной.
- Решается через VIEW и триггеры.
- Защищает старый софт от декомпозиции таблиц.
- Труднее достижима: требует эквивалентности бизнес-логики.
Физическая независимость
- Изолирует концептуальную схему от дисков.
- Решается через индексы, партиции, tablespace.
- Защищает SQL-код от изменений «железа».
- Обеспечивается автоматически оптимизатором СУБД.
11. Инженерный разбор: Рефакторинг кассового узла
Задача: В таблицу Customers добавлено поле loyalty_tier (уровень кэшбэка). Старые кассовые терминалы при попытке выполнить SELECT * падают из-за неожиданной новой колонки в протоколе обмена.
Инженерное решение:
1. Создается представление v_cashier_customers, содержащее строго старый набор колонок.
2. Терминалы перенаправляются на это представление.
3. Логическая независимость восстановлена без перепрошивки сотен кассовых аппаратов!
12. Топ-3 ошибок студентов при анализе
- «Создание индекса — это изменение логической схемы»: НЕТ! Индекс не добавляет новых данных и не меняет состав полей таблицы. Это чистый физический уровень.
- «VIEW копирует данные и тратит диск»: НЕТ! Обычное VIEW — это сохраненный SQL-запрос (виртуальное окно), оно не дублирует строки на диске.
- «При партиционировании нужно писать новые имена таблиц»: НЕТ! Приложение всегда обращается к мастер-таблице, ядро СУБД диспетчеризирует чтение самостоятельно.
13. Главные выводы архитектора баз данных
- Независимость данных — фундаментальная причина победы реляционных СУБД над файловыми архивами.
- Никогда не давайте внешним приложениям прямой доступ к базовым таблицам критических систем — используйте слой представлений (VIEW).
- Настраивайте индексы и размещайте данные по дискам свободно: бизнес-логика ваших приложений при этом не пострадает.
Грамотная архитектура ANSI/SPARC экономит миллионы рублей на поддержке и рефакторинге корпоративного ПО!
Тематический интернет-мем: «Exploits of a Mom» (культовый веб-комикс про «Little Bobby Tables», xkcd #327).
Автор: Randall Munroe.
Первоисточник: https://xkcd.com/327/.
Лицензия: Creative Commons Attribution-NonCommercial 2.5 Generic (CC BY-NC 2.5).
Смысл мема в контексте занятия: Когда приложение напрямую лезет в базовые таблицы в обход изолированных слоев представлений, валидации и параметризованных интерфейсов, имя ребенка
Robert'); DROP TABLE Students;-- уничтожает всю физическую и логическую структуру данных школы за один учебный год!