Логическая и физическая независимость данных

1. Доисторическая эпоха: файловый ад 1960-х

До изобретения СУБД приложения писались с жесткой привязкой к байтам на магнитном носителе:

Главный кошмар: стоит изменить структуру записи (добавить код подразделения), как все программы компании перестают компилироваться и работать!

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. Физическое разбиение по файлам скрыто от прикладного разработчика!

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 ошибок студентов при анализе

  1. «Создание индекса — это изменение логической схемы»: НЕТ! Индекс не добавляет новых данных и не меняет состав полей таблицы. Это чистый физический уровень.
  2. «VIEW копирует данные и тратит диск»: НЕТ! Обычное VIEW — это сохраненный SQL-запрос (виртуальное окно), оно не дублирует строки на диске.
  3. «При партиционировании нужно писать новые имена таблиц»: НЕТ! Приложение всегда обращается к мастер-таблице, ядро СУБД диспетчеризирует чтение самостоятельно.

13. Главные выводы архитектора баз данных

Грамотная архитектура ANSI/SPARC экономит миллионы рублей на поддержке и рефакторинге корпоративного ПО!
xkcd: Exploits of a Mom
Тематический интернет-мем: «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;-- уничтожает всю физическую и логическую структуру данных школы за один учебный год!
1 / 15