Практическое занятие №1: ключи, объекты и проект БД, таблицы

1. От концепции к физической реализации

Физическое проектирование — это трансляция концептуальных сущностей и атрибутов в конкретные таблицы СУБД, определение типов хранения данных и правил целостности.

Концептуальный уровень (ER)

  • Сущность (Entity)
  • Атрибут (Attribute)
  • Связь (Relationship)
  • Бизнес-правило (Rule)

Физический уровень (SQL DDL)

  • Таблица (Table)
  • Колонка и тип данных (Column, DataType)
  • Первичные и внешние ключи (PK, FK)
  • Ограничения (NOT NULL, UNIQUE, CHECK)

2. Архитектура реляционной таблицы

Реляционная таблица — это физическое воплощение математического отношения:

Порядок следования строк и столбцов на физическом уровне не гарантирован и не должен влиять на логику приложений.

3. Первичный ключ (Primary Key)

Primary Key (PK) — столбец или набор столбцов, однозначно идентифицирующий каждую строку таблицы. Эквивалентен UNIQUE NOT NULL.

Три обязательных реляционных аксиомы первичного ключа:

  1. Уникальность: исключает существование двух строк с совпадающим ключом.
  2. Непустота (Non-nullability): первичный ключ никогда не может принимать значение NULL.
  3. Неизменяемость (Immutability): значение ключа объекта не должно изменяться на протяжении всей его жизни в БД.

По первичному ключу СУБД строит кластеризованный или уникальный B-Tree индекс.

4. Естественные vs Суррогатные ключи

Естественный ключ (Natural Key)

  • Взят из реального мира: VIN, ИНН, ISBN, серия-номер паспорта.
  • Плюс: информативен без JOIN.
  • Минус: строковые ключи медленно соединяются и раздувают размер B-Tree индексов.
  • Риск: законы и форматы документов меняются в реальном мире.

Суррогатный ключ (Surrogate Key)

  • Искусственное поле: INT, BIGINT, UUID.
  • Плюс: 4/8 байт, максимальная скорость JOIN, абсолютная неизменяемость.
  • Правило: при использовании суррогатного ID на естественный реквизит ОБЯЗАТЕЛЬНО накладывается UNIQUE NOT NULL!

5. Генерация суррогатных ключей

Современные реляционные СУБД (PostgreSQL, MySQL, Oracle, MSSQL) поддерживают три основных стандарта:

-- Стандарт SQL:2003 (PostgreSQL)
id_avto INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
vin VARCHAR(17) NOT NULL UNIQUE

6. Типы данных: Числа и Деньги

Критическое правило инженера: Никогда не используйте типы с плавающей запятой (FLOAT, REAL, DOUBLE) для финансовых расчетов и цен!

Двоичное представление чисел с плавающей точкой (IEEE 754) дает ошибку округления: 0.1 + 0.2 = 0.30000000000000004.

7. Строки, Даты и Булевы флаги

is_aktivnyy BOOLEAN NOT NULL DEFAULT TRUE,
data_vyezda TIMESTAMP NOT NULL,
vin CHAR(17) NOT NULL UNIQUE

8. Декларативная защита данных

Ограничения целостности выполняются на уровне ядра СУБД и не зависят от ошибок в коде веб-сервера или мобильного клиента:

Качественная схема БД защищает целостность даже при прямом ручном вмешательстве через SQL-консоль.

9. Ограничения CHECK (Бизнес-правила)

Ограничение CHECK проверяет истинность логического выражения при каждой вставке или обновлении строки:

-- 1. Валидация жизненного цикла (перечисление)
CHECK (status IN ('доступен', 'занят', 'уборка', 'ремонт'))

-- 2. Темпоральная целостность (дата выезда позже заезда)
CHECK (data_vyezda > data_zaezda)

-- 3. Защита от отрицательных остатков и цен
CHECK (probeg_pri_vozvrashchenii >= probeg_pri_vyezde)
CHECK (cena_prodazhi >= cena_zakupki AND cena_zakupki >= 0)

10. Внешний ключ (Foreign Key)

Foreign Key (FK) — колонка дочерней таблицы, значения которой обязаны присутствовать в первичном ключе родительской таблицы.

Внешний ключ физически связывает таблицы при реализации отношений 1:M и 1:1:

11. Каскадные политики: ON DELETE

RESTRICT / NO ACTION

Промышленный стандарт по умолчанию. Блокирует удаление родительской записи, если есть дочерние строки. Защищает финансовые архивы, договоры и путевые листы.

CASCADE

Автоматически стирает дочерние записи. Опасно! Допустимо строго для неделимых подчиненных спецификаций (строки заказа при удалении черновика).

ON DELETE SET NULL зануляет ссылку при удалении родителя (например, уволен мастер-приемщик, но заказ сохранился).

12. Анатомия DDL: Полный пример

CREATE TABLE putevye_listy (
    id_putevogo_lista BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    nomer_dokumenta   VARCHAR(30) NOT NULL UNIQUE,
    id_avto           INT NOT NULL REFERENCES avtomobili(id_avto)
                          ON UPDATE CASCADE ON DELETE RESTRICT,
    id_voditelya      INT NOT NULL REFERENCES voditeli(id_voditelya)
                          ON UPDATE CASCADE ON DELETE RESTRICT,
    probeg_pri_vyezde INT NOT NULL CHECK (probeg_pri_vyezde >= 0),
    probeg_pri_vozvrashchenii INT,
    CONSTRAINT chk_probeg CHECK (probeg_pri_vozvrashchenii >= probeg_pri_vyezde)
);

13. Топ-3 ошибок начинающих инженеров

  1. «Универсальный VARCHAR»: хранение чисел, дат и цен в строках переменной длины. Ломает сортировку, поиск диапазонов и индексы.
  2. «Слепой CASCADE»: установка каскадного удаления на справочники и клиентов, приводящая к уничтожению связанной истории.
  3. «Суррогатный ключ без UNIQUE»: создание id SERIAL без ограничения уникальности на паспорт или VIN, что допускает дублирование реальных объектов.
Культовый веб-комикс xkcd: Exploits of a Mom
Тематический интернет-мем: «Exploits of a Mom» (культовый веб-комикс про «Little Bobby Tables»).
Автор: Randall Munroe. Первоисточник: xkcd.com/327.
Лицензия: Creative Commons Attribution-NonCommercial 2.5 Generic (CC BY-NC 2.5).
Смысл мема: Когда проектировщик пренебрегает строгой валидацией типов данных, ограничениями целостности таблиц и параметризацией запросов, одна строковая запись в таблице учеников способна стереть всю базу данных школы (Robert'); DROP TABLE Students;--).
1 / 15