Дисциплина: «ОП.08 Основы проектирования баз данных» — Тема 3. Этапы проектирования баз данных — Практическое занятие №6: ключевые поля, индексы, связи (Занятие №18)
Занятие рассчитано на 2 академических часа. Ниже приведен детальный поминутный тайминг для основного регламента (80 минут) и сокращенного расписания (60 минут).
| Этап занятия | 80 минут (основной) | 60 минут (сокращенный) | Ключевой фокус этапа |
|---|---|---|---|
| 1. Организационный момент и постановка инженерной проблемы | 5 минут | 3 минуты | Кейс «Падение интернет-банкинга при формировании выписок за месяц» |
| 2. Актуализация опорных знаний и экспресс-разминка | 8 минут | 5 минут | Первичный ключ vs Внешний ключ, ссылочная целостность, поиск O(N) vs O(log N) |
| 3. Инструктаж и теоретический базис физического индексирования | 18 минут | 12 минут | Структура B-Tree, Composite Index, кластеризация, Partial Index, накладные расходы |
| 4. Разбор сквозного эталона и планов запросов EXPLAIN | 12 минут | 10 минут | Seq Scan vs Index Scan, чтение EXPLAIN ANALYZE, блокировки при FK без индексов |
| 5. Практическая работа студентов в zanyatie.html | 28 минут | 24 минуты | Индивидуальное решение 4 дифференцированных кейсов (Банкинг, Связь, Недвижимость, Доставка) |
| 6. Подведение итогов, рефлексия, закрытие критериев | 9 минут | 6 минут | Разбор типичных ошибок, мем Little Bobby Tables (xkcd #327), фиксация оценок |
В большинстве современных реляционных СУБД (PostgreSQL, MySQL/InnoDB, Oracle, MS SQL Server) стандартным типом индекса по умолчанию является B-Tree (сбалансированное дерево поиска). Преподавателю важно подчеркнуть его физические свойства:
BETWEEN, >=, <=) и сортировки (ORDER BY) без повторного обращения к корню.Индекс выполняет две фундаментальные роли: ускорение поиска и принудительное обеспечение бизнес-ограничений целостности данных.
CREATE UNIQUE INDEX: гарантирует, что ни одна комбинация значений столбцов не повторится. Используется для альтернативных ключей (номер паспорта, ИНН, трек-номер, email). При вставке СУБД выполняет предварительную проверку наличия ключа в дереве (Unique Check).CREATE INDEX (неуникальный): оптимизирует поиск по полям с множественными совпадениями (внешние ключи, даты, категории, статусы).Составной индекс строится по нескольким столбцам: CREATE INDEX idx_abc ON T (A, B, C);. Данные в B-Tree сортируются строго лексикографически: сначала по колонке A, внутри одинаковых A — по B, внутри одинаковых B — по C.
WHERE) присутствуют столбцы, начиная с самого левого (ведущего) столбца индекса без пропусков:
WHERE A = 1 AND B = 2 AND C = 3 — индекс используется полностью (все 3 поля).WHERE A = 1 AND B = 2 — индекс используется эффективно по префиксу (A, B).WHERE A = 1 — индекс используется эффективно по префиксу (A).WHERE B = 2 AND C = 3 — индекс НЕ может использоваться для прямого поиска по дереву (нет ведущего поля A), СУБД выберет Seq Scan или Index Full Scan.[Столбцы точного равенства (=)] → [Столбцы диапазонных условий (<, >, BETWEEN)] → [Столбцы сортировки (ORDER BY)].Преподавателю необходимо разъяснить различие в архитектурах хранения данных различных СУБД:
TID / ctid (номер страницы блока и смещение строки в блоке).SELECT), но замедляют любую запись (INSERT, UPDATE, DELETE):
Один из самых распространенных пробелов в подготовке выпускников СПО — убеждение, что СУБД автоматически создает индекс на внешний ключ. Это опасное заблуждение!
Transactions.id_счета) по умолчанию НЕ проиндексирован!JOIN дочерняя таблица сканируется последовательно (Seq Scan), что обрушивает производительность отчетов и выборок.DELETE или UPDATE в родительской таблице (например, удаление или блокировка счета) СУБД обязана проверить отсутствие ссылок в дочерней таблице. Без индекса на FK СУБД накладывает блокировку на всю дочернюю таблицу и запускает полный просмотр (Seq Scan) миллионов транзакций, парализуя работу всей информационной системы!Оптимизатор запросов СУБД выбирает план выполнения на основе внутренней статистики распределения данных:
-- Пример плана без индекса:
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42;
-> Seq Scan on orders (cost=0.00..45210.00 rows=15 width=72) (actual time=0.045..142.310 rows=15 loops=1)
Filter: (customer_id = 42)
Rows Removed by Filter: 1999985
-- Пример плана с B-Tree индексом:
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42;
-> Index Scan using idx_orders_customer on orders (cost=0.43..12.50 rows=15 width=72) (actual time=0.021..0.052 rows=15 loops=1)
Index Cond: (customer_id = 42)
cost=0.43..12.50: стартовая стоимость (поиск в B-Tree) и полная стоимость выборки. При Seq Scan стоимость исчисляется десятками тысяч.Rows Removed by Filter: 1999985 — очевидный признак катастрофически неэффективного запроса: система прочитала 2 миллиона строк с диска, чтобы вернуть всего 15.Bitmap Index Scan: промежуточный вариант, когда СУБД сначала формирует в оперативной памяти битовую карту страниц по индексу, а затем пакетом читает страницы с диска (используется при выборке сотен или тысяч подходящих строк).INSERT превращается в 11 физических записей на диск. Спросить: «Что произойдет с биллинговой системой сотовых звонков при 5000 звонков в секунду? Сервер захлебнется в операциях I/O».
(дата, id_клиента) под запрос WHERE id_клиента = 10 AND дата BETWEEN '...' AND '...'.CREATE INDEX idx_status ON Users (is_active); при 98% активных пользователей.WHERE is_active = false.
FOREIGN KEY, но забывает создать CREATE INDEX на эту колонку.Orders при попытке обновить строку в родительской таблице Customers.