- Notifications
You must be signed in to change notification settings - Fork0
postgrespro/demodb
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Программа-генератор создает базы данных с той же структурой, что идемобаза, но иным наполнением. Она имеет ряд настроек, позволяющих изменить характеристики данных, есть возможность поменять маршрутную сеть и флот авиакомпании и т. п.
Программу также можно использовать как генератор нагрузки, например для демонстрации систем мониторинга или тренировки оптимизации запросов.
Подключитесь в psql к любой базе, кромеdemo
, убедитесь, что находитесь в каталоге репозитория, и выполните установку:
\! pwd\i install
При необходимости смените текущий каталог командой\cd
.
В ходе установки будет заново создана база данныхdemo
. Если она существовала, то все данные в ней будут потеряны! В этой базе данных будут созданы две схемы:gen
для объектов генератора иbookings
для создаваемой демобазы.
Устанавливаются расширенияbtree_gist
(для реализации темпорального ключа),earthdistance
иcube
(для расчета расстояний на сфере), а такжеdblink
(для запуска параллельных процессов). Эти расширения входят в стандартный набор, но убедитесь, что они присутствуют в вашей установке PostgreSQL.
Генерация запускается процедуройgenerate
, которой передаются начальное и конечноемодельное время (которое будет фигурировать в таблицах демобазы). Например:
CALL generate( now(), now()+ interval'1 year' );
Такая команда выполнит необходимую инициализацию, создаст очередь событий и начнет генерацию демобазы за один год.
Чтобы ускорить работу, можно запустить генерацию в нескольких параллельных процессах:
CALL generate( now(), now()+ interval'1 year',4 );
Работа в любом случае выполняется в параллельных процессах (даже если такой процесс один), поэтому командаCALL
немедленно возвращает управление.
Быстро проверить состояние генерации можно запросом:
SELECT busy();
Истинное значение будет означать, что генерация еще в процессе.
Более полное представление о процессе можно получить, наблюдая за журналом сообщений генератора:
SELECT*FROMgen.logORDER BY atDESCLIMIT30 \watch60
Разрыв соединения не завершает работу генератора. Прервать генерацию досрочно можно командой:
CALL abort();
После успешного окончания генерации полезно ознакомиться с получившимися характеристиками:
\icheck.sql
Если все в порядке, полученную демобазу можно выгрузить в виде SQL-скрипта. Для этого в операционной системе выполните команду, находясь в каталоге репозитория:
./export.sh>`date +%Y%m%d`.sql
Генерацию можно продолжить с того момента, на котором она остановилась. Например, сгенерировать данные еще за три месяца:
CALL continue( now()+ interval'1 year 3 month',4 );
Генерация настраивается рядом конфигурационных параметров. Доступ к значениям параметров должны иметь параллельные процессы, поэтому установка на уровне сеанса (SET
) не сработает. Удобнее всего устанавливать параметры на уровне базы данных:
ALTERDATABASE demoSET gen.имя-параметра= значение;
(Внутренние настройки не вынесены на уровень пользователя, но присутствуют в исходном коде в виде immutable-функций; неудачные значения могут привести к ошибкам генерации или к неожиданным результатам. Часть настроек и вовсе никуда не вынесена и присутствует в коде только в виде констант.)
Строка подключения к базе данныхdemo
.
Значение по умолчаниюdbname=demo
, что соответствует подключению к локальному серверу. При необходимости укажите любые параметры, допускаемые libpq.
Название авиакомпании. Появляется только в значении, возвращаемом функциейbookings.version
.
Значение по умолчаниюPostgresPro
.
Код авиакомпании. Используется как префикс номеров билетовbookings.tickets.ticket_no
.
Значение по умолчаниюPG
.
Коэффициент для пересчета относительного пассажиропотокаgen.airports_data.traffic
в количество бронирований из данного аэропорта в неделю.
Доля рейсов, которая должна приходиться на внутренние перелеты в пределах одной страны. Это целевое значение; оно играет роль при формировании графа перелетов, но граф в любом случае будет связным.
Значение по умолчанию0.9
.
Доля бронирований, при которых билеты покупаются «туда и обратно». Это целевое значение; в реальности доля будет меньше из-за того, что обратные билеты не всегда доступны.
Значение по умолчанию0.9
.
Доля задержанных рейсов.
Значение по умолчанию0.05
.
Доля отмененных рейсов.
Значение по умолчанию0.005
.
Коэффициент пересчета минут полета в стоимость билета в предпочитаемой валюте. В зависимости от класса обслуживания применяется дополнительный повышающий коэффициент (функцияget_price
).
Значение по умолчанию50
.
Максимальное количество пассажиров в одном бронировании.
Значение по умолчанию5
.
Минимальное время в часах между пересадками. Уменьшение запаса на пересадку увеличивает количество рейсов, доступных для формирования маршрута, но и увеличивает шанс опоздать на стыковочный рейс при задержке предыдущего.
Значение по умолчанию2
.
Максимальное время в часах между пересадками. Увеличение этого порога увеличивает количество рейсов, доступных для формирования маршрута, но где взять таких терпеливых пассажиров?
Значение по умолчанию48
.
Максимальное количество пересадок в одном билете. Чем больше допускается пересадок, тем больше вероятность, что пассажир сумеет воспользоваться нашей авиакомпанией, чтобы добраться до желаемого пункта.
Значение по умолчанию4
.
Приоритет сообщений, попадающих в журналgen.log
. Наиболее важные сообщения имеют приоритет 0.
Значение по умолчанию0
, что означает, что записываются только важные сообщения. Большее значение имеет смысл устанавливать только для отладки.
Язык, на котором в демобазе будут выводиться названия моделей самолетов, стран, городов и аэропортов. Это значение будет устанавливаться при развертывании демобазы, но впоследствии может быть изменено. Поддерживаются русский (ru
) и английский (en
) языки.
Значение по умолчаниюen
.
Ряд процедур и функций образуют API, с помощью которого пользователь взаимодействует с генератором.
Подпрограммаgenerate
начинает генерацию демобазы. Ее параметры:
start_date
(timestamptz
) — модельное время начала генерации;end_date
(timestamptz
) — модельное время окончания генерации;jobs
(integer
) — количество параллельных процессов (по умолчанию 1).
Пример вызова:
CALL generate( start_date=> date_trunc('day', now() ), end_date=> date_trunc('day', now()+ interval'1 year' ), jobs=>4);
Подпрограммаcontinue
продолжает генерацию демобазы после останова прошлого вызоваgenerate
илиcontinue
. Ее параметры:
end_date
(timestamptz
) — модельное время окончания генерации;jobs
(integer
) — количество параллельных процессов (по умолчанию 1).
В качестве начальной даты будет взято время предыдущего останова генерации.
Пример вызова:
CALL continue( end_date=> date_trunc('day', now()+ interval'2 years' ), jobs=>4);
Функцияbusy
возвращает текущее состояние генерации:true
— работает,false
— завершилась.
Пример вызова:
SELECT busy();
Процедураabort
досрочно прерывает генерацию. После прерывания можно начать генерацию заново с помощьюgenerate
, но вызовcontinue
не гарантирует корректного продолжения.
Пример вызова:
CALL abort();
Функцияget_passenger_name
выдает случайное имя пассажира из указанной страны.
Параметр:
country
(text
) — код страны.
Справочники генератора содержат имена, записанные латиницей, для следующих стран: Россия (RU
), Китай (CN
), Индия (IN
), США (US
), Канада (CA
), Япония (JP
), Франция (FR
), Германия (DE
), Италия (IT
), Великобритания (GB
), Чили (CL
), Швеция (SE
), Непал (NP
), Финляндия (FI
), Новая Зеландия (NZ
), Австрия (AT
) и Чехия (CZ
).
Функцию не требуется вызывать отдельно, но эта часть генератора может быть полезной для наполнения других баз данных, в которых требуется случайные имена с правдоподобным распределением.
Пример вызова, выводящего десять случайных непальских имен:
CALL calc_names_cume_dist();-- необходимо выполнить один разSELECT get_passenger_name('NP')FROM generate_series(1,10);
Генератор записывает сообщения в журнальную таблицуgen.log
, которую можно исследовать после генерации или использовать в процессе генерации для мониторинга:
SELECT*FROMgen.logORDER BY atDESCLIMIT30 \watch60
В журнальную таблицу попадают все сообщения с приоритетом не ниже, чем значение параметраgen.severity
. Для целей отладки набор сообщений можно расширить, указав ненулевой приоритет.
Ниже перечислены основные типы сообщений и их значение.
JobN (connname=соединение):результат
Запуск рабочего процесса номерN, используя соединение с именемсоединение.
день: one day inвремя
Выводится раз в день модельного времени и сообщает, сколько реального времени занял расчет этого модельного дня. За этим сообщением следует несколько дополнительных.
New bookings:B (forceonewayF), nopathP, noseatS
За день модельного времени было созданоB бронирований. Из нихF штук планировались как бронирования «туда и обратно» (с учетом значения параметра
gen.roundtrip_frac
), но из-за отсутствия нужных билетов бронь была сделана только в одну сторону. При этомP попыток создать бронирование полностью не удались из-за отсутствия подходящих рейсов, аS — из-за того, что на одном из выбранных рейсов не оказалось свободных мест.Book-ref retries =R (F retries/booking)
За день модельного времени потребовалосьR раз повторно выбирать случайный номер бронирования из-за того, что выбранный номер уже занят. ЗначениеF показывает количество повторных попыток в пересчете на одно бронирование.
Чем дольше работает генератор, тем больше номеров будет занято и тем больше времени будет уходить на поиск свободного значения. Емкость номера бронирования составляет около 2 млрд значений; за один модельный год при настройках по умолчанию генерируется около 5 млн бронирований, поэтому на горизонте нескольких модельных лет эта причина не вызывает замедления.
New boarding passes:BP
За день модельного времени было созданоBP посадочных талонов.
Building routes, rangeпериод
Выполняется перестроение маршрутов с периодом действияпериод. После этого сообщения идет перечисление новых маршрутов.
А1 ->A2:модель xN, traffic =P pass/week
Построен маршрут из аэропортаА1 в аэропортА2. Он выполняется самолетоммодельN раз в неделю, предполагаемый пассажиропоток составляетP пассажиров в неделю.
Cannot choose an aircraft forА1 ->А2 (out of range?)
Маршрут из аэропортаА1 в аэропортА2 не удалось построить. Обычная причина состоит в том, что расстояние между аэропортами превышает дальность всех самолетов компании. Само по себе такое сообщение не является ошибкой, но может указывать на неудачно выбранный флот, если повторяется многократно.
Vacuum
Выполнение очистки и анализа.
End date reached, exiting
Рабочий процесс завершил свою работу.
После того как демобаза сгенерирована, имеет смысл выполнить стандартные проверки, чтобы убедиться в качестве подготовленных данных.
\icheck.sql
Скрипт выполняет несколько запросов, описанных ниже.
Число, отличное от нуля, означает, что в процессе генерации произошли ошибки. Ошибки будут записаны в журнальную таблицуgen.log
и будут начинаться со слова Error.
Запросы этой секции показывают количество сгенерированных бронирований, билетов, перелетов, рейсов и маршрутов.
Скорость генерации в событиях в секунду.
Рассчитанная скорость включает и время простоя между вызовамиgenerate
иcontinue
.
Первый запрос показывает среднюю заполненность салонов самолетов.
Второй запрос показывает количество рейсов, выполненных с пустым салоном. Небольшое количество пустых рейсов может выглядеть правдоподобно.
Третий запрос показывает список моделей самолетов и количество маршрутов, которые эта модель обслуживала. Учтите, что в разные периоды времени один и тот же маршрут может обслуживаться разными самолетами, поэтому выведенные числа не стоит складывать. ВердиктNOT USED
означает, что модель не выполнила ни одного рейса — такую модель, скорее всего, стоит заменить. ВердиктWRONGLY USED
свидетельствует об ошибке в алгоритме и не должен появляться.
Отношение количества билетов «туда и обратно» к общему количеству билетов. Второе число показывает целевое значение (заданное параметромgen.roundtrip_frac
). Реальное значение всегда будет меньше целевого из-за того, что не для каждого прямого билета удается купить обратный.
ВердиктERROR: max_pass_per_bookings not satisfied
говорит о том, что в бронированиях бывает болееgen.max_pass_per_booking
пассажиров и свидетельствует об ошибке в алгоритме.
Второй запрос показывает распределение бронирований по количеству пассажиров в них. Например, строка сnpass
, равным 2, иcnt
, равным 100, говорит о том, что сто бронирований включают двух пассажиров.
Запрос показывает распределение пассажиров по количеству выполненных ими бронирований. Например, строка сnbook
, равным 3, иcnt_pass
, равным 1000, говорит о том, что тысяча пассажиров сделали по три бронирования.
Запрос показывает распределение билетов по количеству перелетов в них. Например, строка сsegments
, равным 3, иcnt
, равным 1000, говорит о том, что тысяча билетов включает три перелета.
Количество рейсов в разных статусах.
Три статуса, в которых рейсов немного, независимо от размера базы, — этоOn Time
(вылет по расписанию),Departed
(вылетел и находится в воздухе) иBoarding
(посадка пассажиров). Если таких рейсов нет, возможно стоит продолжить генерацию на несколько модельных часов, чтобы обеспечить разнообразие данных.
ВердиктERROR: route and flight discrepancy
в первом запросе говорит о рассогласовании данных о продолжительности полетов между таблицамиroutes
иflights
и свидетельствует об ошибке в алгоритме.
Второй запрос показывает минимальную, среднюю и максимальную продолжительность полетов — как запланированную, так и реальную.
Минимальная, средняя и максимальная задержка вылетов и прибытий.
ВердиктERROR: overbooking
говорит о том, что посадочных талонов выдано больше, чем мест в самолете, и свидетельствует об ошибке в алгоритме.
Доля отмененных рейсов и целевое значение (параметрgen.cancel_frac
). Должны совпадать с хорошей точностью.
ВердиктERROR: non-adjacent segments
говорит о том, что аэропорт прибытия одного перелета не совпадает с аэропортом вылета следующего перелета из того же билета. Это свидетельствует об ошибке в алгоритме.
ВердиктERROR: validity ranges have holes
говорит о наличии пропусков между периодами действия маршрутов. Это свидетельствует об ошибке в алгоритме.
ВердиктERROR: absent flights
говорит о том, что в таблицеflights
отсутствуют рейсы, которые должны быть согласно таблицеroutes
.
ВердиктERROR: excess flights
говорит о том, что в таблицеflights
есть рейсы, не соответствующие расписанию в таблицеroutes
.
Возможны оба сообщения одновременно (absent and excess flights
). Любая ошибка свидетельствует об ошибке в алгоритме.
Вердикт первого запросаERROR: flights timing discrepancy
говорит о рассогласовании времен в информации о рейсе.
Вердикт второго запросаERROR: boarding after takeoff
говорит о том, что посадка пассажиров продолжалась после взлета.
Вердикт третьего запросаERROR: booking after boarding
говорит о том, что бронирование на рейс продолжалось после начала посадки пассажиров.
Любая ошибка в этой секции свидетельствует об ошибке в алгоритме.
Пассажир может опоздать на рейс из-за задержки предыдущего стыковочного рейса. Генератор отслеживает такие ситуации, чтобы не допустить опоздавшего пассажира к следующим рейсам в билете.
Первый запрос выводит фактическое количество пассажиров, опоздавших на рейс, а также количество некорректно зарегистрированных генератором опозданий и количество незарегистрированных генератором опозданий. ВердиктERROR: incorrect missed flights
свидетельствует об ошибке в алгоритме.
Вердикт второго запросаERROR: boarding after miss
говорит о том, что пассажир садился в самолет после опоздания и свидетельствует об ошибке в алгоритме.
ВердиктERROR: interlaced flights
говорит о том, что один и тот же пассажир совершал более одного путешествия одновременно. Это свидетельствует об ошибке в алгоритме.
Сгенерированную демобазу можно выгрузить в виде SQL-скрипта, аналогичного результату работы командыpg_dump
. Находясь в каталоге репозитория выполните скрипт, перенаправляя его результат в файл, например:
./export.sh| gzip>`date +%Y%m%d`.sql.gz
Скрипту можно передать любые параметры подключения, принимаемые утилитойpg_dump
.
В SQL-скрипт будут входить объекты схемыbooking
, включая определения функцийbookings.now
(значение конечной модельной даты, указанной при генерации) иbookings.version
(версия сгенерированной демобазы). Также будут включены команды для установки параметровbookings.lang
иsearch_path
на уровне базы данных.
Генератор имитирует работу авиакомпании, создавая и обрабатывая поток случайных событий: бронирование авиабилетов пассажирами, регистрация и посадка, отправления и прибытия самолетов и т. п. Обработчик события может добавлять в очередь новые события, реализуя, в частности, конечный автомат состояний рейса.
Все таблицы генератора располагаются в схемеgen
. Они используются при генерации и хранят ее текущее состояние. Далее, если имя схемы не указано, предполагается схемаgen
.
Таблицы демобазы находятся в схемеbookings
и описаны в документации по демобазе.
Очередь событий. Очередь обрабатывается процедуройprocess_queue
, а отдельное событие - процедуройprocess_event
.
Ниже перечислены типы событий.
Это «затравочное» событие, обработка которого (процедураdo_init
) приводит к инициализации состояния всех таблиц и вставке начального набора событий:BUILD ROUTES
,BOOKING
,VACUUM
,MONITORING
.
Событие перестройки маршрутов. При его обработке (процедураbuild_routes
) создается случайный, но связный граф маршрутов. В маршрутной сети участвуют аэропорты, имеющие непустое значениеtraffic
в таблицеairports_data
. Перелеты между несколькими аэропортами одного города никогда не создаются.
Добавляемые ребра графа записываются в таблицуdirections
. Вначале от каждого аэропорта, начиная с наименее загруженного, добавляются ребра к двум другим случайным аэропортам. Вероятность добавления ребра пропорциональна трафику аэропорта назначения и обратно пропорциональна расстоянию между аэропортами. При этом с вероятностьюgen.domestic_frac
выбирается аэропорт той же страны (при наличии в маршрутной сети хотя бы двух городов этой страны).
Связность графа отслеживается с помощью таблицыdirections_connect
. Если построенный граф не является связным, в него по тем же правилам добавляются другие случайные ребра, пока связность не будет достигнута.
Новые маршруты переносятся изdirections
в таблицуbookings.routes
с соответствующим интервалом действияvalidity
. Самолет, обслуживающий маршрут, и количество рейсов в неделю подбираются исходя из прогнозируемого трафика между аэропортами (таблицаweek_traffic
).
Первое событиеBUILD ROUTES
добавляется при обработкеINIT
и порождает расписание на месяц, начиная с даты начала генерации. Далее маршруты перестраиваются каждый месяц, для чего в конце обработки события в очередь вставляется следующее событиеBUILD ROUTES
. Также для каждого построенного маршрута добавляется событиеFLIGHT
, отмечающее начало бронирований на этот маршрут за месяц до его вступления в силу.
Событие бронирования из заданного аэропорта. При его обработке (процедураmake_booking
) совершается попытка бронирования путешествия в случайный аэропорт. Вероятность выбора целевого аэропорта пропорциональна его трафику и обратно пропорциональна расстоянию между аэропортами, а также учитывает параметрgen.domestic_frac
(как и при создании расписания).
Маршрут до выбранного аэропорта определяется (функцияget_path
) с учетом следующих факторов:
- предпочтению отдается маршруту с наименьшим количеством пересадок, причем их количество не должно превышать
gen.max_hops
; - рассматриваются рейсы, на которые в продаже есть билеты и осталось достаточно времени до отправления (еще не открыта регистрация на рейс);
- между стыковочными рейсами должно быть как минимум
gen.min_transfer
часов (иначе велик риск пропустить рейс из-за возможной задержки) и не должно быть большеgen.max_transfer
часов (иначе слишком долго ждать); - среди возможных маршрутов выбирается тот, чей первый перелет начинается раньше.
Количество пассажиров в бронировании определяется случайно с учетом параметраgen.max_pass_per_booking
.
Если не удается найти подходящий маршрут или если на выбранный маршрут не удается забронировать билеты на всех пассажиров, попытка бронирования считается неудачной и отменяется.
С вероятностьюgen.roundtrip_frac
выполняется также попытка забронировать полет в обратном направлении через случайный интервал времени (до месяца, в среднем — около недели). Маршрут обратного следования может не совпадать с исходным маршрутом. Неуспешная попытка не отменяет бронирования в прямом направлении.
В результате бронирования создается строка в таблицеbookings.bookings
, строки для каждого билета вbookins.tickets
(по одной на каждого пассажира и направления следования), строки в таблице перелетовbookings.segments
.
Следующее событиеBOOKING
для данного аэропорта-источника создается так, чтобы события образовывали пуассоновский поток с частотой, соответствующей пассажиропотоку аэропорта. В среднем в неделю будет генерироватьсяairports_data.traffic
умноженное на значение параметраgen.traffic_coeff
событий бронирования.
Событие добавления рейса в расписание за месяц до отправления.
Обработчик (процедураopen_booking
) вставляет строку в таблицуbookings.flights
для рейса, открывая возможность бронирования (статусScheduled
). С вероятностьюgen.cancel_frac
рейс отменяется (статусCancelled
). Отмена всегда происходит заранее: не бывает ситуаций, когда рейс отменяется уже после того, как на него куплены какие-либо билеты.
За день до отправления неотмененного рейса на него должна открыться регистрация, за это отвечает добавляемое событиеREGISTRATION
.
Событие открытия регистрации на рейс за день до отправления.
Обработчик (процедураregistration
) меняет статус рейса наOn Time
и определяет фактическое время начала регистрации (допустима небольшая задержка на несколько минут). С вероятностьюgen.delay_frac
рейс задерживается (статусDelayed
) на время от часа до 12 часов.
Создает события регистрацииCHECK-IN
для каждого билета, проданного на данный рейс (регистрация заканчивается за 40 минут до отправления). Также создает событие начала посадкиBOARDING
на этот рейс.
Событие регистрации на рейс для конкретного билета.
Пассажир проходит регистрацию только один раз, на первый рейс в билете. Обработчик (процедураcheck_in
) создает строки в таблицеbookings.boarding_passes
для посадочных талонов на каждый рейс в билете (мы считаем, что все рейсы в билете являются стыковочными).
Событие начала посадки на рейс за полчаса до вылета.
Обработчик (процедураboarding
) меняет статус рейса наBoarding
и создает события посадкиGET IN
для каждого билета, проданного на рейс. Посадка завершается в течение 20 минут.
Если посадка заканчивается до конца периода генерации, событияGET IN
не создаются, а вместо этого номер и время посадки проставляются в посадочных талонах (таблицаbookings.boarding_passes
) немедленно. Эта оптимизация позволяет существенно сократить количество событий и ускорить генерацию.
Также создает событие взлетаTAKEOFF
, определяя фактическое время вылета (допускается небольшая задержка на несколько минут).
Событие посадки в самолет для конкретного билета.
Обработчик (процедураget_in
) проставляет номер и время посадки в посадочном талоне (таблицаbookings.boarding_passes
).
Событие взлета.
Обработчик (процедураtakeoff
) меняет статус рейса наDeparted
и создает событие приземленияLANDING
, определяя фактическую продолжительность полета (возможно отклонение от плановой продолжительности на несколько процентов как в одну, так и в другую сторону).
Событие приземления.
Обработчик (процедураlanding
) меняет статус рейса наArrived
. На этом рейс считается отработанным; новых событий не генерируется.
Событие очистки.
Обработка очереди событий происходит хотя и в разных транзакциях, но в одном операторе CALL. Из-за этого статистика изменения таблиц не передается сборщику статистики: автоочистка не имеет представления, что содержимое таблиц меняется, и не срабатывает.
Поэтому раз в неделю модельного времени очистка и анализ запускаются принудительно с помощью данного события (процедураvacuum
). Запуск происходит в отдельном процессе с помощью расширенияdblink
.
Событие мониторинга.
Событие срабатывает раз в день модельного времени и заносит в журнальную таблицуlog
сведения о прошедшем дне (процедураmonitoring
).
В эту таблицу переносятся отработанные строки изevents
для возможности отладки.
Данные о моделях самолетов. В таблицуbookings.airplanes_data
переносятся все строки и все столбцы, за исключением столбцаin_use
, который определяет, надо ли назначать данную модель на рейсы.
Данные о конфигурации салонов самолетов. Все данные переносятся без изменений в таблицуbookings.seats
.
Используется генератором для отслеживания остатка свободных мест на рейсах.
Данные об аэропортах. В таблицуbookings.airports_data
переносятся все строки и все столбцы, за исключением столбцов:
country_code
— двухсимвольный код страны в соответствии с ISO 3166-1 alpha-2 (попадает в номер билетаbookings.tickets.ticket_no
);traffic
— относительный пассажиропоток авиакомпании в данном аэропорту (абсолютное количество попыток бронирований в неделю из данного аэропорта вычисляется умножением этой величины на значение параметраgen.traffic_coeff
).
Используется генератором при составлении графа перелетов. В эту таблицу добавляются пары аэропортов, которые будет связаны прямыми рейсами.
Используется для определения связности графа перелетов.
Хранит предварительно вычисленные накопленные вероятности полета из одного аэропорта в другой (не обязательно связанных прямым рейсом) и используется при составлении графа перелетов и для выбора аэропорта назначения при бронировании.
Прогноз пассажиропотока между двумя аэропортами, соединенными прямым рейсом.
Данные о популярности имен (given names) в разбивке по странам. Таблица позволяет разделить имена одной страны на группы, например, на мужские и женские для тех языков, в которых фамилия зависит от пола. При инициализации в столбецcume_dist
заносится накопленная вероятность выбора данного имени.
Данные о популярности фамилий (family names) в разбивке по странам. Таблица позволяет разделить фамилии одной страны на группы. При инициализации в столбецcume_dist
заносится накопленная вероятность выбора данной фамилии.
Перечень уникальных пассажиров. Таблица используется генератором, чтобы гарантировать, что одному номеру документаpassenger_id
соответствует одно имя, а также что один пассажир не участвует в нескольких одновременных поездках. Информация из этой таблицы не переносится в демобазу, в которой нет отдельной сущности «пассажир».
Используется генератором для отслеживания билетов тех пассажиров, которые опоздали на очередной перелет из-за задержки предыдущего рейса.
Статистика по бронированиям. Используется для мониторинга генерации.
Статистика по параллельным процессам. В норме счетчики обработанных событий для каждого процесса должны быть примерно равны. Если счетчик какого-либо процесса не увеличивается во время генерации, следует искать сообщение об ошибке в журналеlog
.
Статистика по количеству повторов, которые потребовались для генерации уникального номера бронированияbook\_ref
.
В демобазе язык перевода выбирается параметромbookings.lang
. Переводятся названия моделей самолетов (представлениеairplanes
), а также названия аэропортов, городов и стран (представлениеairports
). В настоящий момент имеются переводы на два языка: русский (значение параметраru
) и английский (en
).
Чтобы добавить новый язык, необходимо добавить переводы в JSON-столбцыairplanes_data.model
,airports_data.airport_name
,airports_data.city
иairports_data.country
. Это непростая задача, поскольку в таблице аэропортов содержится около 5500 строк. Как минимум нужно перевести хотя бы строки с непустым значением пассажиропотока (traffic
), участвующие в маршрутной сети.
Желаемые модели самолетов и конфигурацию их салонов необходимо поместить в таблицыairplanes_data
иseats
. Все они будут перенесены в аналогичныеbookings
-таблицы. В рейсах будут участвовать только самолеты с признакомin_use
.
Необходимо учитывать, что дальность полета выбранного набора самолетов должна покрывать расстояния между городами, иначе некоторые перелеты могут оказаться нереализуемыми.
Вместимость самолетов должна соответствовать планируемому пассажиропотоку: рейс выполняется минимум раз в неделю и максимум семь раз в неделю. Без должного разнообразия вместимостей все рейсы могут оказаться переполненными или недозаполненными.
Были выбраны страны ведущих разработчиков PostgreSQL (major contributors), а также несколько других стран, имеющих определенное отношение к PostgreSQL.
Вы можете добавить и другие страны (см. ниже).
Количество городов в демобазе пропорционально квадрату суммы логарифмов площадей стран и численности их населения:
Вы можете сделать другой выбор (см. ниже).
Установите непустое значение пассажиропотокаtraffic
для желаемых аэропортов в таблицеairports_data
. Эти аэропорты и будут использоваться в маршрутах.
При добавлении новой страны недостаточно просто выбрать аэропорты в таблицеairports_data
. Потребуется также определить справочники имен для новой страны.
В настоящее время справочники генератора содержат имена, записанные латиницей, для следующих стран: Россия (RU
), Китай (CN
), Индия (IN
), США (US
), Канада (CA
), Япония (JP
), Франция (FR
), Германия (DE
), Италия (IT
), Великобритания (GB
), Чили (CL
), Швеция (SE
), Непал (NP
), Финляндия (FI
), Новая Зеландия (NZ
), Австрия (AT
) и Чехия (CZ
).
Полное имя пассажира формируется из имени (given name) и фамилии (family name), поэтому в качестве исходных данных необходимо иметь список имен и фамилий и их относительную частоту. В качестве такого списка можно, например, использовать данные переписи населения. В простом случае, если по правилам языка страны фамилия не склоняется в зависимости от рода имени (как, например, в германских и романских языках, таких как английский или французский), таких исходных данных будет достаточно.
Имена необходимо добавить в таблицуfirstname
:
country
— двухсимвольный код страны в соответствии с ISO 3166-1 alpha-2;name
— имя;qty
— целое число, отражающее популярность имени (например, зарегистрированное количество людей, носящих данное имя).
В столбецgrp
поместите значение-
.
Фамилии добавляются в таблицуlastnames
с той же структурой.
Чтобы проверить результат, можно выполнить такой запрос, гдеXX
— код страны:
CALL calc_names_cume_dist();-- рассчитывает накопленную вероятностьSELECT get_passenger_name('XX')FROM generate_series(1,10);
Для языков, в которых фамилии зависят от рода имени (например, славянские и балтийские языки, такие как русский), потребуется разделить все имена и все фамилии на мужские и женские с помощью столбцаgrp
. В этот столбец можно поместить любое текстовое значение, но оно должно совпадать в обеих таблицах (например, можно использоватьm
иf
).
Имена, относящиеся как к мужским, так и к женским, должны быть помещены в обе группы (возможно, с разной популярностью).
Тот же принцип можно использовать для разделения и на другие группы, например, чтобы смоделировать этнические группы с обособленными системами имен.
При генерации имени сначала из всех групп выбирается случайная фамилия, а затем выбирается случайное имя из той группы, к которой принадлежит фамилия. При этом полные имена, в которых имя (given name) и фамилия (family name) одинаковы, не выбираются.
Добавьте строку в таблицуairports_data
. Для этого необходимо знать:
- Код ИАТА;
- Английское название аэропорта;
- Английское название города;
- Часовой пояс;
- Координаты аэропорта (указываются в формате «долгота, широта»).
Полной актуальной базы аэропортов нет в свободном доступе. Существует несколько открытых проектов (OpenFlights,OurAirports,DataHub), но полнота и актуальность их информации под вопросом. Конкретный аэропортможно проверить на официальном сайте ИАТА.
Название аэропорта и города необходимо перевести на русский язык (и другие языки, если они должны поддерживаться настройкой многоязычностиbookings.lang
).
Чтобы новая запись была согласована с существующими, стоит придерживаться некоторых правил.
В качестве города (city
) выбирается город, который обслуживается этим аэропортом. Часто это ближайший к аэропорту крупный населенный пункт, а не тот пункт, в котором расположен аэропорт. Например, для IAR городом является Ярославль, а не село Туношна.
Официальное название аэропорта часто состоит из названия населенного пункта, в котором расположен аэропорт, посвящения какому-либо видному деятелю и других частей. Для краткости имя сокращается по следующим правилам:
- Название города не повторяется в названии аэропорта (за исключением случаев, когда официальное название состоит только из названия города, например, AAC «El Arish»);
- В качестве названия аэропорта используется либо название населенного пункта, где расположен аэропорт, либо имя человека, причем предпочтение отдается населенному пункту (например, SVO «Шереметьево имени А. С. Пушкина» сокращается до «Шереметьево»).
- Если используется посвящение человеку, титулы и воинские звания отбрасываются (например, YAI «General Bernardo O'Higgins» сокращается до «Bernardo O'Higgins»);
- Отбрасываются слова «международный», «региональный» и т. п. (например, ROA «Roanoke–Blacksburg Regional» сокращается до «Blacksburg», учитывая, что Roanoke — название города).
- В русском языке промежуточные инициалы убираются (например, JFK «John F. Kennedy» переводится как «Джон Кеннеди»).
About
Demonstration Database
Resources
License
Uh oh!
There was an error while loading.Please reload this page.