This page is extracted from the official PDF into native Markdown. Slide text, code and speaker notes are kept in reading order; the original PDF and HTML remain the layout references.
HTML source: No matching course-page link was captured in the source inventory.
Archive:QPT-handouts-16-en-20251018.zipPDF pages: 28
Non-commercial use of course materials (presentations, demonstrations) is allowed without restrictions. Commercial use is possible only with the written permission of Postgres Professional. It is prohibited to make changes to the course materials.
In no event shall Postgres Professional company be liable for any damages or loss, including loss of profits, that arise from direct or indirect, special or incidental use of course materials. Postgres Professional company specifically disclaims any warranties on course materials. Course materials are provided “as is,” and Postgres Professional company has no obligations to provide maintenance, support, updates, enhancements, or modifications.
Page 2: Topics
Goals and Objectives
Subject Area and General Schema of the Demonstration Database
The demonstration database was created for the following purposes:
● Self-directed study of the SQL query language
● Development of textbooks, guides, and training courses on SQL;
● Showcasing PostgreSQL features in articles and notes
When developing the demonstration database, we set out to achieve several objectives:
● The data schema should be simple enough to be understood without additional explanations.
● At the same time, the data schema should be sufficiently complex to enable the creation of meaningful queries;
● The database should be populated with realistic data that are engaging to work with.
The demonstration database is licensed under the PostgreSQL license.
The database is available in three versions with different sizes. For example, the large-volume database used in the query optimization course contains a year’s worth of flight data.
This topic covers the demo database version from 15.08.2017.
A booking can include multiple passengers, each receiving their own ticket (tickets).
A ticket may include one or more flights (ticket_flights). A ticket can include multiple flights when there’s no direct flight between the departure and destination (a connecting flight) or when it’s a round-trip ticket.
Each flight (flights) departs from one airport (airports) to another. Flights with the same number have identical departure and arrival locations but different departure dates.
When checking in for a flight, the passenger receives a boarding pass (boarding_passes) that specifies the seat on the plane. A passenger can only check in for the flight listed in their ticket Each flight and seat combination is unique.
The number of seats and their allocation across service classes in an aircraft depend on the specific aircraft model used for the flight. Each aircraft model is assumed to have only one cabin layout.
The schema highlights only the columns that correspond to primary and foreign keys. Next, we’ll take a closer look at the main objects in the demonstration database.
Page 5: Bookings
Bookings
A passenger books a ticket a month in advance for themselves and possibly
other passengers.
Booking number (alphanumeric combination)
Booking date
Total amount of tickets included in the booking
Speaker notes
The passenger books a ticket for themselves and possibly others in advance, with the booking date (book_date) up to a month before the flight. Bookings are identified by a unique identifier (book_ref, a six-character alphanumeric code).
The total_amount field stores the total cost of all passengers’ flights included in the booking.
Column | Type | Modifiers | Description
--------------+---------------+--------------+---------------------------
book_ref | char(6) | not null | Booking Number
book_date | timestamptz | not null | Booking date
total_amount | numeric(10,2) | not null | Total booking amount
Indexes:
PRIMARY KEY, btree (book_ref)
External References:
TABLE "tickets" FOREIGN KEY (book_ref) REFERENCES bookings(book_ref)
?column?
------------------
20 days 18:24:00
(1 row)
Page 7: Tickets
Tickets
A ticket is issued to a single passenger and may cover multiple flights.
Neither the passenger ID nor the name is permanent; it is not possible to
uniquely identify all tickets for the same passenger.
Ticket No.
Booking reference
Passenger ID (Document Number)
passenger_name | 16
Passenger Contact Details
Speaker notes
The ticket contains a unique 13-digit number (ticket_no).
The ticket contains a passenger ID (passenger_id) — the passenger’s identity document number — along with their surname and name (passenger_name) and contact information (contact_data).
Neither the passenger ID nor the name is permanent (e.g., a passport can be replaced or a surname changed), making it impossible to uniquely identify all tickets for the same passenger.
Column | Type | Modifiers | Description
----------------+-------------+--------------+-----------------------------
ticket_no | char(13) | not null | Ticket Number
book_ref | char(6) | not null | Booking Number
passenger_id | varchar(20) | not null | Passenger ID
passenger_name | text | not null | Passenger's Name
contact_data | jsonb | | Passenger's Contact Information
Indexes:
PRIMARY KEY, btree (ticket_no)
Foreign Key Constraints:
FOREIGN KEY (book_ref) REFERENCES bookings(book_ref)
External References:
TABLE "ticket_flights" FOREIGN KEY (ticket_no) REFERENCES tickets(ticket_no)
Page 8: Tickets Ticket Details
Let’s check which tickets are included in the selected reservation.
Here, we’re only looking at one ticket – all routes in a booking always match.
It appears that the ticket includes 6 flights, one in business class and the rest in economy class.
Page 11: Flights
Flights
The flight operates on schedule between airports.
Natural key: flight number and departure date, but a surrogate key is used.
Flight ID
flight number
scheduled departure and arrival
actual departure and arrival
Departure and arrival airports
Flight status
filter: (aircraft_code = f.aircraft_code)
Speaker notes
A flight connects the departure and arrival airports. If there’s no direct flight, the ticket includes multiple flights.
Column | Type | Modifiers | Description
---------------------+-------------+--------------+----------------------------
flight_id | integer | not null | Flight ID
flight_no | char(6) | not null | Flight Number
scheduled_departure | timestamptz | not null | Scheduled departure time
scheduled_arrival | timestamptz | not null | Scheduled Arrival Time
departure_airport | char(3) | not null | Departure Airport
Arrival Airport
status | varchar(20) | not null | Flight Status
aircraft_code | char(3) | not null | Aircraft code (IATA)
Actual Departure Time
actual_arrival | timestamptz | | Actual Arrival Time
Indexes:
PRIMARY KEY, btree (flight_id)
UNIQUE CONSTRAINT, btree (flight_no, scheduled_departure)
Check Constraints:
CHECK (scheduled_arrival > scheduled_departure)
CHECK ((actual_arrival IS NULL)
OR ((actual_departure IS NOT NULL AND actual_arrival IS NOT NULL)
AND (actual_arrival > actual_departure)))
CHECK (status IN ('On Time', 'Delayed', 'Departed',
'Arrived', 'Scheduled', 'Cancelled'))
Foreign Key Constraints:
FOREIGN KEY (aircraft_code) REFERENCES aircrafts_data(aircraft_code)
FOREIGN KEY (arrival_airport) REFERENCES airports_data(airport_code)
FOREIGN KEY (departure_airport) REFERENCES airports_data(airport_code)
Page 12: Flights Flight Details
Now let’s look into which flights are associated with the selected ones.
There are three outbound and three return flights. All outbound flights have already arrived (Arrived), while the passenger is currently on the return flight (Departed). The next flight is on time (On Time), and check-in hasn’t opened yet for the final flight (Scheduled).
Let’s take a closer look at all the columns of one of the flights.
Implementation: Multilingual view on airports_data
airport code
airport name
city
Airport coordinates (longitude and latitude)
timezone
Speaker notes
The airport is identified by a three-letter code (airport_code) and is known as (airport_name).
Cities are not represented as a separate entity, but a “city” field has been introduced to help locate airports within the same city. This view also includes the airport’s coordinates (coordinates) and time zone (timezone).
The airport_name and city field values depend on the language set in the configuration parameter bookings.lang.
We can see the local time in the departure and arrival cities’ time zones, flight duration, and airport names here.
Since the routes in the demo database remain unchanged over time, we can isolate data that’s independent of a specific departure date from the flights table. This data is organized in the routes view:
=>SELECT*FROMroutesrWHEREr.flight_no='PG0412'\gx
Page 15: Page 15
-[ RECORD 1 ]----------+----------------
flight_no | PG0412
departure_airport | VKO
departure_airport_name | Внуково
departure_city | Москва
arrival_airport | PEE
arrival_airport_name | Пермь
arrival_city | Пермь
aircraft_code | 773
duration | 01:25:00
days_of_week | {1,2,3,4,5,6,7}
It’s clear that flights run daily (array days_of_week).
Page 16: Aircrafts
Aircrafts
aircraft models operating flights
Implementation: a multilingual view of aircrafts_data
filter: (aircraft_code = f.aircraft_code)
aircraft model
Maximum flight range (km)
Speaker notes
Each aircraft model is uniquely identified by its three-digit code (aircraft_code). Additionally, the model (model) and maximum flight range in kilometers (range) are specified.
The model field’s value is determined by the selected language specified in the configuration parameter bookings.lang.
aircraft_code | model | range
---------------+---------------+-------
773 | Боинг 777-300 | 11100
(1 row)
Page 18: Seats
Seats
Seats determine the cabin layout
All aircraft of the same model share the same cabin layout
filter: (aircraft_code = f.aircraft_code)
seat number
class of service
Speaker notes
Seats determine the cabin layout for each model. Each seat is identified by its seat number (seat_no) and is assigned a class of service (fare_conditions) – Economy, Comfort, or Business.
The boarding pass is issued when checking in for the flight.
Ticket No.
Flight ID
boarding pass number (in the order of registration)
seat number
Speaker notes
Passengers can register for a flight up to a day in advance of the scheduled departure date, and they are then issued a boarding pass.
Boarding passes are assigned sequential numbers (boarding_no) according to the order in which passengers register for the flight. This number is unique only within the flight. The boarding pass includes the seat number (seat_no).
Column | Type | Modifiers | Description
-------------+------------+--------------+--------------------------
ticket_no | char(13) | not null | Ticket Number
flight_id | integer | not null | Flight ID
boarding_no | integer | not null | Boarding Pass Number
seat_no | varchar(4) | not null | Seat Number
Indexes:
PRIMARY KEY, btree (ticket_no, flight_id)
UNIQUE CONSTRAINT, btree (flight_id, boarding_no)
UNIQUE CONSTRAINT, btree (flight_id, seat_no)
Foreign Key Constraints:
FOREIGN KEY (ticket_no, flight_id)
REFERENCES ticket_flights(ticket_no, flight_id)
Page 21: Boarding Tickets Boarding Passes
Where was our passenger seated? To find out, you need to check the boarding pass issued during check-in for the flight:
The passenger hasn’t checked in for the two remaining flights yet.
Page 22: Multilingual Support
Configuration parameter
bookings.lang
Tables to store multilingual names
airports_data
aircrafts_data
Speaker notes
The language for displaying city, airport, and aircraft model names is set via the configuration parameter bookings.lang. The demo base contains names in Russian (ru) and English (en).
You can independently expand the language support by addingnames in any language to the rows of the airports_data and aircrafts_data tables.
Page 23: Multilingual Support
The demo database has the capability to translate the names of airports, cities, and aircraft into other languages. As we saw, by default, all names are displayed in Russian:
-[ RECORD 1 ]+---------------------------------------------------------
airport_code | VKO
airport_name | {"en": "Vnukovo International Airport", "ru": "Внуково"}
city | {"en": "Moscow", "ru": "Москва"}
coordinates | (37.2615013123,55.5914993286)
timezone | Europe/Moscow
Page 24: Takeaways
The demo database’s schema is simple yet enables the creation of complex and intriguing queries.
The data in the demo database is similar to real data.
The demo database can be used for learning SQL, showcasing PostgreSQL features, and other purposes.
Page 25: Practice
Write a few queries against the demo database. 1. How many people are included in a single booking? 2. Which cities cannot be reached from Moscow without transfers? 3. Which airplane model operates the most flights, and which operates the fewest? 4. And which aircraft model carried the most passengers?
The result will be two columns:
Number of people per booking
Booking count
Page 26: How many people are in each booking?
We’ll count the number of people in each booking and then determine how many bookings there are for each number of people.
city
--------------------------
Оренбург
Липецк
Южно-Сахалинск
Красноярск
Уфа
Калуга
Новый Уренгой
Нарьян-Мар
Белгород
Нерюнгри
Ульяновск
Салехард
Грозный
Орск
Нижневартовск
Астрахань
Минеральные Воды
Краснодар
Саранск
Когалым
Кемерово
Братск
Якутск
Казань
Новокузнецк
Белоярский
Нижний Новгород
Екатеринбург
Пенза
Омск
Пермь
Чебоксары
Сургут
Надым
Тюмень
Сыктывкар
Нальчик
Page 27: Page 27
Иркутск
Волгоград
Томск
Советский
Норильск
Анапа
Ростов-на-Дону
Курск
Владикавказ
Удачный
Ставрополь
Йошкар-Ола
Петропавловск-Камчатский
Новосибирск
Кызыл
Улан-Удэ
Воронеж
Киров
Мирный
Стрежевой
Ярославль
Саратов
Горно-Алтайск
Геленджик
Петрозаводск
Иваново
Усть-Кут
Магадан
Абакан
Хабаровск
Самара
Калининград
Воркута
Махачкала
Тамбов
Чита
Анадырь
Усинск
Мурманск
Брянск
Череповец
Урай
Комсомольск-на-Амуре
Челябинск
Бугульма
Сочи
Усть-Илимск
Москва
Благовещенск
Санкт-Петербург
Ухта
Элиста
Барнаул
Нефтеюганск
Ханты-Мансийск
Псков
Магнитогорск
Нижнекамск
Нягань
Курган
Ноябрьск
Ижевск
Архангельск
Владивосток
(101 rows)
It’s interesting that you can’t get from Moscow to Moscow without transfers.
Which models have the highest and lowest number of flights?