Demo database "Air Transport"
16
Copyright
© Postgres Professional, 2019–2024
Authors Authors: Egor Rogov, Pavel Luzanov, Ilya Bashtanov
Photo by: Oleg Bartunov (Phu monastery, Bhrikuti summit, Nepal)
Use of course materials
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.
Feedback
Please send your feedback, comments and suggestions to:
edu@postgrespro.com
Disclaimer
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.
2
Topics
Goals and Objectives
Subject Area and General Schema of the Demonstration
Database
Detailed Object Descriptions
3
Aviation
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.
4
Overview
Bookings
Bookings
# book_ref
Tickets
Tickets
# ticket_no
* book_ref
Aircrafts
Aircrafts
# aircraft_code
Seats
Seats
# aircraft_code
# seat_no
Ticket_flights
Flights
# ticket_no
# flight_id
Boarding_passes
Boarding Passes
# ticket_no
# flight_id
Flights
Flights
# flight_id
* departure_airport
* arrival_airport
* aircraft_code
Airports
Airports
# airport_code
The primary entity is booking (bookings).
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.
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
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)
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
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)
9
Flights
Ticket_flights
Flight connects tickets to flights
Ticket No.
Flight ID
class of service
Flight Cost
A flight links a ticket to a flight, identified by the ticket and flight numbers.
For each flight, the cost (amount) and service class (fare_conditions) are
specified.
Column | Type | Modifiers | Description
-----------------+---------------+--------------+---------------------
ticket_no | char(13) | not null | Ticket Number
flight_id | integer | not null | Flight ID
fare_conditions | varchar(10) | not null | Class of service
amount | numeric(10,2) | not null | Flight Cost
Indexes:
PRIMARY KEY, btree (ticket_no, flight_id)
Check Constraints:
CHECK (amount >= 0)
CHECK (fare_conditions IN ('Economy', 'Comfort', 'Business'))
Foreign Key Constraints:
FOREIGN KEY (flight_id) REFERENCES flights(flight_id)
FOREIGN KEY (ticket_no) REFERENCES tickets(ticket_no)
External References:
TABLE "boarding_passes" FOREIGN KEY (ticket_no, flight_id)
REFERENCES ticket_flights(ticket_no, flight_id)
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)
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)
13
Airports
Airports
The city is not stored in a separate table
Implementation: Multilingual view on airports_data
airport code
airport name
city
Airport coordinates (longitude and latitude)
timezone
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.
Column | Type | Modifiers | Description
--------------+---------+--------------+---------------------------------------
airport_code | char(3) | not null | Airport code
airport_name | text | not null | Description: Airport Name
city | text | not null | City
Description: Airport coordinates
timezone | text | not null | Airport Time Zone
View Definition:
SELECT ml.airport_code,
ml.airport_name ->> lang() AS airport_name,
ml.city ->> lang() AS city,
ml.coordinates,
ml.timezone
FROM airports_data ml;
15
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)
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.
Column | Type | Modifiers | Description
---------------+---------+--------------+-----------------------------------
aircraft_code | char(3) | not null | Aircraft code (IATA)
model | text | not null | Aircraft Model
range | integer | not null | Maximum flight range (km)
View Definition:
SELECT ml.aircraft_code,
ml.model ->> lang() AS model,
ml.range
FROM aircrafts_data ml;
17
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
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.
Column | Type | Modifiers | Description
-----------------+-------------+--------------+--------------------
aircraft_code | char(3) | not null | Aircraft code (IATA)
seat_no | varchar(4) | not null | Seat Number
fare_conditions | varchar(10) | not null | Class of service
Indexes:
PRIMARY KEY, btree (aircraft_code, seat_no)
Check Constraints:
CHECK (fare_conditions IN ('Economy', 'Comfort', 'Business'))
Foreign Key Constraints:
FOREIGN KEY (aircraft_code)
REFERENCES aircrafts(aircraft_code) ON DELETE CASCADE
19
Boarding Passes
Boarding_passes
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
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)
21
Multilingual Support
Configuration parameter
bookings.lang
Tables to store multilingual names
airports_data
aircrafts_data
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.
23
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.
24
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?
1. The result will be two columns:
Number of people per booking
Booking count