Демобаза Авиаперевозки Postgres Pro: структура и развёртывание

Рейтинг: 72.2% · 10 голосов
Подробный курс по PostgreSQL: SQL по демобазе, типы данных и JSONB, индексы, транзакции и MVCC, VACUUM, EXPLAIN и планировщик, роли и привилегии, репликация, бэкап, настройка под нагрузку и под 1С. Актуально на 2026.
Ответить
Аватара пользователя
Egor_DBA
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Демобаза Авиаперевозки Postgres Pro: структура и развёртывание

Сообщение Egor_DBA »

Оглавление курса (47)
  1. Что такое PostgreSQL: история, философия, где применяется
  2. Урок 1. Что нового в PostgreSQL 15 и далее (15 -> 16 -> 17)
  3. Установка и первый запуск: Linux, Windows, Docker
  4. psql детально: метакоманды и работа в консоли
  5. Демобаза Авиаперевозки Postgres Pro: структура и развёртывание (вы здесь)
  6. SELECT: проекция, фильтрация, сортировка
  7. Транзакции и ACID
  8. Уровни изоляции транзакций: Read Committed, Repeatable Read, Serializable
  9. Соединения таблиц (JOIN)
  10. Агрегация: GROUP BY, HAVING, GROUPING SETS
  11. Подзапросы и CTE (WITH), рекурсия
  12. Оконные функции
  13. Изменение данных: INSERT/UPDATE/DELETE, UPSERT, MERGE
  14. Числовые и булевы типы, NULL и трёхзначная логика
  15. Строки, текст, дата и время, таймзоны
  16. Массивы, диапазоны, enum, составные типы
  17. JSON и JSONB: операторы и индексация
  18. DDL: CREATE TABLE, схемы, ALTER
  19. Ограничения целостности
  20. Представления и материализованные представления
  21. Последовательности, IDENTITY, генерируемые столбцы
  22. Индексы: B-tree и когда индекс не используется
  23. Типы индексов: Hash, GiST, SP-GiST, GIN, BRIN
  24. Продвинутые индексы: частичные, по выражению, покрывающие
  25. Обслуживание индексов и таблиц: bloat, REINDEX, CONCURRENTLY
  26. Полнотекстовый поиск
  27. Роли и пользователи
  28. Привилегии: GRANT/REVOKE
  29. Row-Level Security и безопасность данных
  30. Подключение приложения: pg_hba.conf, SSL, пулы соединений
  31. Серверное программирование: функции и процедуры
  32. Триггеры и события
  33. Архитектура PostgreSQL: процессы и память
  34. MVCC: версии строк и видимость
  35. VACUUM, autovacuum, freeze и wraparound
  36. WAL, контрольные точки и долговечность
  37. Блокировки и взаимоблокировки
  38. Планировщик запросов
  39. EXPLAIN и EXPLAIN ANALYZE: чтение планов
  40. Конфигурация сервера: ключевые параметры
  41. Настройка под нагрузку и под 1С
  42. Параллельные запросы и партиционирование
  43. Резервное копирование и восстановление
  44. Репликация: потоковая и hot standby
  45. Логическая репликация и кластерные решения
  46. Внешние данные, расширения и сертификация
  47. Разбор планов запросов на explain.tensor.ru: глубокое чтение EXPLAIN ANALYZE
Урок 4. Демобаза Авиаперевозки Postgres Pro: структура и развёртывание

Чтобы учить SQL не на выдуманных табличках employees из трёх строк, нам нужна осмысленная база с настоящими связями и объёмом. Дальше весь курс - SELECT, JOIN, агрегаты, оконные функции, indexes и explain analyze - мы будем отрабатывать на одной и той же демобазе Авиаперевозки от Postgres Professional. В этом уроке разберём, из каких таблиц она состоит, как они связаны между собой, как её скачать и развернуть командой psql -f, и почему именно такая модель данных удобна для обучения postgresql.

Изображение

Как это работает

Демобаза моделирует работу авиакомпании: пассажиры покупают билеты, билеты включают перелёты по конкретным рейсам, на рейсы назначаются самолёты с местами, а перед вылетом пассажир получает посадочный талон. Все таблицы лежат в отдельной схеме bookings, а не в public - это сделано специально, чтобы вы привыкали указывать схему и не путали учебные данные со своими.

Сердце модели - три уровня бронирования. Сначала идёт bookings: одно бронирование - это один поход в кассу или на сайт, у него есть номер book_ref из шести символов и общая сумма. Внутри бронирования может быть несколько билетов tickets - например, вы покупаете билеты сразу себе и ребёнку одним заказом. А каждый билет - это не один полёт, а связка перелётов ticket_flights: если летите с пересадкой Москва - Сочи через Ростов, то на один билет приходится два перелёта, у каждого своя цена и класс обслуживания.

Дальше идёт справочная часть, описывающая физический мир. flights - это расписание рейсов: номер рейса, плановые и фактические времена вылета и прилёта, аэропорты отправления и назначения, статус и какой самолёт назначен. airports хранит коды и города аэропортов, aircrafts - модели самолётов, а seats - схему салона, то есть какие места есть в конкретной модели и к какому классу они относятся.

Замыкает всё boarding_passes - посадочные талоны. Талон выдаётся не на билет вообще, а на конкретный перелёт, поэтому он ссылается сразу на пару ticket_no плюс flight_id и добавляет номер по порядку посадки и назначенное место. Так в модели честно отражается, что место в самолёте вам дают только при регистрации на конкретный рейс, а не при покупке.

Важная деталь актуальная на 2026: в текущих версиях демобазы airports и aircrafts - это не таблицы, а представления (view) над таблицами airports_data и aircrafts_data. Сделано это ради многоязычных названий: внутри они хранятся в типе jsonb, а представление вытаскивает строку на нужном языке. Поэтому когда вы делаете \d airports, не пугайтесь пометки view - данные настоящие, просто читаются через слой совместимости.

SQL и примеры

Сначала развернём базу. Скачиваете дамп с сайта Postgres Professional (есть варианты demo small, medium и big - отличаются глубиной истории полётов), затем подаёте файл в psql. Дамп сам создаёт базу demo, схему bookings и наполняет таблицы.

Код: Выделить всё

# в обычном терминале, не в psql
psql -f demo-small-20170815.sql postgres
Файл подключается к серверу под вашим пользователем и внутри себя выполняет CREATE DATABASE demo и переключение на неё. После загрузки заходим внутрь и осматриваемся.

Код: Выделить всё

psql -d demo

-- список таблиц учебной схемы
\dt bookings.*

-- структура таблицы рейсов: колонки, типы, ключи
\d bookings.flights
Чтобы не писать bookings. перед каждой таблицей, выставим схему в search_path на время сессии. Тогда flights будет искаться сначала в bookings.

Код: Выделить всё

SET search_path = bookings, public;
Проверим, что данные на месте, и заодно почувствуем размер базы. Запрос считает строки в ключевых таблицах:

Код: Выделить всё

SELECT
  (SELECT count(*) FROM bookings)       AS bookings,
  (SELECT count(*) FROM tickets)         AS tickets,
  (SELECT count(*) FROM ticket_flights)  AS ticket_flights,
  (SELECT count(*) FROM flights)         AS flights;
Теперь первый осмысленный JOIN через всю цепочку - от бронирования до конкретного перелёта. Он показывает, как четыре таблицы связаны ключами:

Код: Выделить всё

SELECT b.book_ref,
       t.passenger_name,
       f.flight_no,
       f.scheduled_departure,
       tf.fare_conditions,
       tf.amount
FROM bookings b
  JOIN tickets t        ON t.book_ref = b.book_ref
  JOIN ticket_flights tf ON tf.ticket_no = t.ticket_no
  JOIN flights f        ON f.flight_id = tf.flight_id
LIMIT 10;
Здесь видно правило связей: bookings и tickets соединяются по book_ref, tickets и ticket_flights - по ticket_no, а перелёт привязан к расписанию через flight_id. Ровно по этим ключам мы будем строить отчёты в следующих уроках.

Частые грабли
  • Забыли схему. После загрузки таблицы лежат в bookings, а вы по привычке пишете SELECT * FROM tickets из public и получаете relation does not exist. Решение - SET search_path или полное имя bookings.tickets.
  • Путают flight_no и flight_id. flight_no (например, PG0405) - это рейс из расписания, он повторяется каждый день. flight_id - уникальный конкретный вылет в конкретную дату. JOIN всегда делаем по flight_id.
  • Ждут, что airports - таблица, и пытаются туда вставить строку. Это представление над airports_data; прямой INSERT упадёт или потребует учитывать jsonb-структуру.
  • Запускают psql -f, уже находясь внутри psql. Команда psql -f - это команда операционной системы, её набирают в обычном терминале, а не в приглашении postgres=#.
  • Берут самый большой дамп demo-big на слабой машине и удивляются долгой загрузке. Для учёбы хватает demo-small.
  • Думают, что boarding_passes есть у всех билетов. Талоны существуют только для уже прошедшей регистрации, поэтому LEFT JOIN тут даёт NULL для будущих рейсов - это нормально.
Мини-лаба
  • Скачайте demo-small с сайта Postgres Professional и разверните: psql -f demo-small-*.sql postgres.
  • Подключитесь: psql -d demo, выполните \dt bookings.* и убедитесь, что видите все восемь таблиц.
  • Выставьте SET search_path = bookings, public и проверьте \d seats - найдите, какой составной первичный ключ у таблицы мест.
  • Посчитайте число рейсов по статусам: SELECT status, count(*) FROM flights GROUP BY status.
  • Найдите модели самолётов и их дальность: SELECT model, range FROM aircrafts ORDER BY range DESC.
  • Через цепочку JOIN выведите имена пассажиров и номера рейсов для одного выбранного book_ref.
  • Выполните \d+ bookings.flights и посмотрите, какие внешние ключи (Foreign-key constraints) ссылаются на airports и aircrafts.
Контрольные вопросы
  • Почему один билет (tickets) может быть связан с несколькими строками в ticket_flights?
  • По каким ключам соединяются bookings, tickets, ticket_flights и flights?
  • Чем flight_id отличается от flight_no и почему JOIN делают по flight_id?
  • Почему airports и aircrafts в современной демобазе являются представлениями, а не таблицами?
  • На что именно ссылается boarding_passes - на билет или на конкретный перелёт, и как это отражает реальную регистрацию?
  • Зачем учебные таблицы вынесены в схему bookings, а не в public?
👍4 ❤️2 🔥 😄 🤔1
Аватара пользователя
sleepyheap
Сообщения: 1
Зарегистрирован: 12 май 2026, 16:39

Re: Демобаза Авиаперевозки Postgres Pro: структура и развёртывание

Сообщение sleepyheap »

А обязательно small качать? У меня сервак мощный, хочу сразу demo-big чтобы explain analyze на больших объёмах гонять
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
ramez
Сообщения: 1
Зарегистрирован: 15 май 2026, 15:22

Re: Демобаза Авиаперевозки Postgres Pro: структура и развёртывание

Сообщение ramez »

Споткнулся ровно на граблях со схемой: писал SELECT * FROM flights и ловил relation does not exist, пока не сделал SET search_path = bookings. Спасибо что предупредили
👍1 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
psql детально: метакоманды и работа в консоли
Следующая глава →
SELECT: проекция, фильтрация, сортировка

Все главы курса «PostgreSQL: от первого запроса до продакшена»

Поделиться темой: ✈ Telegram VK
Похожие запросы: настройка postgresql под 1с и высокую нагрузку

Вернуться в «PostgreSQL: от первого запроса до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость