179

Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

  • Upload
    others

  • View
    20

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя
Page 2: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

Предисловие

Эту небольшую книгу мы написали для тех, кто только на-чинает знакомиться с PostgreSQL. Из нее вы узнаете:

I Что вообще такое, этот PostgreSQL . . . . . . . . . . . . . . . . . . . 3II Что нового появилось в версии PostgreSQL 12 . . . . .17III Как установить PostgreSQL на Linux и Windows . . . .27IV Как подключиться к серверу, начать писать

SQL-запросы, и зачем нужны транзакции . . . . . . . . . . 37V Как продолжить самостоятельное изучение

языка SQL с помощью демобазы . . . . . . . . . . . . . . . . . . . . 65VI Как использовать PostgreSQL в качестве

базы данных для вашего приложения . . . . . . . . . . . . . . 93VII Без каких минимальных настроек сервера

не обойтись, в том числе при работе с 1С . . . . . . . . . 107VIII Про полезную программу pgAdmin . . . . . . . . . . . . . . . . 115IX Про дополнительные возможности:

полнотекстовый поиск, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121формат JSON, . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129доступ к внешним данным . . . . . . . . . . . . . . . . . . . . . . . . . .142

X Какие есть образовательные ресурсы,как стать сертифицированным специалистом . . . . 153

XI Как быть в курсе происходящего . . . . . . . . . . . . . . . . . . 171XII И немного про компанию Postgres Professional . . 175

Мы надеемся, что наша книга сделает ваш первый опытработы с PostgreSQL приятным и поможет влиться в сооб-щество пользователей этой СУБД. Желаем удачи!

Page 3: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя
Page 4: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

3i

I О PostgreSQL

PostgreSQL — наиболее полнофункциональная, свободнораспространяемая СУБД с открытым кодом. Разработаннаяв академической среде, за долгую историю сплотившая во-круг себя широкое сообщество разработчиков, эта СУБДобладает всеми возможностями, необходимыми большин-ству заказчиков. PostgreSQL активно применяется по всемумиру для создания критичных бизнес-систем, работающихпод большой нагрузкой.

Немного истории

Современный PostgreSQL ведет происхождение от проек-та POSTGRES, который разрабатывался под руководствомМайкла Стоунбрейкера (Michael Stonebraker), профессораКалифорнийского университета в Беркли. До этого МайклСтоунбрейкер уже возглавлял разработку INGRES — однойиз первых реляционных СУБД, — и POSTGRES возник какрезультат осмысления предыдущей работы и желания пре-одолеть ограниченность жесткой системы типов.

Работа над проектом началась в 1985 году, и до 1988 годабыл опубликован ряд научных статей, описывающих мо-дель данных, язык запросов POSTQUEL (в то время SQL ещене был общепризнанным стандартом) и устройство храни-лища данных.

Page 5: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

4i

POSTGRES иногда относят к так называемым постреляци-онным СУБД. Ограниченность реляционной модели всегдабыла предметом критики, хотя и являлась обратной сто-роной ее простоты и строгости. Однако проникновениекомпьютерных технологий во все сферы жизни привелок появлению новых классов приложений и потребовало отбаз данных поддержки нестандартных типов данных и та-ких возможностей, как наследование, создание сложныхобъектов и управление ими.

Первая версия СУБД была выпущена в 1989 году. База дан-ных совершенствовалась на протяжении нескольких лет,а в 1993 году, когда вышла версия 4.2, проект был закрыт.Но, несмотря на официальное прекращение, открытый коди BSD-лицензия позволили выпускникам Беркли Эндрю Юи Джоли Чену в 1994 году взяться за его дальнейшее раз-витие. Они заменили язык запросов POSTQUEL на ставшийк тому времени общепринятым SQL, а проект нарекли Post-gres95.

К 1996 году стало ясно, что название Postgres95 не выдер-жит испытание временем, и было выбрано новое имя —PostgreSQL, которое отражает связь и с оригинальным про-ектом POSTGRES, и с переходом на SQL. Надо признать, чтоназвание получилось сложновыговариваемым, но тем неменее: PostgreSQL следует произносить как «постгрес-ку-эль» или просто «постгрес», но только не «постгре».

Новая версия стартовала как 6.0, продолжая исходную ну-мерацию. Проект вырос, и управление им взяла на себяпоначалу небольшая группа инициативных пользователейи разработчиков, которая получила название Глобальнойгруппы разработки PostgreSQL (PostgreSQL Global Develop-ment Group).

Page 6: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

5i

Развитие

Все основные решения о планах развития и выпусках но-вых версий принимаются Управляющим комитетом (Coreteam), состоящим сейчас из пяти человек.

Помимо обычных разработчиков, вносящих посильнуюлепту в развитие системы, выделяется группа основныхразработчиков (major contributors), сделавших существен-ный вклад в развитие PostgreSQL, а также группа разработ-чиков, имеющих право записи в репозиторий исходногокода (committers). Состав групп со временем меняется, по-являются новые члены, кто-то отходит от проекта. Актуаль-ный список разработчиков поддерживается на официаль-ном сайте PostgreSQL www.postgresql.org.

Вклад российских разработчиков в PostgreSQL весьма зна-чителен. Это, пожалуй, самый крупный глобальный проектс открытым исходным кодом с таким широким российскимпредставительством.

Большую роль в становлении и развитии PostgreSQL сыг-рал программист из Красноярска Вадим Михеев, входив-ший в Управляющий комитет. Он является автором такихважнейших частей системы, как многоверсионное управ-ление одновременным доступом (MVCC), система очистки(vacuum), журнал транзакций (WAL), вложенные запросы,триггеры. Сейчас Вадим уже не занимается проектом.

Олег Бартунов, астроном и научный сотрудник ГАИШ МГУ,занимается PostgreSQL без малого 25 лет, и вместе с Фе-дором Сигаевым и Александром Коротковым, имеющимистатус основных разработчиков проекта с правом записив репозиторий, основал в 2015 году компанию PostgresProfessional.

Page 7: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

6i

Среди направлений выполненных ими работ можно выде-лить локализацию PostgreSQL (поддержка национальныхкодировок и Unicode), систему полнотекстового поиска, ра-боту с массивами и слабо-структурированными данными(hstore, json, jsonb), новые методы индексации (GiST, SP-GiST, GIN и RUM, Bloom). Они являются авторами большогочисла популярных расширений.

Цикл работы над очередной версией PostgreSQL обычнозанимает около года. За это время от всех желающих при-нимаются на рассмотрение патчи с исправлениями, изме-нениями и новым функционалом. Для обсуждения патчейпо традиции используется список рассылки pgsql-hackers.Если сообщество признает идею полезной, ее реализа-цию— правильной, а код проходит обязательную проверкудругими разработчиками, то патч включается в релиз.

В некоторый момент (обычно весной, примерно за полгодадо релиза) объявляется этап стабилизации кода — новыйфункционал откладывается до следующей версии, а про-должают приниматься только исправления или улучшенияуже включенных в релиз патчей. Несколько раз в течениерелизного цикла выпускаются бета-версии, ближе к кон-цу цикла появляется релиз-кандидат, а вскоре выходит иновая основная (major) версия PostgreSQL.

Раньше номер основной версии состоял из двух чисел, но,начиная с 2017 года, было решено оставить только одно.Таким образом, за 9.6 последовала 10, а последней акту-альной версией PostgreSQL является версия 12, вышедшаяв октябре 2019 года.

При работе над новой версией СУБД могут обнаруживать-ся ошибки. Наиболее критические из них исправляютсяне только в текущей, но и в предыдущих версиях. Обычнораз в квартал выпускается дополнительные (minor) версии,

Page 8: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

7i

включающие накопленные исправления. Например, вер-сия 10.6 содержит только исправления ошибок, найденныхв 10.5, а 11.2 — для версии 11.1.

Поддержка

Глобальная группа разработки PostgreSQL выполняет под-держку основных версий системы в течение пяти лет с мо-мента выпуска. Эта поддержка, как и координация разра-ботки, осуществляется через списки рассылки. Корректнооформленное сообщение об ошибке имеет все шансы наскорейшее решение: нередки случаи, когда исправленияошибок выпускаются в течение суток.

Помимо поддержки сообществом разработчиков, ряд ком-паний по всему миру осуществляет коммерческую под-держку PostgreSQL. В России такой компанией являетсяPostgres Professional (www.postgrespro.ru), предоставляяуслуги по поддержке в режиме 24x7.

Современное состояние

PostgreSQL является одной из самых популярных баз дан-ных. За свою более чем 20-летнюю историю развития напрочном фундаменте, заложенном академической разра-боткой, PostgreSQL выросла в полноценную СУБД уровняпредприятия и составляет реальную альтернативу коммер-ческим базам данных. Чтобы убедиться в этом, достаточнопосмотреть на важнейшие характеристики новейшей насегодняшний день версии PostgreSQL 12.

Page 9: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

8i

Надежность и устойчивость

Вопросы обеспечения надежности особенно важны в при-ложениях уровня предприятия для работы с критическиважными данными. С этой целью PostgreSQL позволяетнастраивать горячее резервирование, восстановление назаданный момент времени в прошлом, различные виды ре-пликации (синхронную, асинхронную, каскадную).

Безопасность

PostgreSQL позволяет подключаться по защищенному SSL-соединению и предоставляет аутентификацию по паролю(включая SCRAM), возможность использования клиентскихсертификатов, аутентификацию с помощью внешних сер-висов (LDAP, RADIUS, PAM, Kerberos).

При управлении пользователями и доступом к объектам БДпредоставляются следующие возможности:

• создание и управление пользователями и групповымиролями;

• разграничение доступа к объектам БД на уровне как от-дельных пользователей, так и групп;

• детальное управление доступом на уровне отдельныхстолбцов и строк;

• поддержка SELinux через встроенную функциональ-ность SE-PostgreSQL (мандатное управление доступом).

Специальная версия PostgreSQL, выпущенная компаниейPostgres Professional, сертифицирована ФСТЭК для исполь-зования в системах обработки конфиденциальной инфор-мации и персональных данных.

Page 10: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

9i

Соответствие стандартам

По мере развития стандарта ANSI SQL его поддержка по-стоянно добавляется в PostgreSQL. Это относится ко всемверсиям стандарта от SQL-92 до самой последней SQL:2016,стандартизировавшей поддержку работы сформатом JSON.Существенная часть этого функционала уже реализованав PostgreSQL 12.

В целом PostgreSQL обеспечивает высокий уровень соот-ветствия стандарту и поддерживает 160 из 179 обязатель-ных возможностей, а также большое количество необяза-тельных.

Поддержка транзакционности

PostgreSQL обеспечивает полную поддержку свойств ACIDи обеспечивает эффективную изоляцию транзакций. Дляэтого в PostgreSQL используется механизм многоверсион-ного управления одновременным доступом (MVCC), кото-рый позволяет обходиться без блокировок строк во всехслучаях, кроме одновременного изменения одной и тойже строки данных в нескольких процессах: читающие тран-закции никогда не блокируют пишущих транзакций, а пи-шущие — читающих.

Это справедливо и для самого строгого уровня изоляцииserializable, который, используя инновационную системуSerializable Snapshot Isolation, обеспечивает полное от-сутствие аномалий сериализации и гарантирует, что приодновременном выполнении транзакций результат будеттаким же, как и при последовательном выполнении.

Page 11: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

10i

Для разработчиков приложений

Разработчики приложений получают в свое распоряжениебогатый инструментарий, позволяющий реализовать при-ложения любого типа:

• всевозможные языки серверного программирования:встроенный PL/pgSQL (удобный своей тесной интегра-цией с SQL), C для критичных по производительностизадач, Perl, Python, Tcl, а также JavaScript, Java и другие;

• программные интерфейсы для обращения к СУБД изприложений на любом языке, включая стандартные ин-терфейсы ODBC и JDBC;

• набор объектов баз данных, позволяющий эффективнореализовать логику любой сложности на стороне серве-ра: таблицы и индексы, последовательности, ограниче-ния целостности, представления и материализованныепредставления, секционирование, подзапросы и with-запросы (в том числе рекурсивные), агрегатные и окон-ные функции, хранимые функции, триггеры и т. д.;

• гибкая система полнотекстового поиска с поддержкойрусского и всех европейских языков, дополненная эф-фективным индексным доступом;

• слабоструктурированные данные в духе NoSQL: храни-лище пар «ключ-значение» hstore, xml, json (в текстовоми в эффективном двоичном представлении jsonb);

• подключение источников данных, включая все основ-ные СУБД, в качестве внешних таблиц по стандартуSQL/MED с возможностью их полноценного использо-вания, в том числе для записи и распределенного вы-полнения запросов (Foreign Data Wrappers).

Page 12: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

11i

Масштабируемость и производительность

PostgreSQL эффективно использует современную архитек-туру многоядерных процессоров — производительностьСУБД растет практически линейно с увеличением количе-ства ядер.

Начиная с версии 9.6 PostgreSQL умеет работать с дан-ными в параллельном режиме. Версия 10 уже позволялапараллельно читать данные (включая индексное сканиро-вание), выполнять соединения и агрегации. В версии 11был реализован полноценный параллельный режим хеш-соединения, при котором несколько рабочих процессовсовместно строят и используют общую хеш-таблицу. По-явилась возможность сканировать секционированные таб-лицы в параллельном режиме и параллельно создаватьиндексы.

Новая версия 12 позволяет распараллеливать запросы науровне изоляции serializable, выполняет JIT-компиляциюзапросов, тем самым повышая возможности использова-ния аппаратных средств для ускорения операций, и содер-жит множество других оптимизаций.

Планировщик запросов

В PostgreSQL используется планировщик запросов, осно-ванный на стоимости. Используя собираемую статистику иучитывая в своих математических моделях как дисковыеоперации, так и время работы процессора, планировщикпозволяет оптимизировать самые сложные запросы. В егораспоряжении находятся все методы доступа к данным испособы выполнения соединений, характерные для пере-довых коммерческих СУБД.

Page 13: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

12i

Возможности индексирования

В PostgreSQL реализованы различные способы индексиро-вания. Помимо традиционных B-деревьев доступно множе-ство других методов доступа.

• Hash — индекс на основе хеширования. В отличие от B-деревьев, такие индексы работают только при проверкена равенство, но в ряде случаев могут оказаться ком-пактнее и эффективнее.

• GiST — обобщенное сбалансированное дерево поиска,которое применяется для данных, не допускающих упо-рядочения. Примерами могут служить R-деревья дляиндексирования точек на плоскости с возможностьюбыстрого поиска ближайших соседей (k-NN search) и ин-дексирование операции пересечения интервалов.

• SP-GiST— обобщенное несбалансированное дерево, ос-нованное на разбиении области значений на непересе-кающиеся вложенные области. Примерами могут слу-жить дерево квадрантов для пространственных данныхи префиксное дерево для текстовых строк.

• GIN — обобщенный инвертированный индекс, которыйиспользуется для сложных значений, состоящих из эле-ментов. Основной областью применения является пол-нотекстовый поиск, где требуется находить документы,в которых встречается указанные в поисковом запросеслова. Другим примером использования является поискзначений в массивах данных.

• RUM — дальнейшее развитие метода GIN для полнотек-стового поиска. Этот индекс, доступный в виде расши-рения, позволяет ускорить фразовый поиск и сразу вы-давать результаты упорядоченными по релевантности.

Page 14: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

13i

• BRIN — компактная структура, позволяющая найти ком-промисс между размером индекса и скоростью поиска.Такой индекс эффективен на больших кластеризован-ных таблицах.

• Bloom — индекс, основанный на фильтре Блума. Такойиндекс, имея очень компактное представление, позво-ляет быстро отсечь заведомо ненужные строки, однакотребует перепроверки оставшихся.

Многие типы индексов могут создаваться не только по од-ному, но и по нескольким столбцам таблицы. Независимоот типа можно строить индексы как по столбцам, так и попроизвольным выражениям, а также создавать частичныеиндексы только для определенных строк. Покрывающиеиндексы позволяют ускорить запросы за счет того, что всенеобходимые данные извлекаются из самого индекса безобращения к таблице.

В арсенале планировщика имеется сканирование по бито-вой карте, которое позволяет объединять сразу несколькоиндексов для ускорения доступа.

Кроссплатформенность

PostgreSQL работает на операционных системах семей-ства Unix, включая серверные и клиентские разновидностиLinux, FreeBSD, Solaris и macOS, а также на Windows.

За счет открытого и переносимого кода на языке C Post-greSQL можно собрать на самых разных платформах, дажеесли для них отсутствует поддерживаемая сообществомсборка.

Page 15: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

14i

Расширяемость

Расширяемость — одно из фундаментальных преимуществсистемы, лежащее в основе архитектуры PostgreSQL. Поль-зователи могут самостоятельно, не меняя базовый код си-стемы, добавлять

• типы данных,

• функции и операторы для работы с новыми типами,

• индексные и табличные методы доступа,

• языки серверного программирования,

• подключения к внешним источникам данных (ForeignData Wrappers),

• загружаемые расширения.

Полноценная поддержка расширений позволяет реализо-вать функционал любой сложности без внесения измене-ний в ядро PostgreSQL и допуская подключение по меренеобходимости. Например, именно в виде расширений по-строены такие сложные системы, как:

• CitusDB — возможность распределения данных по раз-ным экземплярам PostgreSQL (шардинг) и массивно-параллельного выполнения запросов;

• PostGIS — одна из наиболее известных и мощных сис-тем обработки геоинформационных данных.

Только стандартный комплект, входящий в сборку Post-greSQL 12, содержит около полусотни расширений, дока-завших свою надежность и полезность.

Page 16: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

15i

Доступность

Либеральная лицензия PostgreSQL, сходная с лицензия-ми BSD и MIT, разрешает неограниченное использованиеСУБД, модификацию кода, а также включение в состав дру-гих продуктов, в том числе закрытых и коммерческих.

Независимость

PostgreSQL не принадлежит ни одной компании и развива-ется международным сообществом, в том числе и россий-скими разработчиками. Это означает, что системы, исполь-зующие PostgreSQL, не зависят от какого-либо конкретноговендора, тем самым в любой ситуации сохраняя вложен-ные в них инвестиции.

Page 17: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя
Page 18: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

17ii

II Новое в PostgreSQL 12

Если вы знакомы с предыдущими версиями PostgreSQL, этаглава даст вам представление о том, что успело поменятьсяза прошедший год. Здесь перечислена только часть изме-нений; полный список, как обычно, смотрите в замечанияхк выпуску: postgrespro.ru/docs/postgresql/12/release-12.

Секционирование

В прежние времена аналог секционирования можно былосделать только вручную на основе механизма наследова-ния, ограничений исключения и триггеров. В версии 10 по-явилось долгожданное декларативное секционирование:возможность объявить таблицу секционированной сразупри ее создании. Ограниченный поначалу функционал ак-тивно развивается и улучшается с каждой следующей вер-сией системы.

В версии 11 стало можно объявлять ограничения уникаль-ности на секционированной таблице, но возможность ссы-латься на секционированную таблицу из внешних ключейне была реализована. Теперь это упущение исправлено.

Помимо этой крупной доработки сделаны многочисленныеулучшения, касающиеся скорости выполнения операций

Page 19: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

18ii

(в том числе при большом числе секций), уменьшения уров-ня блокировок для служебных команд, упрощения админи-стрирования.

Глобальные индексы на секционированных таблицах по-прежнему не реализованы, но на эту тему ведутся активныедискуссии.

Индексы

Индексы на основе B-деревьев уменьшаются в размерах:это касается многоколоночных индексов и индексов, со-держащих повторяющиеся данные. Увеличилась и ско-рость вставки в индексы.

Индексы других типов тоже в выигрыше:

• При создании GiST, SP-GiST и GIN генерируется меньшежурнальных записей.

• Индексы GiST могут включать дополнительные столбцыс помощью конструкции INCLUDE, чтобы стать покрыва-ющими (в предыдущей версии это было доступно толь-ко для B-деревьев).

• Индексы SP-GiST обзавелись поиском ближайших сосе-дей (k-NN) наравне с GiST. B-деревья на подходе.

Добавлена команда REINDEX CONCURRENTLY, пересоздаю-щая индексы без помех для операций изменения данных.Раньше этого же можно было достичь командами CREATE иDROP INDEX CONCURRENTLY, но заменить индекс, поддержи-вающий ограничение целостности, без кратковременноймонопольной блокировки было невозможно.

Page 20: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

19ii

Оптимизация и выполнение запросов

Расширенная статистика по нескольким столбцам, появив-шаяся в версии 10, позволяет учесть функциональные за-висимости и количество различных значений для улуч-шения оценок планировщика. Теперь расширенная стати-стика поддерживает списки частых значений. На оценкидля функций теперь можно влиять, указывая планировщи-ку ожидаемую селективность, кардинальность и стоимостьв зависимости от значений параметров функции.

Снято ограничение на материализацию общих табличныхвыражений, что позволяет планировщику оптимизироватьих вместе с основным запросом. Это изменение нарушаетповедение по умолчанию, которое можно вернуть, явноуказав MATERIALIZED.

Выбором общего или частного плана для подготовленныхоператоров теперь можно управлять с помощью парамет-ра сервера. Раньше не было способа запретить планиров-щику переключиться на общий план, что могло приводитьк неоптимальному выполнению запросов.

Теперь запросы могут распараллеливаться на уровне изо-ляции serializable. Учитывая, что в предыдущей версии бы-ла добавлена поддержка предикатных блокировок для ин-дексов GiST, GIN и Hash, уровень serializable становится всеболее привлекательным. Правда, на репликах он пока ещене работает.

Есть и другие изменения, благодаря которым качество пла-нирования запросов улучшается. А еще команда EXPLAINумеет теперь сообщать нестандартные параметры оптими-затора, что полезно для диагностики проблем.

Page 21: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

20ii

Производительность сервера

Добавленная в прошлой версии поддержка JIT-компиля-ции теперь активирована по умолчанию, что свидетель-ствует о ее переходе из экспериментальной возможностив рабочую.

Из TOAST может извлекаться минимально необходимая на-чальная часть значения, вместо того, чтобы полностью рас-паковывать сжатое значение и выбрасывать лишнее, какбыло раньше.

Кроме этого сделано много небольших улучшений, позво-ляющих выполнять ряд операций быстрее.

Мониторинг

Вывод запросов в журнал сообщений может генерироватьогромный объем информации. Теперь есть возможностьрегистрировать в журнале только определенный проценттранзакций, что особенно полезно для OLTP-систем, в ко-торых выполняется много однотипных транзакций. (Воз-можность регистрации только части «коротких» операцийпоявится в следующей версии.)

По аналогии с имеющимся pg_stat_progress_vacuum, до-бавлены представления, показывающие ход выполнениякоманд CREATE INDEX, REINDEX, VACUUM FULL.

Добавлено еще одно событие ожидания: синхронизацияс диском при записи журнальных файлов. Это позволитполучать лучшую детализацию производительности ввода-вывода.

Page 22: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

21ii

Кроме того, многие системные представления показыва-ют теперь более полную информацию. Также добавленыфункции для просмотра архивного и временных каталоговнепосредственно из SQL.

Очистка (vacuum)

В новой версии значения по умолчанию обеспечивают бо-лее производительную работу автоочистки, что не отменя-ет, конечно, необходимости ее аккуратной настройки, темболее, что «ручек» стало еще больше.

Команды VACUUM и ANALYZE научились пропускать таблицы,которые не удалось заблокировать. Заодно они не пытают-ся больше запрашивать блокировку для таблиц, к которымпользователь не имеет доступа.

Появилась возможность не удалять пустые страницы в кон-це табличного файла при очистке; обычно это полезно, нотребует кратковременной монопольной блокировки таб-лицы. Еще команде VACUUM можно запретить очищать ин-дексы, например, чтобы как можно быстрее заморозитьверсии строк для предотвращения последствий перепол-нения счетчика транзакций.

Теперь можно указывать горизонт видимости в утилитеvacuumdb, что позволяет при необходимости направитьочистку на те таблицы, которые больше всего в ней нуж-даются.

Очистка стала удалять пустые листовые страницы из GiST-индексов.

Page 23: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

22ii

Репликация и восстановление

Все параметры восстановления перенесены в файл post-gresql.conf. Recovery.conf больше не существует, а переходв режим восстановления и режим резервного сервера ини-циируется двумя сигнальными файлами. Это изменениеунифицирует работу с конфигурационными параметрамии позволит в будущем менять некоторые настройки без пе-резагрузки сервера.

Теперь можно делать копии репликационных слотов (какфизических, так и логических). Это полезно, в частности,когда надо развернуть несколько реплик из одной резерв-ной копии.

Новая SQL-функция повышает резервный сервер до основ-ного. Ранее это можно было сделать только сигналом состороны операционной системы.

Необходимые для работы потоковой репликации процес-сы wal_sender больше не учитываются при ограничениимаксимального числа соединений. Таким образом, много-численные подключения клиентов не смогут больше поме-шать работе репликации.

А такжемного других, не таких заметных, но полезных улуч-шений.

Команды SQL

Появилась возможность создавать в таблицах генерируе-мые столбцы (конструкция GENERATED ALWAYS AS). Текущая

Page 24: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

23ii

реализация допускает только хранимые столбцы, а вирту-альные (вычисляемые на лету) появятся позже. Генерируе-мые столбцы во многих случаях удобнее столбцов, запол-няемых триггерами, и работают быстрее.

Можно фильтровать строки в команде COPY FROM при копи-ровании записей из файла в таблицу.

К командам COMMIT и ROLLBACK можно добавить AND CHAIN,чтобы завершить одну транзакцию и сразу же начать сле-дующую. Такой вариант предусмотрен стандартом SQL, норанее не был реализован.

Безграничные перспективы открывает возможность созда-вать табличные методы доступа командой CREATE ACCESS

METHOD и указывать метод доступа при создании таблицы.Единственный доступный — старый добрый heap, так чтопока для пользователей ничего не изменилось. Нофактиче-ски это первый шаг к подключаемым хранилищам данных,который в первую очередь потребовал серьезных измене-ний внутри ядра системы. Разработка новых эксперимен-тальных методов доступа уже началась:

• Zheap избавляет нас от раздувания таблиц и необходи-мости очистки, используя журнал отката. Лучше всегоэтот метод должен показать себя при работе с часто из-меняющимися данными.github.com/EnterpriseDB/zheap

• Zedstore реализует колоночное хранение данных совстроенным сжатием. Оно подойдет для аналитическихзапросов, обрабатывающих много строк, но лишь частьстолбцов.github.com/greenplum-db/postgres/tree/zedstore

Page 25: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

24ii

Утилиты

Консольный клиент psql, многими недооцененный, сталеще удобнее. Поддерживается вывод таблиц в форматеCSV, подсказка по командам SQL выдает ссылку на раз-дел документации, улучшено автодополнение по табуля-ции для многих команд, новая команда \dP показываетсекционированные таблицы.

Утилита pg_upgrade, предназначенная для обновления сер-вера, научилась клонировать файлы (если ФС это позво-ляет). Эффект тот же, что и при использовании жесткихссылок, но последующие изменения не затрагивают ста-рый кластер и к нему можно вернуться при возникновениикаких-либо сложностей.

Утилита pg_verify_checksums переименована теперь в про-сто pg_checksums и позволяет включать и выключать кон-трольные суммы кластера без его пересоздания. Сервер,однако, должен быть остановлен — изменение на лету бу-дет доступно позже.

Поддержка SQL/JSON

Стандарт SQL:2016 определил способы работы с даннымив формате JSON в языке SQL, положив конец несовмести-мым друг с другом реализациям. В нынешнюю версию во-шла основная часть стандарта— язык путей SQL/JSON, кото-рый играет примерно такую же роль, как XPath при работес XML. На с. 138 можно увидеть несколько примеров, кото-рые позволят составить представление об этом языке.

Page 26: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

25ii

Позже появится поддержка в SQL/JSON типов даты и вре-мени, равно как и другая часть стандарта, описывающаянеобходимые функции (среди которых, например, пред-ставление JSON в виде реляционной таблицы).

Разное

В таблицах системного каталога столбец oid больше не яв-ляется скрытым. Сам столбец никуда не денется, простотеперь его будет видно в запросах «со звездочкой». А ис-пользовать тип oid в собственных таблицах в любом случаене следует.

Документация обзавелась первыми иллюстрациями. Покаих всего две: загляните в разделы 66.4 «Реализация индек-сов GIN» и 68.6 «Компоновка страницы базы данных».

Page 27: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя
Page 28: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

27iii

III Установкаи начало работы

Что нужно для начала работы с PostgreSQL? В этой главе мыобъясним, как установить службу PostgreSQL и управлятьей, а потом создадим простую базу данных и покажем, каксоздать в ней таблицы. Мы расскажем и основы языка SQL,на котором формулируются запросы. Будет неплохо, есливы сразу начнете пробовать команды по мере чтения.

Мы будем использовать обычный («ванильный», как егочасто называют) дистрибутив PostgreSQL 12. Установка изапуск сервера PostgreSQL зависит от того, какую операци-онную систему вы используете. Если у васWindows, читайтедальше; если Linux семейства Debian или Ubuntu — пере-ходите сразу к с. 33.

Инструкции по установке для других операционных системвы найдете по адресу www.postgresql.org/download.

С тем же успехом вы можете воспользоваться и дистрибу-тивом Postgres Pro Standard 12: он полностью совместимс обычной СУБД PostgreSQL, включает некоторые разработ-ки, выполненные в нашей компании Postgres Professional,и бесплатен для ознакомления и для образовательных це-лей. В этом случае инструкции по установке ищите на сайтеpostgrespro.ru/products/download.

Page 29: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

28iii

Windows

Установка

Скачайте установщик с нашего сайта, запустите его и выбе-рите язык установки: postgrespro.ru/windows.

Установщик построен в традиционном стиле «мастера»: выможете просто нажимать на кнопку «Далее», если вас устра-ивают предложенные варианты. Остановимся подробнеена основных шагах.

Компоненты устанавливаемой программы:

Page 30: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

29iii

Оставьте все флажки, если не уверены, какие выбрать.

Далее следует выбрать каталог для установки PostgreSQL.По умолчанию установка выполняется в папку C:\ProgramFiles\PostgreSQL\12.

Отдельно можно выбрать расположение каталога для базданных.

Именно здесь будет находиться хранимая в СУБД инфор-мация, так что убедитесь, что на диске достаточно места,если вы планируете хранить много данных.

Page 31: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

30iii

Параметры сервера:

Если вы планируете хранить данные на русском языке,выберите локаль «Russian, Russia» (или оставьте вариант«Настройка ОС», если в Windows используется русская ло-каль).

Введите (и подтвердите повторным вводом) пароль пользо-вателя СУБД postgres. Также отметьте флажок «Настроитьпеременные среды», чтобы подключаться к серверу Post-greSQL под текущим пользователем ОС.

Остальные поля можно оставить со значениями по умолча-нию.

Page 32: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

31iii

Если вы планируете установить PostgreSQL только для озна-комительных целей, можно отметить вариант «Использо-вать параметры по умолчанию», чтобы СУБД не занималамного оперативной памяти.

Управление службой и основные файлы

При установке Postgres Pro в вашей системе регистриру-ется служба «postgresql-12». Она запускается автоматиче-ски при старте компьютера под учетной записью NetworkService (Сетевая служба). При необходимости вы може-те изменить параметры службы с помощью стандартныхсредств Windows.

Page 33: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

32iii

Чтобы временно остано-вить службу сервера базданных, выполните про-грамму «Stop Server» изпапки в меню «Пуск», ко-торую вы указали приустановке.

Для запуска службы тамже находится программа«Start Server».

Если при запуске службы произошла ошибка, для поис-ка причины следует заглянуть в журнал сообщений сер-вера. Он находится в подкаталоге log каталога, выбран-ного при установке для баз данных (обычно C:\Program

Files\PostgreSQL\12\data\log). Журнал настроен так,чтобы запись периодически переключалась в новый файл.Найти актуальный файл можно по дате последнего изме-нения или по имени, которое содержит дату и время пере-ключения.

Есть несколько важных конфигурационных файлов, кото-рые определяют настройки сервера. Они располагаютсяв каталоге баз данных. Вам не нужно их изменять, чтобыначать знакомство с PostgreSQL, но в реальной работе онинепременно потребуются:

• postgresql.conf — это основной конфигурационныйфайл, содержащий значения параметров сервера;

• pg_hba.conf — файл, определяющий настройки досту-па. В целях безопасности по умолчанию доступ должен

Page 34: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

33iii

быть подтвержден паролем и допускается только с ло-кального компьютера.

Обязательно загляните в эти файлы — они прекрасно доку-ментированы.

Теперь мы готовы подключиться к базе данных и попробо-вать некоторые команды и запросы. Переходите к разделу«Пробуем SQL» на с. 37.

Debian и Ubuntu

Установка

Если вы используете Linux, то для установки необходи-мо подключить пакетный репозиторий PGDG (PostgreSQLGlobal Development Group). В настоящее время для систе-мы Debian поддерживаются версии 8 «Jessie», 9 «Stretch»и 10 «Buster», а для Ubuntu — 16.04 «Xenial» и 18.04«Bionic».

Выполните в терминале следующие команды:

$ sudo apt-get install lsb-release

$ sudo sh -c 'echo "deb \http://apt.postgresql.org/pub/repos/apt/ \$(lsb_release -cs)-pgdg main" \> /etc/apt/sources.list.d/pgdg.list'

$ wget --quiet -O - \https://www.postgresql.org/media/keys/ACCC4CF8.asc \| sudo apt-key add -

Репозиторий подключен, обновим список пакетов:

Page 35: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

34iii

$ sudo apt-get update

Перед установкой проверьте настройки локализации:

$ locale

Если вы планируете хранить данные на русском языке, зна-чение переменных LC_CTYPE и LC_COLLATE должно бытьравно «ru_RU.UTF8» (значение «en_US.UTF8» тоже подхо-дит, но менее предпочтительно). При необходимости уста-новите эти переменные:

$ export LC_CTYPE=ru_RU.UTF8$ export LC_COLLATE=ru_RU.UTF8

Также убедитесь, что в операционной системе установленасоответствующая локаль:

$ locale -a | grep ru_RUru_RU.utf8

Если это не так, сгенерируйте ее:

$ sudo locale-gen ru_RU.utf8

Теперь можно приступить к установке:

$ sudo apt-get install postgresql-12

Как только эта команда выполнится, СУБД PostgreSQL будетустановлена, запущена и готова к работе. Чтобы проверитьэто, выполните команду:

$ sudo -u postgres psql -c 'select now()'

Если все проделано успешно, в ответ вы должны получитьтекущее время.

Page 36: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

35iii

Управление службой и основные файлы

При установке PostgreSQL на вашей системе автоматиче-ски был создан специальный пользователь postgres, отимени которого работают процессы, обслуживающие сер-вер, и которому принадлежат все файлы, относящиеся кСУБД. PostgreSQL будет автоматически запускаться при пе-резагрузке операционной системы. С настройками по умол-чанию это не проблема: если вы не работаете с серверомбазы данных, он потребляет совсем немного ресурсов ва-шей системы. Если вы все-таки захотите отключить автоза-пуск, выполните:

$ sudo systemctl disable postgresql

Чтобы временно остановить службу сервера баз данных,выполните команду:

$ sudo systemctl stop postgresql

Запустить службу сервера можно командой:

$ sudo systemctl start postgresql

Можно также проверить текущее состояние:

$ sudo systemctl status postgresql

Если служба не запускается, найти причину поможет жур-нал сообщений сервера. Внимательно прочитайте самыепоследние записи из журнала, который находится в файле/var/log/postgresql/postgresql-12-main.log.

Page 37: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

36iii

Вся информация, которая содержится в базе данных, рас-полагается в файловой системе в специальном каталоге/var/lib/postgresql/12/main/. Убедитесь, что у вас до-статочно свободного места, если собираетесь хранить мно-го данных.

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

• /etc/postgresql/12/main/postgresql.conf — основ-ной конфигурационныйфайл, содержащий значения па-раметров сервера;

• /etc/postgresql/12/main/pg_hba.conf—файл, опре-деляющий настройки доступа. В целях безопасности поумолчанию доступ разрешен только с локального ком-пьютера и только под пользователем базы данных, имякоторого совпадает с именем пользователя в операци-онной системе.

Самое время подключиться к базе данных и попробоватьSQL в деле.

Page 38: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

IV Пробуем SQL

Подключение с помощью psql

Чтобы подключиться к серверу СУБД и выполнить какие-либо команды, требуется программа-клиент. В главе «Post-greSQL для приложения» мы будем говорить о том, какпосылать запросы из программ на разных языках програм-мирования, а сейчас речь пойдет о терминальном клиентеpsql, работа с которым происходит интерактивно в режи-ме командной строки.

К сожалению, в наше время многие недолюбливают ко-мандную строку. Почему имеет смысл научиться с ней ра-ботать?

Во-первых, psql— стандартный клиент, он входит в любуюсборку PostgreSQL и поэтому всегда под рукой. Безусловно,хорошо иметь настроенную под себя среду, но нет резонаоказаться беспомощным в незнакомом окружении.

Во-вторых, psql действительно удобен для решения по-вседневных задач по администрированию баз данных, длянаписания небольших запросов и автоматизации процес-сов, например, для периодической установки измененийпрограммного кода на сервер СУБД. Он имеет собствен-ные команды, позволяющие сориентироваться в объектах,хранящихся в базе данных, и удобно представить инфор-мацию из таблиц.

Page 39: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

38iv

Но если вы привыкли работать с графическими пользо-вательскими интерфейсами, попробуйте pgAdmin — мыеще упомянем эту программу ниже — или другие аналогич-ные продукты: wiki.postgresql.org/wiki/Community_Guide_to_PostgreSQL_GUI_Tools

Чтобы запустить psql, в операционной системе Linux вы-полните команду:

$ sudo -u postgres psql

В ОС Windows запусти-те программу «SQL Shell(psql)» из папки меню«Пуск».

В ответ на запрос вве-дите пароль пользова-теля postgres, которыйвы указали при установ-ке PostgreSQL.

Пользователи Windowsмогут столкнуться с про-блемой неправильногоотображения символов

русского языка в терминале. В этом случае убедитесь,что свойствах окна терминала установлен TrueType-шрифт(обычно «Lucida Console» или «Consolas»).

В итоге и в одной, и в другой операционной системе выувидите одинаковое приглашение postgres=#. «Postgres»здесь — имя базы данных, к которой вы сейчас подключе-ны. Один сервер PostgreSQLможет одновременно обслужи-вать несколько баз данных, но одновременно вы работаететолько с одной из них.

Page 40: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

39iv

Дальше мы будем приводить некоторые команды. Вводитетолько то, что выделено жирным шрифтом; приглашение иответ системы на команду приведены исключительно дляудобства.

База данных

Давайте создадим новую базу данных с именем test. Вы-полните:

postgres=# CREATE DATABASE test;

CREATE DATABASE

Не забудьте про точку с запятой в конце команды — покаPostgreSQL не увидит этот символ, он будет считать, чтовы продолжаете ввод (так что команду можно разбить нанесколько строк).

Теперь переключимся на созданную базу:

postgres=# \c test

You are now connected to database "test" as user"postgres".

test=#

Как вы видите, приглашение сменилось на test=#.

Команда, которую мы только что ввели, не похожа на SQL —она начинается с обратной косой черты. Так выглядят спе-циальные команды, которые понимает только psql (поэто-му, если у вас открыт pgAdmin или другое графическоесредство, пропускайте все, что начинается на косую чер-ту, или попытайтесь найти аналог).

Page 41: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

40iv

Команд psql довольно много, и с некоторыми из них мыпознакомимся чуть позже, а полный список с кратким опи-санием можно получить прямо сейчас:

test=# \?

Поскольку справочная информация довольна объемна,она будет показана с помощью настроенной в операцион-ной системе команды-пейджера (обычно more или less).

Таблицы

В реляционных СУБД данные представляются в виде таб-лиц. Заголовок таблицы определяет столбцы; собственноданные располагаются в строках. Данные не упорядочены(в частности, нельзя полагаться на то, что строки хранятсяв порядке их добавления в таблицу).

Для каждого столбца устанавливается тип данных; зна-чения соответствующих полей строк должны удовлетво-рять этим типам. PostgreSQL располагает большим чис-лом встроенных типов (postgrespro.ru/doc/datatype.html)и возможностями для создания новых, но мы ограничимсянесколькими из основных:

• integer — целые числа;

• text — текстовые строки;

• boolean — логический тип, принимающий значенияtrue (истина) или false (ложь).

Помимо обычных значений, определяемых типом данных,поле может иметь неопределенное значение NULL — его

Page 42: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

41iv

можно рассматривать как «значение неизвестно» или «зна-чение не задано».

Давайте создадим таблицу дисциплин, читаемых в вузе:

test=# CREATE TABLE courses(test(# c_no text PRIMARY KEY,test(# title text,test(# hours integertest(# );

CREATE TABLE

Обратите внимание, как меняется приглашение psql: этоподсказка, что ввод команды продолжается на новой стро-ке. В дальнейшем для удобства мы не будем дублироватьприглашение на каждой строке.

В этой командемы определили, что таблица с именем cour-

ses будет состоять из трех столбцов: c_no — текстовыйномер курса, title— название курса, и hours— целое чис-ло лекционных часов.

Кроме столбцов и типов данных мы можем определитьограничения целостности, которые будут автоматическипроверяться — СУБД не допустит появление в базе некор-ректных данных. В нашем примере мы добавили ограниче-ние PRIMARY KEY для столбца c_no, которое говорит о том,что значения в этом столбце должны быть уникальными,а неопределенные значения не допускаются. Такой стол-бец можно использовать для того, чтобы отличить однустроку в таблице от других. Полный список ограниченийцелостности: postgrespro.ru/doc/ddl-constraints.html.

Точный синтаксис команды CREATE TABLE можно посмот-реть в документации, а можно прямо в psql:

test=# \help CREATE TABLE

Page 43: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

42iv

Такая справка есть по каждой команде SQL, а полный спи-сок команд покажет \help без параметров.

Наполнение таблиц

Добавим в созданную таблицу несколько строк:

test=# INSERT INTO courses(c_no, title, hours)VALUES ('CS301', 'Базы данных', 30),

('CS305', 'Сети ЭВМ', 60);

INSERT 0 2

Если вам требуется массовая загрузка данных из внешнегоисточника, команда INSERT — не лучший выбор; посмот-рите на специально предназначенную для этого командуCOPY: postgrespro.ru/doc/sql-copy.html.

Для дальнейших примеров нам потребуется еще две таб-лицы: студенты и экзамены. Для каждого студента будемхранить его имя и год поступления; идентифицироватьсяон будет числовым номером студенческого билета.

test=# CREATE TABLE students(s_id integer PRIMARY KEY,name text,start_year integer

);

CREATE TABLE

test=# INSERT INTO students(s_id, name, start_year)VALUES (1451, 'Анна', 2014),

(1432, 'Виктор', 2014),(1556, 'Нина', 2015);

INSERT 0 3

Page 44: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

43iv

Экзамен содержит оценку, полученную студентом по неко-торой дисциплине. Таким образом, студенты и дисциплинысвязаны друг с другом отношением «многие ко многим»:один студент может сдавать экзаменыпомногим дисципли-нам, а экзамен по одной дисциплине могут сдавать многостудентов.

Запись в таблице экзаменов идентифицируется совокупно-стью номера студбилета и номера курса. Такое ограниче-ние целостности, относящее сразу к нескольким столбцам,определяется с помощью фразы CONSTRAINT:

test=# CREATE TABLE exams(s_id integer REFERENCES students(s_id),c_no text REFERENCES courses(c_no),score integer,CONSTRAINT pk PRIMARY KEY(s_id, c_no)

);

CREATE TABLE

Кроме того, с помощью фразы REFERENCES мы определи-ли два ограничения ссылочной целостности, называемыевнешними ключами. Такие ограничения показывают, чтозначения в одной таблице ссылаются на строки в другойтаблице.

Теперь при любых действиях СУБД будет проверять, чтовсе идентификаторы s_id, указанные в таблице экзаменов,соответствуют реальным студентам (то есть записям в таб-лице студентов), а номера c_no — реальным курсам. Такимобразом, будет исключена возможность оценить несуще-ствующего студента или поставить оценку по несуществую-щей дисциплине — независимо от действий пользователяили возможных ошибок в приложении.

Page 45: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

44iv

Поставим нашим студентам несколько оценок:

test=# INSERT INTO exams(s_id, c_no, score)VALUES (1451, 'CS301', 5),

(1556, 'CS301', 5),(1451, 'CS305', 5),(1432, 'CS305', 4);

INSERT 0 4

Выборка данных

Простые запросы

Чтение данных из таблиц выполняется оператором SQLSELECT. Например, выведем только два столбца из таблицыcourses:

test=# SELECT title AS course_title, hoursFROM courses;

course_title | hours--------------+-------Базы данных | 30Сети ЭВМ | 60

(2 rows)

Конструкция AS позволяет переименовать столбец, еслиэто необходимо. Чтобы вывести все столбцы, достаточноуказать символ звездочки:

test=# SELECT * FROM courses;

c_no | title | hours-------+-------------+-------CS301 | Базы данных | 30CS305 | Сети ЭВМ | 60

(2 rows)

Page 46: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

45iv

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

test=# SELECT start_year FROM students;

start_year------------

201420142015

(3 rows)

Чтобы выбрать все различные года поступления, послеSELECT надо добавить слово DISTINCT:

test=# SELECT DISTINCT start_year FROM students;

start_year------------

20142015

(2 rows)

Подробнее смотрите в документации: postgrespro.ru/doc/sql-select.html#SQL-DISTINCT

Вообще после слова SELECT можно указывать и любые вы-ражения. А без фразы FROM результирующая таблица будетсодержать одну строку. Например:

test=# SELECT 2+2 AS result;

result--------

4(1 row)

Page 47: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

46iv

Обычно при выборке данных требуется получить не всестроки, а только те, которые удовлетворят какому-либоусловию. Такое условие фильтрации записывается во фра-зе WHERE:

test=# SELECT * FROM courses WHERE hours > 45;

c_no | title | hours-------+----------+-------CS305 | Сети ЭВМ | 60

(1 row)

Условие должно иметь логический тип. Например, оно мо-жет содержать отношения =, <> (или !=), >, >=, <, <=; можетобъединять более простые условия с помощью логическихопераций AND, OR, NOT и круглых скобок — как в обычныхязыках программирования.

Тонкий момент представляет собой неопределенное зна-чение NULL. В результирующую таблицу попадают только тестроки, для которых условие фильтрации истинно; если жезначение ложно или не определено, строка отбрасывается.Учтите:

• результат сравнения чего-либо с неопределенным зна-чением не определен;

• результат логических операций с неопределенным зна-чением, как правило, не определен (исключения: trueOR NULL = true, false AND NULL = false);

• для проверки определенности значения используютсяспециальные отношения IS NULL (IS NOT NULL) и IS

DISTINCT FROM (IS NOT DISTINCT FROM), а также бываетудобно воспользоваться функцией coalesce.

Подробнее смотрите в документации: postgrespro.ru/doc/functions-comparison.html

Page 48: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

47iv

Соединения

Грамотно спроектированная реляционная база данных несодержит избыточных данных. Например, таблица экзаме-нов не должна содержать имя студента, потому что егоможно найти в другой таблице по номеру студенческогобилета.

Поэтому для получения всех необходимых значений в за-просе часто приходится соединять данные из несколькихтаблиц, перечисляя их имена во фразе FROM:

test=# SELECT * FROM courses, exams;

c_no | title | hours | s_id | c_no | score-------+-------------+-------+------+-------+-------CS301 | Базы данных | 30 | 1451 | CS301 | 5CS305 | Сети ЭВМ | 60 | 1451 | CS301 | 5CS301 | Базы данных | 30 | 1556 | CS301 | 5CS305 | Сети ЭВМ | 60 | 1556 | CS301 | 5CS301 | Базы данных | 30 | 1451 | CS305 | 5CS305 | Сети ЭВМ | 60 | 1451 | CS305 | 5CS301 | Базы данных | 30 | 1432 | CS305 | 4CS305 | Сети ЭВМ | 60 | 1432 | CS305 | 4

(8 rows)

То, что у нас получилось, называется прямым или декар-товым произведением таблиц — к каждой строке однойтаблицы добавляется каждая строка другой.

Как правило, более полезный и содержательный результатможно получить, указав во фразе WHERE условие соедине-ния. Получим оценки по всем дисциплинам, сопоставляякурсы с теми экзаменами, которые проводились именнопо данному курсу:

test=# SELECT courses.title, exams.s_id, exams.scoreFROM courses, examsWHERE courses.c_no = exams.c_no;

Page 49: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

48iv

title | s_id | score-------------+------+-------Базы данных | 1451 | 5Базы данных | 1556 | 5Сети ЭВМ | 1451 | 5Сети ЭВМ | 1432 | 4

(4 rows)

Запросы можно формулировать и в другом виде, указываясоединения с помощью ключевого слова JOIN. Выведемстудентов и их оценки по курсу «Сети ЭВМ»:

test=# SELECT students.name, exams.scoreFROM studentsJOIN exams

ON students.s_id = exams.s_idAND exams.c_no = 'CS305';

name | score--------+-------Анна | 5Виктор | 4

(2 rows)

С точки зрения СУБД обеформы эквивалентны, так что мож-но использовать тот способ, который представляется болеенаглядным.

Этот пример показывает, что в результат не включаютсястроки исходной таблицы, для которых не нашлось парыв другой таблице: хотя условие наложено на дисциплины,но при этом исключаются и студенты, которые не сдавалиэкзамен по данной дисциплине. Чтобы в выборку попаливсе студенты, надо использовать внешнее соединение:

test=# SELECT students.name, exams.scoreFROM studentsLEFT JOIN exams

ON students.s_id = exams.s_idAND exams.c_no = 'CS305';

Page 50: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

49iv

name | score--------+-------Анна | 5Виктор | 4Нина |

(3 rows)

В этом примере в результат добавляются строки из левойтаблицы (поэтому операция называется LEFT JOIN), длякоторых не нашлось пары в правой. При этом для столб-цов правой таблицы возвращаются неопределенные зна-чения.

Условия во фразе WHERE применяются к уже готовому ре-зультату соединений, поэтому, если вынести ограничениена дисциплины из условия соединения, Нина не попадетв выборку — ведь для нее exams.c_no не определен:

test=# SELECT students.name, exams.scoreFROM studentsLEFT JOIN exams ON students.s_id = exams.s_idWHERE exams.c_no = 'CS305';

name | score--------+-------Анна | 5Виктор | 4

(2 rows)

Не стоит опасаться соединений. Это обычная и естествен-ная для реляционных СУБД операция, и у PostgreSQL име-ется целый арсенал эффективных механизмов для ее вы-полнения. Не соединяйте данные в приложении, доверьтеэту работу серверу баз данных— он прекрасно с ней справ-ляется.

Подробнее смотрите в документации: postgrespro.ru/doc/sql-select.html#SQL-FROM

Page 51: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

50iv

Подзапросы

Оператор SELECT формирует таблицу, которая (как мы ужевидели) может быть выведена в качестве результата, а мо-жет быть использована в другой конструкции языка SQLв любом месте, где по смыслу может находиться таблица.Такая вложенная команда SELECT, заключенная в круглыескобки, называется подзапросом.

Если подзапрос возвращает ровно одну строку и ровноодин столбец, его можно использовать как обычное ска-лярное выражение:

test=# SELECT name,(SELECT scoreFROM examsWHERE exams.s_id = students.s_idAND exams.c_no = 'CS305')

FROM students;

name | score--------+-------Анна | 5Виктор | 4Нина |

(3 rows)

Если скалярный подзапрос, использованный в списке вы-ражений SELECT, не содержит ни одной строки, возвраща-ется неопределенное значение (как в последней строкерезультата примера). Поэтому скалярные подзапросы мож-но раскрыть, заменив их на соединение, но обязательновнешнее.

Скалярные подзапросы можно также использовать в усло-виях фильтрации. Получим все экзамены, которые сдавалистуденты, поступившие после 2014 года:

Page 52: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

51iv

test=# SELECT *FROM examsWHERE (SELECT start_year

FROM studentsWHERE students.s_id = exams.s_id) > 2014;

s_id | c_no | score------+-------+-------1556 | CS301 | 5

(1 row)

В SQL можно формулировать условия и на подзапросы,возвращающие произвольное количество строк. Для это-го существует несколько конструкций, одна из которых —отношение IN — проверяет, содержится ли значение в таб-лице, возвращаемой подзапросом.

Выведем студентов, получивших какие-нибудь оценки поуказанному курсу:

test=# SELECT name, start_yearFROM studentsWHERE s_id IN (SELECT s_id

FROM examsWHERE c_no = 'CS305');

name | start_year--------+------------Анна | 2014Виктор | 2014

(2 rows)

Отношение NOT IN возвращает противоположный резуль-тат. Например, список студентов, получивших только отлич-ные (то есть не получивших более низкие) оценки:

test=# SELECT name, start_yearFROM studentsWHERE s_id NOT IN

(SELECT s_id FROM exams WHERE score < 5);

Page 53: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

52iv

name | start_year------+------------Анна | 2014Нина | 2015

(2 rows)

Еще одна возможность — использовать предикат EXISTS,проверяющий, что подзапрос возвратил хотя бы одну стро-ку. С его помощью можно записать предыдущий запросв другом виде:

test=# SELECT name, start_yearFROM studentsWHERE NOT EXISTS (SELECT s_id

FROM examsWHERE exams.s_id = students.s_idAND score < 5);

name | start_year------+------------Анна | 2014Нина | 2015

(2 rows)

Подробнее смотрите в документации: postgrespro.ru/doc/functions-subquery.html

В примерах выше мы уточняли имена столбцов названия-ми таблиц, чтобы избежать неоднозначности. Иногда этогонедостаточно. Например, в запросе одна и та же таблицаможет участвовать два раза, или вместо таблицы в предло-жении FROM мы можем использовать безымянный подза-прос. В этих случаях после подзапроса можно указать про-извольное имя, которое называется псевдонимом (alias).Псевдонимы можно использовать и для обычных таблиц.

Выведем имена студентов и их оценки по предмету «Базыданных»:

Page 54: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

53iv

test=# SELECT s.name, ce.scoreFROM students sJOIN (SELECT exams.*

FROM courses, examsWHERE courses.c_no = exams.c_noAND courses.title = 'Базы данных') ce

ON s.s_id = ce.s_id;

name | score------+-------Анна | 5Нина | 5

(2 rows)

Здесь s — псевдоним таблицы, а ce — псевдоним подза-проса. Псевдонимы обычно выбирают так, чтобы они быликороткими, но оставались понятными.

Тот же запрос можно записать и без подзапросов, напри-мер так:

test=# SELECT s.name, e.scoreFROM students s, courses c, exams eWHERE c.c_no = e.c_noAND c.title = 'Базы данных'AND s.s_id = e.s_id;

Сортировка

Как уже говорилось, данные в таблицах не упорядочены,но часто бывает важно получить строки результата в строгоопределенном порядке. Для этого используется предло-жение ORDER BY со списком выражений, по которым надовыполнить сортировку. После каждого выражения (ключасортировки) можно указать направление: ASC — по воз-растанию (этот порядок используется по умолчанию) илиDESC — по убыванию.

Page 55: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

54iv

test=# SELECT *FROM examsORDER BY score, s_id, c_no DESC;

s_id | c_no | score------+-------+-------1432 | CS305 | 41451 | CS305 | 51451 | CS301 | 51556 | CS301 | 5

(4 rows)

Здесь строки упорядочены сначала по возрастанию оцен-ки, для совпадающих оценок — по возрастанию номерастуденческого билета, а при совпадении первых двух клю-чей — по убыванию номера курса.

Операцию сортировки имеет смысл выполнять в концезапроса непосредственно перед получением результата;в подзапросах она обычно бессмысленна.

Подробнее смотрите в документации: postgrespro.ru/doc/sql-select.html#SQL-ORDERBY.

Группировка

При группировке в одной строке результата размещаетсязначение, вычисленное на основании данных несколькихстрок исходных таблиц. Вместе с группировкой используютагрегатные функции. Например, выведем общее количе-ство проведенных экзаменов, количество сдававших ихстудентов и средний балл:

test=# SELECT count(*), count(DISTINCT s_id),avg(score)FROM exams;

Page 56: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

55iv

count | count | avg-------+-------+--------------------

4 | 3 | 4.7500000000000000(1 row)

Аналогичную информацию можно получить в разбивке пономерам курсов с помощью предложения GROUP BY, в кото-ром указываются ключи группировки:

test=# SELECT c_no, count(*),count(DISTINCT s_id), avg(score)FROM examsGROUP BY c_no;

c_no | count | count | avg-------+-------+-------+--------------------CS301 | 2 | 2 | 5.0000000000000000CS305 | 2 | 2 | 4.5000000000000000

(2 rows)

Полный список агрегатных функций: postgrespro.ru/doc/functions-aggregate.html.

В запросах, использующих группировку, может возник-нуть необходимость отфильтровать строки на основаниирезультатов агрегирования. Такие условия можно задатьв предложении HAVING. Отличие от WHERE состоит в том,что условия WHERE применяются до группировки (в нихможно использовать столбцы исходных таблиц), а условияHAVING — после группировки (и в них можно также исполь-зовать столбцы таблицы-результата).

Выберем имена студентов, получивших более одной пятер-ки по любому предмету:

test=# SELECT students.nameFROM students, examsWHERE students.s_id = exams.s_id AND exams.score = 5GROUP BY students.nameHAVING count(*) > 1;

Page 57: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

56iv

name------Анна

(1 row)

Подробнее смотрите в документации: postgrespro.ru/doc/sql-select.html#SQL-GROUPBY.

Изменение и удаление данных

Изменение данных в таблице выполняет оператор UPDATE,в котором указываются новые значения полей для строк,определяемых предложением WHERE (таким же, как в опе-раторе SELECT).

Например, увеличим число лекционных часов для курса«Базы данных» в два раза:

test=# UPDATE coursesSET hours = hours * 2WHERE c_no = 'CS301';

UPDATE 1

Подробнее смотрите в документации: postgrespro.ru/doc/sql-update.html.

Оператор DELETE удаляет из указанной таблицы строки,определяемые все тем же предложением WHERE:

test=# DELETE FROM exams WHERE score < 5;

DELETE 1

Подробнее смотрите в документации: postgrespro.ru/doc/sql-delete.html.

Page 58: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

57iv

Транзакции

Давайте немного расширим нашу схему данных и распре-делим студентов по группам. При этом потребуем, чтобыу каждой группы в обязательном порядке был староста.Для этого создадим таблицу групп:

test=# CREATE TABLE groups(g_no text PRIMARY KEY,monitor integer NOT NULL REFERENCES students(s_id)

);

CREATE TABLE

Здесь мы использовали ограничение целостности NOT

NULL, которое запрещает неопределенные значения.

Теперь в таблице студентов нам необходим еще один стол-бец — номер группы, — о котором мы не подумали сразу.К счастью, в уже существующую таблицу можно добавитьновый столбец:

test=# ALTER TABLE studentsADD g_no text REFERENCES groups(g_no);

ALTER TABLE

С помощью команды psql всегда можно посмотреть, какиестолбцы определены в таблице:

test=# \d students

Table "public.students"Column | Type | Modifiers

------------+---------+----------s_id | integer | not nullname | text |start_year | integer |g_no | text |...

Page 59: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

58iv

Также можно вспомнить, какие вообще таблицы присут-ствуют в базе данных:

test=# \d

List of relationsSchema | Name | Type | Owner

--------+----------+-------+----------public | courses | table | postgrespublic | exams | table | postgrespublic | groups | table | postgrespublic | students | table | postgres

(4 rows)

Создадим теперь группу «A-101» и поместим в нее всех сту-дентов, а старостой сделаем Анну.

Тут возникает затруднение. С одной стороны, мы не можемсоздать группу, не указав старосту. А с другой, как мы мо-жем назначить Анну старостой, если она еще не входитв группу? Это привело бы к появлению в базе данных ло-гически некорректных, несогласованных данных.

Мы столкнулись с тем, что две операции надо совершитьодновременно, потому что ни одна из них не имеет смыс-ла без другой. Такие операции, составляющие логическинеделимую единицу работы, называются транзакцией.

Начнем транзакцию:

test=# BEGIN;

BEGIN

Затем добавим группу вместе со старостой. Поскольку мыне помним наизусть номер студенческого билета Анны, вы-полним запрос прямо в команде добавления строк:

Page 60: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

59iv

test=# INSERT INTO groups(g_no, monitor)SELECT 'A-101', s_idFROM studentsWHERE name = 'Анна';

INSERT 0 1

Откройте теперь новое окно терминала и запустите ещеодин процесс psql: это будет сеанс, работающий парал-лельно с первым.

Чтобы не запутаться, команды второго сеанса мы будемпоказывать с отступом. Увидит ли второй сеанс сделанныеизменения?

postgres=# \c test

You are now connected to database "test" as user"postgres".

test=# SELECT * FROM groups;

g_no | monitor------+---------(0 rows)

Нет, не увидит, ведь транзакция еще не завершена.

Теперь переведем всех студентов в созданную группу:

test=# UPDATE students SET g_no = 'A-101';

UPDATE 3

И снова второй сеанс видит согласованные данные, акту-альные на начало еще не оконченной транзакции:

test=# SELECT * FROM students;

Page 61: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

60iv

s_id | name | start_year | g_no------+--------+------------+------1451 | Анна | 2014 |1432 | Виктор | 2014 |1556 | Нина | 2015 |(3 rows)

А теперь завершим транзакцию, зафиксировав все сделан-ные изменения:

test=# COMMIT;

COMMIT

И только в этот момент второму сеансу становятся доступ-ны все изменения, сделанные в транзакции, как будто онипоявились одномоментно:

test=# SELECT * FROM groups;

g_no | monitor-------+---------A-101 | 1451(1 row)

test=# SELECT * FROM students;

s_id | name | start_year | g_no------+--------+------------+-------1451 | Анна | 2014 | A-1011432 | Виктор | 2014 | A-1011556 | Нина | 2015 | A-101(3 rows)

СУБД дает несколько очень важных гарантий.

Во-первых, любая транзакция либо выполняется целиком(как в нашем примере), либо не выполняется совсем. Ес-ли бы в одной из команд произошла ошибка, или мы сами

Page 62: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

61iv

прервали бы транзакцию командой ROLLBACK, то база дан-ных осталась бы в том состоянии, в котором она была докоманды BEGIN. Это свойство называется атомарностью.

Во-вторых, когда фиксируются изменения транзакции, всеограничения целостности должны быть выполнены, иначетранзакция прерывается. В начале работы транзакции дан-ные находятся в согласованном состоянии, и в конце своейработы транзакция оставляет их согласованными; это свой-ство так и называется — согласованность.

В-третьих, как мы убедились на примере, другие пользова-тели никогда не увидят несогласованные данные, которыетранзакция еще не зафиксировала. Это свойство называет-ся изоляцией; за счет его соблюдения СУБД способна па-раллельно обслуживать много сеансов, не жертвуя коррект-ностью данных. Особенностью PostgreSQL является оченьэффективная реализация изоляции: несколько сеансов мо-гут одновременно читать и изменять данные, не блокируядруг друга. Блокировка возникает только при одновремен-ном изменении одной и той же строки двумя разными про-цессами.

И в-четвертых, гарантируется долговечность: зафиксиро-ванные данные не пропадут даже в случае сбоя (конечно,при правильных настройках и регулярном выполнении ре-зервного копирования).

Это крайне полезные свойства, без которых невозможнопредставить себе реляционную систему управления база-ми данных.

Подробнее о транзакциях см. postgrespro.ru/doc/tutorial-transactions.html (и еще более подробно — postgrespro.ru/doc/mvcc.html).

Page 63: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

62iv

Полезные команды psql

\? Справка по командам psql.

\h Справка по SQL: список доступных команд илисинтаксис конкретной команды.

\x Переключает традиционный табличный вы-вод (столбцы и строки) на расширенный (каж-дый столбец на отдельной строке) и обратно.Удобно для просмотра нескольких «широких»строк.

\l Список баз данных.

\du Список пользователей.

\dt Список таблиц.

\di Список индексов.

\dv Список представлений.

\df Список функций.

\dn Список схем.

\dx Список установленных расширений.

\dp Список привилегий.

\d имя Подробная информация по конкретному объ-екту базы данных.

\d+ имя И еще более подробная информация по кон-кретному объекту.

\timing on Показывать время выполнения операторов.

Page 64: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

63iv

Заключение

Конечно, мы успели осветить только малую толику того, чтонеобходимо знать о СУБД, но надеемся, что вы убедились:начать использовать PostgreSQL совсем нетрудно. Язык SQLпозволяет формулировать запросы самой разной сложно-сти, а PostgreSQL предоставляет качественную поддержкустандарта и эффективную реализацию. Пробуйте, экспери-ментируйте!

И еще одна важная команда psql: для того, чтобы завер-шить сеанс работы, наберите

test=# \q

Page 65: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя
Page 66: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

65v

V Демонстрационнаябаза данных

Описание

Общая информация

Чтобы двигаться дальше и учиться писать более слож-ные запросы, нам понадобится более серьезная база дан-ных — не три таблицы, а целых восемь, — и наполнение ееправдоподобными данными. Схема базы данных, которуюмы будем использовать, изображена в виде диаграммы«сущность-связи» на с. 67.

В качестве предметной области мы выбрали авиаперевоз-ки: будем считать, что речь идет о нашей (пока еще несу-ществующей) авиакомпании. Тем, кто хотя бы раз летал насамолетах, эта область должна быть понятна; в любом слу-чае мы сейчас все объясним.

Хочется отметить, что мы старались сделать схему данныхкак можно проще, не загромождая ее многочисленнымидеталями, но, в то же время, не слишком простой, чтобы наней можно было учиться писать интересные и осмыслен-ные запросы.

Page 67: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

66v

Основной сущностью является бронирование (bookings).В одно бронирование можно включить несколько пассажи-ров, каждому из которых выписывается отдельный билет(tickets). Как таковой пассажир не является отдельной сущ-ностью: для простоты можно считать, что все пассажирыуникальны.

Каждый билет включает один или несколько перелетов(ticket_flights). Несколько перелетов могут включаться в би-лет в нескольких случаях:

1. Нет прямого рейса, соединяющего пункты отправле-ния и назначения (полет с пересадками);

2. Взят билет «туда и обратно».

В схеме данных нет жесткого ограничения, но предполага-ется, что все билеты в одном бронировании имеют одина-ковый набор перелетов.

Каждый рейс (flights) следует из одного аэропорта (air-ports) в другой. Рейсы с одним номером имеют одинаковыепункты вылета и назначения, но будут отличаться датой от-правления.

При регистрации на рейс пассажиру выдается посадочныйталон (boarding_passes), в котором указано место в самоле-те. Пассажир может зарегистрироваться только на тот рейс,который есть у него в билете. Комбинация рейса и местав самолете должна быть уникальной, чтобы не допуститьвыдачу двух посадочных талонов на одно место.

Количество мест (seats) в самолете и их распределениепо классам обслуживания зависит от конкретной моделисамолета (aircrafts), выполняющего рейс. Предполагается,что у каждой модели — только одна компоновка салона.

Page 68: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

67v

Bookings

#book_ref

∗book_date

∗total_am

ount

Airports

#airport_code

∗airport_nam

e∗city

∗coordinates

∗timezone

Tickets

#ticket_no

∗book_ref

∗passenger_id

∗passenger_nam

e∗contact_data

Ticket_flights

#ticket_no

#flight_id

∗fare_conditions

∗am

ount

Flights

#flight_id

∗flight_no

∗scheduled_departure

∗scheduled_arrival

∗departure_airport

∗arrival_airport

∗status

∗aircraft_code

◦actual_departure

◦actual_arrival

Aircrafts

#aircraft_code

∗model

∗range

Boarding_passes

#ticket_no

#flight_id

∗boarding_no

∗seat_no

Seats

#aircraft_code

#seat_no

∗fare_conditions

1

Page 69: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

68v

Page 70: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

69v

Схема данных не контролирует, что места в посадочныхталонах соответствуют имеющимся в салоне.

Далее мы подробно опишем каждую из таблиц, а такжедополнительные представления и функции. Точное опре-деление любой таблицы, включая типы данных и описаниестолбцов, вы всегда можете получить командой \d+.

Бронирование

Намереваясь воспользоваться услугами нашей авиаком-пании, пассажир заранее (book_date, максимум за месяцдо рейса) бронирует необходимые билеты. Бронированиеидентифицируется своим номером book_ref (шестизнач-ная комбинация букв и цифр).

Поле total_amount хранит общую стоимость включенныхв бронирование перелетов всех пассажиров.

Билет

Билет имеет уникальный номер ticket_no, состоящий из13 цифр.

Билет содержит номер документа, который удостоверя-ет личность пассажира passenger_id, а также его фами-лию и имя passenger_name и контактную информациюcontact_data.

Заметим, что ни идентификатор пассажира, ни его имя неявляются постоянными (можно поменять паспорт, можносменить фамилию). Поэтому однозначно найти все биле-ты одного и того же пассажира невозможно. Для простотыможно считать, что все пассажиры уникальны.

Page 71: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

70v

Перелет

Перелет соединяет билет с рейсом и идентифицируетсядвумя их номерами.

Для каждого перелета указываются его стоимость amountи класс обслуживания fare_conditions.

Рейс

Естественный ключ таблицы рейсов состоит из двух по-лей — номера рейса flight_no и даты отправленияscheduled_departure. Чтобы сделать внешние ключи наэту таблицу компактнее, в качестве первичного использу-ется суррогатный ключ flight_id.

Рейс всегда соединяет две точки — аэропорты вылетаdeparture_airport и прибытия arrival_airport.

Такое понятие, как «рейс с пересадками» отсутствует: еслииз одного аэропорта до другого нет прямого рейса, в билетпросто включаются несколько необходимых рейсов.

У каждого рейса есть запланированные дата и время вы-лета scheduled_departure и прибытия scheduled_arri-

val. Реальные время вылета actual_departure и прибы-тия actual_arrival могут отличаться: обычно не сильно,но иногда и на несколько часов, если рейс задержан.

Статус рейса status может принимать одно из значений:

• ScheduledРейс доступен для бронирования. Это происходит за ме-сяц до плановой даты вылета; до этого запись о рейсене существует в базе данных.

Page 72: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

71v

• On TimeРейс доступен для регистрации (за сутки до плановойдаты вылета) и не задержан.

• DelayedРейс доступен для регистрации (за сутки до плановойдаты вылета), но задержан.

• DepartedСамолет уже вылетел и находится в воздухе.

• ArrivedСамолет прибыл в пункт назначения.

• CancelledРейс отменен.

Аэропорт

Каждый аэропорт идентифицируется трехбуквенным ко-дом airport_code и имеет название airport_name.

Название города city указывается как атрибут аэропорта;отдельной сущности для него не предусмотрено. Названиеможно использовать для того, чтобы определить аэропор-ты одного города. Также указываются координаты (долготаи широта) coordinates и часовой пояс timezone.

Посадочный талон

При регистрации на рейс, которая возможна за сутки доплановой даты отправления, пассажиру выдается посадоч-ный талон. Он идентифицируется так же, как и перелет —номером билета и номером рейса.

Page 73: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

72v

Посадочным талонам присваиваются последовательныеномера boarding_no в порядке регистрации пассажировна рейс (этот номер будет уникальным только в пределахданного рейса). В посадочном талоне указывается номерместа seat_no.

Самолет

Каждая модель воздушного судна идентифицируется сво-им трехзначным кодом aircraft_code. Указывается такженазвание модели model и максимальная дальность полетав километрах range.

Место

Места определяют схему салона каждой модели. Каж-дое место определяется своим номером seat_no и име-ет закрепленный за ним класс обслуживания fare_condi-tions — Economy, Comfort или Business.

Представление для рейсов

Над таблицей flights создано представление flights_v,содержащее дополнительную информацию:

• расшифровку данных об аэропорте вылетаdeparture_airport, departure_airport_name,departure_city;

• расшифровку данных об аэропорте прибытияarrival_airport, arrival_airport_name,arrival_city;

Page 74: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

73v

• местное время вылетаscheduled_departure_local,actual_departure_local;

• местное время прибытияscheduled_arrival_local, actual_arrival_local;

• продолжительность полетаscheduled_duration, actual_duration.

Представление для маршрутов

Таблица рейсов содержит избыточность: из нее можно бы-ло бы выделить информацию о маршруте (номер рейса,аэропорты отправления и назначения, модель самолета),не зависящую от конкретных дат рейсов.

Именно такая информация и составляет представлениеroutes. Кроме того, это представление показывает массивдней недели days_of_week, по которым совершаются по-леты, и плановую продолжительность рейса duration.

Функция now

Демонстрационная база содержит временной «срез» дан-ных — так, как будто в некоторый момент была сделана ре-зервная копия реальной системы. Например, если некото-рый рейс имеет статус Departed, это означает, что в моментрезервного копирования самолет находился в воздухе.

Позиция «среза» сохранена в функции bookings.now. Ейможно пользоваться в запросах там, где в обычной жизнииспользовалась бы функция now.

Page 75: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

74v

Кроме того, значение этой функции определяет версиюдемонстрационной базы данных. Актуальная версия на мо-мент подготовки этого выпуска книги — от 15.08.2017.

Установка

Установка с сайта

База данных доступна в трех версиях, которые отличаютсятолько объемом данных:

• edu.postgrespro.ru/demo-small.zip — небольшая,данные по полетам за один месяц (файл 21 МБ,размер БД 280 МБ),

• edu.postgrespro.ru/demo-medium.zip — средняя,данные по полетам за три месяца (файл 62 МБ,размер БД 702 МБ),

• edu.postgrespro.ru/demo-big.zip — большая,данные по полетам за один год (файл 232 МБ,размер БД 2638 МБ).

Небольшая база годится для того, чтобы тренироваться пи-сать запросы, и при этом не займет много места на диске.Если же вы хотите погрузиться в вопросы оптимизации, вы-берите большую базу, чтобы сразу понять, как ведут себязапросы на больших объемах данных.

Файлы содержат логическую резервную копию базы demo,созданную утилитой pg_dump. Имейте в виду, что если у васуже есть база данных с именем demo, она будет удалена исоздана заново при восстановлении из резервной копии.

Page 76: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

75v

Владельцем базы demo станет тот пользователь СУБД, подкоторым выполнялось восстановление.

Чтобы установить демонстрационную базу данных в опера-ционной системе Linux, скачайте один из файлов, предва-рительно переключившись на пользователя postgres. На-пример, для базы небольшого размера это можно сделатьследующим образом:

$ sudo su - postgres

$ wget https://edu.postgrespro.ru/demo-small.zip

Затем выполните команду:

$ zcat demo-small.zip | psql

В операционной системе Windows любым веб-браузеромскачайте с сайта файл edu.postgrespro.ru/demo-small.zip,после чего дважды кликните на нем, чтобы открыть архив,и затем скопируйте файл demo-small-20170815.sql в ка-талог C:\Program Files\PostgreSQL\12.

Программа pgAdmin (о которой пойдет речь на с. 115) непозволяет восстановить базу данных из такой резервнойкопии. Поэтому запустите psql (ярлык «SQL Shell (psql)») ивыполните команду:

postgres# \i demo-small-20170815.sql

Если файл не будет найден, проверьте у ярлыка свойство«Start in» («Рабочая папка») — файл должен находитьсяименно в этом каталоге.

Page 77: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

76v

Примеры запросов

Пара слов о схеме

Теперь, когда установка выполнена, запустите psql и под-ключитесь к демонстрационной базе:

postgres=# \c demo

You are now connected to database "demo" as user"postgres".

Все интересующие нас объекты находятся в схеме book-

ings. При подключении к базе данных эта схема использу-ется автоматически, так что явно ее указывать не нужно:

demo=# SELECT * FROM aircrafts;

aircraft_code | model | range---------------+---------------------+-------773 | Боинг 777-300 | 11100763 | Боинг 767-300 | 7900SU9 | Сухой Суперджет-100 | 3000320 | Аэробус A320-200 | 5700321 | Аэробус A321-200 | 5600319 | Аэробус A319-100 | 6700733 | Боинг 737-300 | 4200CN1 | Сессна 208 Караван | 1200CR2 | Бомбардье CRJ-200 | 2700

(9 rows)

Однако для функции bookings.now указывать схему необ-ходимо, чтобы отличать ее от стандартной функции now:

demo=# SELECT bookings.now();

now------------------------2017-08-15 18:00:00+03

(1 row)

Page 78: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

77v

Как вы уже заметили, названия самолетов выводятся по-русски. Так же обстоит дело и с названиями аэропортови городов:

demo=# SELECT airport_code, cityFROM airports LIMIT 5;

airport_code | city--------------+--------------------------YKS | ЯкутскMJZ | МирныйKHV | ХабаровскPKC | Петропавловск-КамчатскийUUS | Южно-Сахалинск

(5 rows)

Если вы предпочитаете английские названия, установитепараметр bookings.lang в значение en:

demo=# ALTER DATABASE demo SET bookings.lang = en;

ALTER DATABASE

Настройка действует только для новых сеансов, поэтомунужно подключиться заново.

demo=# \c

You are now connected to database "demo" as user"postgres".

demo=# SELECT airport_code, cityFROM airports LIMIT 5;

airport_code | city--------------+-------------------YKS | YakutskMJZ | MirnyjKHV | KhabarovskPKC | PetropavlovskUUS | Yuzhno-sakhalinsk

(5 rows)

Page 79: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

78v

Как это устроено, вы можете разобраться, посмотрев опре-деление aircrafts или airports командой psql \d+.

Подробнее про управление схемами: postgrespro.ru/doc/ddl-schemas.html и про установку конфигурационных па-раметров: postgrespro.ru/doc/config-setting.html.

Простые запросы

Ниже мы покажем несколько задач на демонстрационнойсхеме. Большинство из них приведены вместе с решения-ми, остальные предлагается решить самостоятельно.

Задача. Кто летел позавчера рейсом Москва (SVO) — Ново-сибирск (OVB) на месте 1A, и когда он забронировал свойбилет?

Решение. «Позавчера» отсчитывается от booking.now, а неот текущей даты.

SELECT t.passenger_name,b.book_date

FROM bookings bJOIN tickets t

ON t.book_ref = b.book_refJOIN boarding_passes bp

ON bp.ticket_no = t.ticket_noJOIN flights f

ON f.flight_id = bp.flight_idWHERE f.departure_airport = 'SVO'AND f.arrival_airport = 'OVB'AND f.scheduled_departure::date =

bookings.now()::date - INTERVAL '2 day'AND bp.seat_no = '1A';

Задача. Сколько мест осталось незанятыми вчера на рейсеPG0404?

Page 80: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

79v

Решение. Задачу можно решить несколькими способами.Первый вариант использует конструкцию NOT EXISTS, что-бы определить места без посадочных талонов:

SELECT count(*)FROM flights f

JOIN seats sON s.aircraft_code = f.aircraft_code

WHERE f.flight_no = 'PG0404'AND f.scheduled_departure::date =

bookings.now()::date - INTERVAL '1 day'AND NOT EXISTS (

SELECT NULLFROM boarding_passes bpWHERE bp.flight_id = f.flight_idAND bp.seat_no = s.seat_no

);

Второй использует операцию вычитания множеств:

SELECT count(*)FROM (

SELECT s.seat_noFROM seats sWHERE s.aircraft_code = (

SELECT aircraft_codeFROM flightsWHERE flight_no = 'PG0404'AND scheduled_departure::date =

bookings.now()::date - INTERVAL '1 day')EXCEPTSELECT bp.seat_noFROM boarding_passes bpWHERE bp.flight_id = (

SELECT flight_idFROM flightsWHERE flight_no = 'PG0404'AND scheduled_departure::date =

bookings.now()::date - INTERVAL '1 day')

) t;

Page 81: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

80v

Какой вариант использовать, во многом зависит от личныхпредпочтений. Необходимо только учитывать, что выпол-няться такие запросы будут по-разному, так что если важнапроизводительность, то имеет смысл попробовать оба.

Задача.На каких маршрутах произошли самые длительныезадержки рейсов? Выведите список из десяти «лидирую-щих» рейсов.

Решение. В запросе надо учитывать только рейсы, которыеуже вылетели:

SELECT f.flight_no,f.scheduled_departure,f.actual_departure,f.actual_departure - f.scheduled_departureAS delay

FROM flights fWHERE f.actual_departure IS NOT NULLORDER BY f.actual_departure - f.scheduled_departure

DESCLIMIT 10;

То же самое условие можно записать и на основе столб-ца status, перечислив все подходящие статусы. А можнообойтись и вовсе без условия WHERE, указав порядок сорти-ровки DESC NULLS LAST, чтобы неопределенные значенияпопали не в начало, а в конец выборки.

Агрегатные функции

Задача. Какова минимальная и максимальная продолжи-тельность полета для каждого из возможных рейсов изМосквы в Санкт-Петербург, и сколько раз вылет рейса былзадержан больше, чем на час?

Page 82: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

81v

Решение. Здесь удобно воспользоваться готовым представ-лением flights_v, чтобы не выписывать соединения необ-ходимых таблиц. В запросе учитываем только уже выпол-ненные рейсы.

SELECT f.flight_no,f.scheduled_duration,min(f.actual_duration),max(f.actual_duration),sum(CASE WHEN f.actual_departure >

f.scheduled_departure +INTERVAL '1 hour'

THEN 1 ELSE 0END) delays

FROM flights_v fWHERE f.departure_city = 'Москва'AND f.arrival_city = 'Санкт-Петербург'AND f.status = 'Arrived'GROUP BY f.flight_no,

f.scheduled_duration;

Задача. Найдите самых дисциплинированных пассажиров,которые зарегистрировались на все рейсы первыми. Учти-те только тех пассажиров, которые совершали минимумдва рейса.

Решение. Используем тот факт, что номера посадочных та-лонов выдаются в порядке регистрации.

SELECT t.passenger_name,t.ticket_no

FROM tickets tJOIN boarding_passes bp

ON bp.ticket_no = t.ticket_noGROUP BY t.passenger_name,

t.ticket_noHAVING max(bp.boarding_no) = 1AND count(*) > 1;

Page 83: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

82v

Задача. Сколько человек бывает включено в одно брони-рование?

Решение. Сначала посчитаем количество человек в каждомбронировании, а затем число бронирований для каждогоколичества человек.

SELECT tt.cnt,count(*)

FROM (SELECT t.book_ref,

count(*) cntFROM tickets tGROUP BY t.book_ref

) ttGROUP BY tt.cntORDER BY tt.cnt;

Оконные функции

Задача. Для каждого билета выведите входящие в негоперелеты вместе с запасом времени на пересадку на следу-ющий рейс. Ограничьте выборку теми билетами, которыебыли забронированы неделю назад.

Решение. Используем оконные функции, чтобы не обра-щаться к одним и тем же данным два раза.

Глядя в результаты приведенного ниже запроса, можно об-ратить внимание, что запас времени в некоторых случаяхсоставляет несколько дней. Как правило, это билеты, взя-тые туда и обратно, то есть мы видим уже не время пере-садки, а время нахождения в пункте назначения. Исполь-зуя решение одной из задач в разделе «Массивы», можноучесть этот факт в запросе.

Page 84: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

83v

SELECT tf.ticket_no,f.departure_airport,f.arrival_airport,f.scheduled_arrival,lead(f.scheduled_departure) OVER wAS next_departure,lead(f.scheduled_departure) OVER w -

f.scheduled_arrivalAS gap

FROM bookings bJOIN tickets t

ON t.book_ref = b.book_refJOIN ticket_flights tf

ON tf.ticket_no = t.ticket_noJOIN flights f

ON tf.flight_id = f.flight_idWHERE b.book_date =

bookings.now()::date - INTERVAL '7 day'WINDOW w AS (

PARTITION BY tf.ticket_noORDER BY f.scheduled_departure);

Задача. Какие сочетания имен и фамилий встречаются ча-ще всего и какую долю от числа всех пассажиров они со-ставляют?

Решение. Оконная функция используется для подсчета об-щего числа пассажиров.

SELECT passenger_name,round( 100.0 * cnt / sum(cnt) OVER (), 2)AS percent

FROM (SELECT passenger_name,

count(*) cntFROM ticketsGROUP BY passenger_name

) tORDER BY percent DESC;

Page 85: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

84v

Задача. Решите предыдущую задачу отдельно для имен иотдельно для фамилий.

Решение. Приведем вариант для имен.

WITH p AS (SELECT left(passenger_name,

position(' ' IN passenger_name))AS passenger_name

FROM tickets)SELECT passenger_name,

round( 100.0 * cnt / sum(cnt) OVER (), 2)AS percent

FROM (SELECT passenger_name,

count(*) cntFROM pGROUP BY passenger_name

) tORDER BY percent DESC;

Вывод такой: не стоит объединять в одном текстовом поленесколько значений, если вы собираетесь работать с ни-ми по отдельности; по-научному это называется «первойнормальной формой».

Массивы

Задача. В билете нет указания, в один ли он конец, илитуда и обратно. Однако это можно вычислить, сравнив пер-вый пункт отправления с последним пунктом назначения.Выведите для каждого билета аэропорты отправления иназначения без учета пересадок, и признак, взят ли билеттуда и обратно.

Page 86: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

85v

Решение. Пожалуй, проще всего свернуть список аэропор-тов на пути следования в массив с помощью агрегатнойфункции array_agg и работать с ним.

В качестве аэропорта назначения для билетов «туда и об-ратно» выбираем средний элемент массива, предполагая,что пути «туда» и «обратно» имеют одинаковое число пе-ресадок.

WITH t AS (SELECT ticket_no,

a,a[1] departure,a[cardinality(a)] last_arrival,a[cardinality(a)/2+1] middle

FROM (SELECT t.ticket_no,

array_agg( f.departure_airportORDER BY f.scheduled_departure) ||

(array_agg( f.arrival_airportORDER BY f.scheduled_departure DESC)

)[1] AS aFROM tickets t

JOIN ticket_flights tfON tf.ticket_no = t.ticket_no

JOIN flights fON f.flight_id = tf.flight_id

GROUP BY t.ticket_no) t

)SELECT t.ticket_no,

t.a,t.departure,CASE

WHEN t.departure = t.last_arrivalTHEN t.middle

ELSE t.last_arrivalEND arrival,(t.departure = t.last_arrival) return_ticket

FROM t;

Page 87: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

86v

В таком варианте таблица билетов просматривается толь-ко один раз. Массив аэропортов выводится исключительнодля наглядности; на большом объеме данных имеет смыслубрать его из запроса, поскольку лишние данные могут нелучшим образом сказаться на производительности.

Задача. Найдите билеты, взятые туда и обратно, в которыхпуть «туда» не совпадает с путем «обратно».

Задача. Найдите такие пары аэропортов, рейсы между ко-торыми в одну и в другую стороны отправляются по разнымдням недели.

Решение. Часть задачи по построению массива дней неде-ли уже фактически решена в представлении routes. Оста-ется только найти пересечение массивов с помощью опе-ратора && и убедиться, что оно пусто:

SELECT r1.departure_airport,r1.arrival_airport,r1.days_of_week dow,r2.days_of_week dow_back

FROM routes r1JOIN routes r2

ON r1.arrival_airport = r2.departure_airportAND r1.departure_airport = r2.arrival_airport

WHERE NOT (r1.days_of_week && r2.days_of_week);

Рекурсивные запросы

Задача. Как с помощью минимального числа пересадокможно долететь из Усть-Кута (UKX) в Нерюнгри (CNN), и ка-кое время придется провести в воздухе?

Решение. Здесь фактически нужно найти кратчайший путьв графе, что делается рекурсивным запросом.

Page 88: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

87v

WITH RECURSIVE p(last_arrival,destination,hops,flights,flight_time,found

) AS (SELECT a_from.airport_code,

a_to.airport_code,array[a_from.airport_code],array[]::char(6)[],interval '0',a_from.airport_code = a_to.airport_code

FROM airports a_from,airports a_to

WHERE a_from.airport_code = 'UKX'AND a_to.airport_code = 'CNN'UNION ALLSELECT r.arrival_airport,

p.destination,(p.hops || r.arrival_airport)::char(3)[],(p.flights || r.flight_no)::char(6)[],p.flight_time + r.duration,bool_or(r.arrival_airport = p.destination)

OVER ()FROM p

JOIN routes rON r.departure_airport = p.last_arrival

WHERE NOT r.arrival_airport = ANY(p.hops)AND NOT p.found

)SELECT hops,

flights,flight_time

FROM pWHERE p.last_arrival = p.destination;

Этот запрос разбирается детально, шаг за шагом, в статьеhabr.com/company/postgrespro/blog/318398, так что здесьдадим только краткие комментарии.

Page 89: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

88v

Зацикливание предотвращается проверкой по массиву пе-ресадок hops, который строится в процессе выполнениязапроса.

Обратите внимание, что поиск происходит «в ширину», тоесть первый же путь, который будет найден, будет кратчай-шим по числу пересадок. Чтобы не перебирать остальныепути (которых может быть очень много и которые заведомодлиннее уже найденного), используется признак «маршрутнайден» (found). Он рассчитывается с помощью оконнойфункции bool_or.

Поучительно сравнить скорость выполнения этого запросас более простым вариантом без флага.

Подробно про рекурсивные запросы можно посмотретьв документации: postgrespro.ru/doc/queries-with.html

Задача. Какое максимальное число пересадок может по-требоваться, чтобы добраться из одного любого аэропортав любой другой?

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

Конечно, так можно поступить, только если графмаршрутовявляется связным, но в нашей демонстрационной базе этодействительно выполняется.

В этом запросе также используется признак «маршрут най-ден», но здесь его необходимо рассчитывать отдельно длякаждой пары аэропортов.

Page 90: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

89v

WITH RECURSIVE p(departure,last_arrival,destination,hops,found

) AS (SELECT a_from.airport_code,

a_from.airport_code,a_to.airport_code,array[a_from.airport_code],a_from.airport_code = a_to.airport_code

FROM airports a_from,airports a_to

UNION ALLSELECT p.departure,

r.arrival_airport,p.destination,(p.hops || r.arrival_airport)::char(3)[],bool_or(r.arrival_airport = p.destination)

OVER (PARTITION BY p.departure,p.destination)

FROM pJOIN routes r

ON r.departure_airport = p.last_arrivalWHERE NOT r.arrival_airport = ANY(p.hops)AND NOT p.found

)SELECT max(cardinality(hops)-1)FROM pWHERE p.last_arrival = p.destination;

Задача. Найдите кратчайший путь, ведущий из Усть-Кута(UKX) в Нерюнгри (CNN), с точки зрения чистого времениперелетов (игнорируя время пересадок).

Подсказка: этот путь может оказаться не оптимальным почислу пересадок.

Page 91: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

90v

Решение на этой и следующей страницах.

WITH RECURSIVE p(last_arrival,destination,hops,flights,flight_time,min_time

) AS (SELECT a_from.airport_code,

a_to.airport_code,array[a_from.airport_code],array[]::char(6)[],interval '0',NULL::interval

FROM airports a_from,airports a_to

WHERE a_from.airport_code = 'UKX'AND a_to.airport_code = 'CNN'UNION ALLSELECT r.arrival_airport,

p.destination,(p.hops || r.arrival_airport)::char(3)[],(p.flights || r.flight_no)::char(6)[],p.flight_time + r.duration,least(

p.min_time,min(p.flight_time+r.duration)FILTER (

WHERE r.arrival_airport = p.destination) OVER ()

)FROM p

JOIN routes rON r.departure_airport = p.last_arrival

WHERE NOT r.arrival_airport = ANY(p.hops)AND p.flight_time + r.duration

< coalesce(p.min_time,INTERVAL '1 year'

))

Page 92: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

91v

SELECT hops,flights,flight_time

FROM (SELECT hops,

flights,flight_time,min(min_time) OVER () min_time

FROM pWHERE p.last_arrival = p.destination

) tWHERE flight_time = min_time;

Функции и расширения

Задача. Найдите расстояние между Калининградом (KGD) иПетропавловском-Камчатским (PKC).

Решение. В таблице airports имеются координаты аэро-портов. Чтобы аккуратно вычислить расстояние междусильно удаленными точками, нужно учесть сферическуюформу Земли. Для этого удобно воспользоваться расши-рением earthdistance (и затем перевести результат измилей в километры).

CREATE EXTENSION IF NOT EXISTS cube;

CREATE EXTENSION IF NOT EXISTS earthdistance;

SELECT round((a_from.coordinates <@> a_to.coordinates) *1.609344

)FROM airports a_from,

airports a_toWHERE a_from.airport_code = 'KGD'AND a_to.airport_code = 'PKC';

Задача. Нарисуйте граф рейсов между аэропортами.

Page 93: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя
Page 94: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

93vi

VI PostgreSQLдля приложения

Отдельный пользователь

В предыдущей главе мы подключались к серверу баз дан-ных под пользователем postgres, единственным существу-ющим сразу после установки СУБД. Но postgres обладаетправами суперпользователя, поэтому приложению не сле-дует использовать его для подключения к базе данных.Лучше создать нового пользователя и сделать его владель-цем отдельной базы данных — тогда его права будут огра-ничены этой базой.

postgres=# CREATE USER app PASSWORD 'p@ssw0rd';

CREATE ROLE

postgres=# CREATE DATABASE appdb OWNER app;

CREATE DATABASE

Подробнее про пользователей и их привилегии смотри-те в документации: postgrespro.ru/doc/user-manag.html иpostgrespro.ru/doc/ddl-priv.html.

Чтобы подключиться к новой базе данных и работать с нейот имени созданного пользователя, выполните:

postgres=# \c appdb app localhost 5432

Page 95: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

94vi

Password for user app: ***You are now connected to database "appdb" as user"app" on host "127.0.0.1" at port "5432".

appdb=>

В команде указываются последовательно имя базы дан-ных (appdb), имя пользователя (app), узел (localhost или127.0.0.1) и номер порта (5432).

Обратите внимание, что в подсказке-приглашении изме-нилось не только имя базы данных: вместо «решетки» те-перь отображается символ «больше». Решетка указываетна роль суперпользователя по аналогии с пользователемroot в операционной системе Unix.

Со своей базой данных пользователь app работает безограничений. Например, в ней можно создать таблицу:

appdb=> CREATE TABLE greeting(s text);

CREATE TABLE

appdb=> INSERT INTO greeting VALUES ('Привет, мир!');

INSERT 0 1

Удаленное подключение

В нашем примере клиент и СУБД находятся на одном и томже компьютере. Разумеется, можно установить PostgreSQLна выделенный сервер, а подключаться к нему с другоймашины (например, с сервера приложений). В этом слу-чае вместо localhost надо указать адрес вашего сервераСУБД. Но этого недостаточно: по умолчанию из соображе-ний безопасности PostgreSQL допускает только локальныеподключения.

Page 96: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

95vi

Чтобы подключиться к базе данных снаружи, необходимоотредактировать два файла.

Во-первых, postgresql.conf — файл основных настроек(обычно располагается в каталоге баз данных). Найдитестроку, определяющую, какие сетевые интерфейсы слуша-ет PostgreSQL:

#listen_addresses = 'localhost'

и замените ее на:

listen_addresses = '*'

Во-вторых, pg_hba.conf—файл с настройками аутентифи-кации. Когда клиент подключается к серверу, в этом файлевыбирается первая сверху строка, соответствующая соеди-нению по четырем параметрам: типу соединения, именибазы данных, имени пользователя и IP-адресу клиента.В той же строке написано, как пользователь должен под-твердить, что он действительно тот, за кого себя выдает.

Например, для ОС Debian и Ubuntu в этом файле, в числепрочих, есть такая настройка (верхняя строка, начинающа-яся с «решетки», считается комментарием):

# TYPE DATABASE USER ADDRESS METHODlocal all all peer

Она говорит, что локальные соединения (local) к любойбазе данных (all) под любым пользователем (all) должныпроверяться методом peer (IP-адрес для локальных соеди-нений, конечно, не указывается).

Метод peer означает, что PostgreSQL запрашивает имя те-кущего пользователя у операционной системы и считает,

Page 97: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

96vi

что ОС уже выполнила необходимую проверку (спросилау пользователя пароль). Поэтому в Linux-подобных опера-ционных системах пользователю обычно не приходитсявводить пароль при подключении к серверу на своем ком-пьютере: достаточно того, что пароль был введен при входев систему.

А вот для Windows локальные соединения не поддержива-ются, и там настройка выглядит следующим образом:

# TYPE DATABASE USER ADDRESS METHODhost all all 127.0.0.1/32 md5

Она означает, что сетевые соединения (host) к любой базеданных (all) под любым пользователем (all) с локальногоадреса (127.0.0.1) должны проверяться методом md5. Этотметод подразумевает ввод пароля пользователем.

Итак, для наших целей допишите в конец pg_hba.conf сле-дующую строку, которая разрешит доступ к базе данныхappdb пользователю app с любого адреса при указанииверного пароля:

host appdb app all md5

После внесения изменений в конфигурационные файлы незабудьте попросить сервер перечитать настройки:

postgres=# SELECT pg_reload_conf();

Подробнее о настройках аутентификации: postgrespro.ru/doc/client-authentication.html.

Page 98: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

97vi

Проверка связи

Для того чтобы подключиться к PostgreSQL из програм-мы, написанной на каком-либо языке программирования,необходимо использовать подходящую библиотеку и уста-новить драйвер СУБД. Обычно драйвер представляет собойобертку для libpq — штатной библиотеки, реализующийклиент-серверный протокол PostgreSQL, — хотя встречают-ся и другие реализации.

Ниже приведены простые примеры кода для несколькихпопулярных языков. Эти примеры помогут вам быстро про-верить соединение с установленной и настроенной базойданных.

Приведенные программы намеренно содержат только ми-нимально необходимый код для выполнения простого за-проса к базе данных и вывода полученного результата;в частности, в них не предусмотрена никакая обработкаошибок. Не стоит рассматривать эти фрагменты как при-мер для подражания.

Если вы используете Windows, для корректного отобра-жения символов национального алфавита вам может по-требоваться в окне Command Prompt сменить шрифт наTrueType (например, «Lucida Console» или «Consolas») и по-менять кодовую страницу. Например, для русского языкавыполните команды:

C:\> chcp 1251

Active code page: 1251

C:\> set PGCLIENTENCODING=WIN1251

Page 99: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

98vi

PHP

В языке PHP работа с PostgreSQL организована с помощьюспециального расширения. В Linux кроме самого PHP нампотребуется пакет с этим расширением:

$ sudo apt-get install php5-cli php5-pgsql

PHP для Windows доступен на сайте windows.php.net/download. Расширение для PostgreSQL уже входит в ком-плект, но в файле php.ini необходимо найти и раскоммен-тировать (убрать точку с запятой) строку:

;extension=php_pgsql.dll

Пример программы (test.php):

<?php$conn = pg_connect('host=localhost port=5432 ' .

'dbname=appdb user=app ' .'password=p@ssw0rd') or die;

$query = pg_query('SELECT * FROM greeting') or die;while ($row = pg_fetch_array($query)) {

echo $row[0].PHP_EOL;}pg_free_result($query);pg_close($conn);

?>

Выполняем:

$ php test.php

Привет, мир!

Расширение для PostgreSQL описано в документации:php.net/manual/ru/book.pgsql.php.

Page 100: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

99vi

Perl

В языке Perl работа с базами данных организована с помо-щью интерфейса DBI. Сам Perl предустановлен в Debian иUbuntu, так что дополнительно нужен только драйвер:

$ sudo apt-get install libdbd-pg-perl

Существует несколько сборок Perl для Windows, которыеперечислены на сайте www.perl.org/get.html. Популярныесборки ActiveState Perl и Strawberry Perl уже включаютнеобходимый для PostgreSQL драйвер.

Пример программы (test.pl):

use DBI;my $conn = DBI->connect(

'dbi:Pg:dbname=appdb;host=localhost;port=5432','app','p@ssw0rd') or die;

my $query = $conn->prepare('SELECT * FROM greeting');$query->execute() or die;while (my @row = $query->fetchrow_array()) {

print @row[0]."\n";}$query->finish();$conn->disconnect();

Выполняем:

$ perl test.pl

Привет, мир!

Интерфейс описан в документации:metacpan.org/pod/DBD::Pg.

Page 101: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

100vi

Python

В языке Python для работы с PostgreSQL обычно исполь-зуется библиотека psycopg (название произносится как«сайко-пи-джи»). В Debian и Ubuntu язык Python версии 2предустановлен, так что нужен только драйвер:

$ sudo apt-get install python-psycopg2

(Если вы используете Python 3, установите вместо этого па-кет python3-psycopg2.)

Python для операционной системы Windows можно взятьс сайта www.python.org. Библиотека psycopg доступна насайте проекта initd.org/psycopg (выберите версию, соответ-ствующую установленной версии Python). Там же находит-ся необходимая документация.

Пример программы (test.py):

import psycopg2conn = psycopg2.connect(

host='localhost',port='5432',database='appdb',user='app',password='p@ssw0rd')

cur = conn.cursor()cur.execute('SELECT * FROM greeting')rows = cur.fetchall()for row in rows:

print(row[0])conn.close()

Выполняем:

$ python test.py

Привет, мир!

Page 102: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

101vi

Java

В языке Java работа с базами данных организована че-рез интерфейс JDBC. Устанавливаем JDK 1.7; дополнительнонам потребуется пакет с драйвером JDBC:

$ sudo apt-get install openjdk-7-jdk

$ sudo apt-get install libpostgresql-jdbc-java

JDK для ОС Windows можно скачать с www.oracle.com/technetwork/java/javase/downloads. Драйвер JDBC досту-пен на сайте jdbc.postgresql.org (выберите версию, котораясоответствует установленной версии JDK). Там же находит-ся и документация.

Пример программы (Test.java):

import java.sql.*;public class Test {

public static void main(String[] args)throws SQLException {

Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/appdb","app", "p@ssw0rd");

Statement st = conn.createStatement();ResultSet rs = st.executeQuery(

"SELECT * FROM greeting");while (rs.next()) {

System.out.println(rs.getString(1));}rs.close();st.close();conn.close();

}}

Компилируем и выполняем программу, указывая в ключепуть к классу-драйверу JDBC (в Windows пути разделяютсяне двоеточием, а точкой с запятой):

Page 103: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

102vi

$ javac Test.java

$ java -cp .:/usr/share/java/postgresql-jdbc4.jar \Test

Привет, мир!

Резервное копирование

Хотя в созданной нами базе данных всего одна таблица,не помешает задуматься и о сохранности данных. Покав вашем приложении немного данных, сделать резервнуюкопию проще всего утилитой pg_dump:

$ pg_dump appdb > appdb.dump

Если вы посмотрите получившийся файл appdb.dump с по-мощью текстового редактора, то обнаружите в нем обыч-ные команды SQL, создающие и заполняющие даннымивсе объекты appdb. Этот файл можно подать на вход psql,чтобы восстановить содержимое базы данных. Например,можно создать новую БД и загрузить данные туда:

$ createdb appdb2

$ psql -d appdb2 -f appdb.dump

Именно в таком виде распространяется демобаза, с кото-рой мы познакомились в предыдущей главе.

У pg_dump много возможностей, с которыми стоит познако-миться: postgrespro.ru/doc/app-pgdump. Некоторые из нихдоступны, только когда данные выгружаются в специаль-ном внутреннем формате; в таком случае для восстановле-ния нужно использовать не psql, а утилиту pg_restore.

Page 104: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

103vi

В любом случае pg_dump выгружает содержимое только од-ной базы данных. Если требуется сделать резервную копиюкластера, включая все базы данных, пользователей и таб-личные пространства, надо воспользоваться другой, хотяи похожей, командой pg_dumpall.

Для больших серьезных проектов требуется продуманнаястратегия периодического резервного копирования. Дляэтого лучше подойдет физическая «двоичная» копия кла-стера, которую создает утилита pg_basebackup:

$ pg_basebackup -D backup

Такая команда создаст резервную копию всего кластерабаз данных в каталоге backup. Чтобы восстановить системуиз созданной копии, достаточно скопировать ее в каталогбаз данных и запустить сервер.

Подробнее про все доступные средства резервного ко-пирования и восстановления смотрите в документации:postgrespro.ru/doc/backup.html, а также в учебном курсеpostgrespro.ru/education/courses/DBA3.

Штатные средства PostgreSQL позволяют сделать практи-чески все, что нужно, однако требуют выполнения много-численных шагов, нуждающихся в автоматизации. Поэтомумногие компании создают собственные инструменты длярезервного копирования и восстановления. Такой инстру-мент — pg_probackup — есть и у нашей компании PostgresProfessional. Он распространяется свободно и позволяетвыполнять инкрементальное резервное копирование науровне страниц, контролировать целостность данных, ра-ботать с большими объемами информации за счет парал-лелизма и сжатия, реализовывать различные стратегии ре-зервного копирования. Полная документация доступна поадресу postgrespro.ru/doc/app-pgprobackup.

Page 105: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

104vi

Что дальше?

Теперь вы готовы к разработке вашего приложения. По от-ношению к базе данных оно всегда будет состоять из двухчастей: серверной и клиентской. Серверная часть — это все,что относится к СУБД: таблицы, индексы, представления,триггеры, хранимые функции. А клиентская — все, что ра-ботает вне СУБД и подключается к ней; с точки зрения базыданных не важно, будет ли это «толстый» клиент или сер-вер приложений.

Важный вопрос, на который нет однозначного правильно-го ответа: где должна быть сосредоточена бизнес-логикаприложения?

Популярен подход, при котором вся логика находится наклиенте, вне базы данных. Особенно часто это происходит,когда команда разработчиков не знакома на детальномуровне с возможностями, предоставляемымиреляционнойСУБД, и предпочитает полагаться на то, что хорошо знает:на прикладной код.

В этом случае СУБД становится неким второстепеннымэлементом приложения и лишь обеспечивает «персистент-ность» данных, их надежное хранение. Часто от СУБД от-гораживаются еще и дополнительным слоем абстракции,например, ORM-ом, который автоматически генерирует за-просы к базе данных из конструкций на языке програм-мирования, привычном разработчикам. Иногда такое ре-шение мотивируют желанием обеспечить переносимостьприложения на любую СУБД.

Подход имеет право на существование; если система, по-строенная таким образом, работает и выполняет возлагае-мые на нее задачи — почему бы нет?

Page 106: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

105vi

Но у этого решения есть и очевидные недостатки:

• Поддержка согласованности данных возлагается наприложение.Вместо того, чтобы поручить СУБД следить за согласо-ванностью данных (а это именно то, чем сильны реля-ционные системы), приложение самостоятельно выпол-няет необходимые проверки. Будьте уверены, что раноили поздно в базу попадут некорректные данные. Этиошибки придется исправлять или учить приложение ра-ботать с ними. А ведь бывают ситуации, когда над однойбазой данных строятся несколько разных приложений:в этом случае обойтись без помощи СУБД просто невоз-можно.

• Производительность оставляет желать лучшего.ORM-системы позволяют в какой-то мере абстрагиро-ваться от СУБД, но качество генерируемых ими SQL-запросов весьма сомнительно. Как правило, выполняет-ся много небольших запросов, каждый из которых сампо себе работает достаточно быстро. Такая схема вы-держивает только небольшие нагрузки на небольшомобъеме данных, и практически не поддается какой-либооптимизации со стороны СУБД.

• Усложняется прикладной код.На прикладном языке программирования невозможносформулировать по-настоящему сложный запрос, ко-торый бы автоматически и адекватно транслировалсяв SQL. Поэтому сложную обработку (если она нужна, ра-зумеется) приходится программировать на уровне при-ложения, предварительно выбирая из базы все необ-ходимые данные. При этом, во-первых, выполняетсялишняя пересылка данных по сети, а во-вторых, такиеалгоритмы, как сканирование, соединение, сортировка

Page 107: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

106vi

или агрегация в СУБД отлаживаются и оптимизируютсядесятилетиями и справятся с задачей гарантированнолучше, чем прикладной код.

Конечно, использование СУБД на полную мощность, с реа-лизацией всех ограничений целостности и логики работыс данными в хранимых функциях, требует вдумчивого изу-чения ее особенностей и возможностей. Потребуется осво-ить язык SQL для написания запросов и какой-либо языксерверного программирования (обычно PL/pgSQL) для на-писания функций и триггеров. Взамен вы овладеете надеж-ным инструментом, одним из важных «кубиков» в архитек-туре любой информационной системы.

Так или иначе, вопрос о том, где разместить бизнес-логи-ку — на сервере или на клиенте — вам придется для себярешить. Добавим только, что крайности нужны не всегда ичасто истину стоит искать где-то посередине.

Page 108: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

VII Настройка PostgreSQL

Основные настройки

Конфигурационные параметры PostgreSQL по умолчаниюимеют значения, которые позволяют запустить сервер налюбом самом слабом «железе». Но чтобы СУБД работалаэффективно, ее нужно сконфигурировать с учетом как фи-зических характеристик сервера, так и профиля нагрузкиприложения.

Здесь мы рассмотрим только несколько самых основныхнастроек, которым совершенно точно необходимо уделитьвнимание, если СУБД используется для реальной работы.Тонкая настройка под конкретное приложение требует до-полнительных знаний, которые, например, можно получитьиз курсов по администрированию PostgreSQL (см. с. 153).

Как изменять конфигурационные параметры

Чтобы изменить значение конфигурационного параметра,откройте файл postgresql.conf и либо найдите в нем нуж-ный параметр и исправьте его значение, либо добавьтеновую строку в конец файла — она будет иметь приори-тет над значением, которое устанавливалось выше в томже файле.

Page 109: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

108vii

После изменений необходимо сигнализировать серверуперечитать настройки:

postgres=# SELECT pg_reload_conf();

После этого проверьте текущее значение параметра коман-дой SHOW. Если значение не изменилось, скорее всего приредактировании файла была допущена ошибка; заглянитев журнал сообщений сервера.

Наиболее важные параметры

Одни из наиболее важных параметров определяют, какPostgreSQL распоряжается оперативной памятью.

Параметр shared_buffers задает размер буферного кэша,который используется для того, чтобы работа с наиболеечасто используемыми данными происходила в оператив-ной памяти и не требовала избыточных обращений к диску.Настройку можно начинать с 25% от общего объема ОЗУсервера. Изменение этого параметра вступает в силу толь-ко после перезагрузки сервера!

Значение параметра effective_cache_size не влияет на вы-деление памяти, но подсказывает PostgreSQL, на какой об-щий размер кэша рассчитывать, включая кэш операцион-ной системы. Чем выше это значение, тем большее пред-почтение отдается индексам. Начать можно с 50–75% отобъема ОЗУ.

Параметр work_mem определяет объем памяти, выделя-емый для выполнения таких операций, как сортировкаили построение хеш-таблиц при выполнении соединения.

Page 110: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

109vii

Признаком того, что памяти недостаточно, является актив-ное использование временных файлов и, как следствие,уменьшение производительности. Значение по умолчанию4 МБ в большинстве случаев стоит увеличить как минимумв несколько раз, но так, чтобы не выйти при этом за общийразмер оперативной памяти сервера.

Параметр maintenance_work_mem определяет размер па-мяти, выделяемый служебным процессам. Его увеличе-ние может ускорить построение индексов, работу процес-са очистки (vacuum). Обычно устанавливается значение,в несколько раз превышающее значения work_mem.

Например, при ОЗУ 32 ГБ можно начать с настройки:

shared_buffers = '8GB'effective_cache_size = '24GB'work_mem = '128MB'maintenance_work_mem = '512MB'

Отношение значений двух параметров random_page_cost иseq_page_cost должно соответствовать отношению скоро-стей произвольного и последовательного доступа к диску.По умолчанию предполагается, что произвольный доступв 4 раза медленнее последовательного в расчете на обыч-ные HDD-диски. Но для дисковых массивов и SSD-дисковзначение random_page_cost надо уменьшить (но никогдане изменяйте значение seq_page_cost, равное 1).

Например, для дисков SSD будет адекватна настройка:

random_page_cost = 1.2

Очень ответственной является настройка автоочистки(autovacuum). Этот процесс занимается «сборкой мусора»

Page 111: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

110vii

и выполняет ряд других важных для системы задач. На-стройка существенно зависит от конкретного приложенияи нагрузки, которую оно создает, но в большинстве случаевможно начать со следующего:

• уменьшить значение autovacuum_vacuum_scale_factorдо 0.01, чтобы очистка выполнялась чаще и меньшимипорциями;

• увеличить значение autovacuum_vacuum_cost_limit (ли-бо уменьшить autovacuum_vacuum_cost_delay) в 10 раз,чтобы очистка выполнялась быстрее (для версий до 12).

Не менее важной является настройка процессов, связан-ных с обслуживанием буферного кэша и журнала предза-писи, но и она зависит от конкретного приложения. Нач-ните с установки checkpoint_completion_target = 1 (чтобысгладить нагрузку), увеличения checkpoint_timeout с 5 ми-нут до 30 (чтобы уменьшить накладные расходы на выпол-нение контрольных точек) и пропорционального увеличе-ния max_wal_size (с той же целью).

Тонкости настройки различных параметров подробно рас-сматриваются в учебном курсе DBA2 (с. 157).

Настройка подключения

Этот вопрос мы уже рассматривали в главе «PostgreSQLдля приложения» на с. 93. Напомним, что обычно требу-ется установить параметр listen_addresses в значение ’*’и добавить разрешение на подключение в конфигурацион-ный файл pg_hba.conf.

Page 112: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

111vii

Вредные советы

Можно встретить советы по увеличению быстродействия,к которым ни в коем случае нельзя прислушиваться:

• Выключение автоочистки (autovacuum = off).

Такая «экономия» ресурсов действительно даст кратко-временный незначительный выигрыш в производитель-ности, но приведет к накоплению «мусора» в данныхи росту таблиц и индексов. Через некоторое время СУБДперестанет нормально функционировать. Автоочисткунужно не отключать, а правильно настраивать.

• Выключение синхронизации с диском (fsync = off).

Отключение действительно приведет к существенномуускорению работы, но любой сбой сервера (будь то про-граммный или аппаратный) приведет к полной потеребаз данных. Восстановить систему можно будет толькоиз резервной копии (если, конечно, она есть).

PostgreSQL и 1С

1С официально поддерживает работу с PostgreSQL. Это от-личная возможность сэкономить на дорогих лицензиях накоммерческие СУБД.

Как и любое другое приложение, продукты 1С будут рабо-тать эффективнее, если PostgreSQL правильно сконфигури-рован. Кроме того, есть ряд параметров, специфических иобязательных для работы 1С.

Page 113: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

112vii

Далее приведены рекомендации по установке и первона-чальной настройке, которые помогут вам быстро присту-пить к работе.

Выбор версии и платформы

Для работы с 1С требуется версия PostgreSQL со специ-альными патчами. Такую версию можно взять на сайте1С releases.1c.ru, а можно использовать СУБД Postgres ProStandard или Postgres Pro Enterprise, которые тоже включа-ют необходимые патчи.

PostgreSQL работает и на Windows, но если есть возмож-ность выбора, то стоит отдать предпочтение ОС семействаLinux.

Перед установкой следует решить, необходим ли выделен-ный сервер для базы данных. Выделенный сервер болеепроизводителен за счет распределения нагрузки междусервером приложений и сервером базы данных.

Параметры конфигурации

Физические характеристики сервера должны соответство-вать предполагаемой нагрузке. В качестве примерного ори-ентира можно привести следующие данные. Выделенный8-ядерный сервер с ОЗУ 8 ГБ и дисковой подсистемойс RAID1 SSD должен справится с объемом базы в пределах100 ГБ, общим количеством пользователей до 50 человек,количеством документов до 2000 в день. Если сервер неявляется выделенным, то соответствующее количество ре-сурсов общего сервера должно быть свободно для нуждPostgreSQL.

Page 114: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

113vii

Исходя из общих рекомендаций, приведенных выше, и зна-ния специфики приложений 1С, для такого сервера мы ре-комендуем следующие начальные настройки:

# Обязательные для 1С настройкиstandard_conforming_strings = offescape_string_warning = offshared_preload_libraries = 'online_analyze, plantuner'plantuner.fix_empty_table = ononline_analyze.enable = ononline_analyze.table_type = 'temporary'online_analyze.local_tracking = ononline_analyze.verbose = off

# Параметры, зависящие от объема оперативной памятиshared_buffers = '2GB' # 25% ОЗУeffective_cache_size = '6GB' # 75% ОЗУwork_mem = '64MB' # 64-128MBmaintenance_work_mem = '256MB' # 4*work_mem# активная работа с временными таблицамиtemp_buffers = '32MB' # 32-128MB

# Требуется больше блокировок, чем 64 по умолчаниюmax_locks_per_transaction = 256

Настройка подключения

Параметр listen_addresses в файле postgresql.conf дол-жен быть установлен в значение ’*’.

В начало конфигурационного файла pg_hba.conf необ-ходимо добавить следующую строку, заменив «IP-адрес-сервера-1С» на конкретный адрес и маску подсети:

host all all IP-адрес-сервера-1С md5

После перезапуска PostgreSQL все изменения из файловpostgresql.conf и pg_hba.conf вступят в силу и сервербудет готов к подключению 1С.

Page 115: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

114vii

Для подключения 1С использует суперпользовательскуюроль, обычно это postgres. Установите для нее пароль:

postgres=# ALTER ROLE postgres PASSWORD 'p@ssw0rd';

ALTER ROLE

В настройках информа-ционной базы 1С ука-жите в качестве сер-вера базы данных IP-адрес и порт сервераPostgreSQL и выберитетип СУБД «PostgeSQL».Укажите название ба-зы данных, которая бу-дет использоваться для1С, и поставьте флажок«Создать базу данныхв случае ее отсутствия»(создавать базу данныхсредствами PostgreSQLне нужно). Укажите имяи пароль суперпользовательской роли, которая будет ис-пользоваться для подключения.

Приведенные советы позволяют быстро начать работу иподходят в большинстве случаев, хотя, конечно, не даютстопроцентной гарантии требуемого уровня производи-тельности.

Выражаем благодарность Антону Дорошкевичу из компа-нии Инфософт за помощь в подготовке этого материала.

Page 116: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

VIII pgAdmin

pgAdmin — популярное графическое средство для админи-стрирования PostgreSQL. Программа упрощает основныезадачи администрирования, отображает объекты баз дан-ных, позволяет выполнять запросы SQL.

Долгое время стандартом де-факто являлся pgAdmin 3, од-нако разработчики из EnterpriseDB прекратили его под-держку и в 2016 году выпустили новую, четвертую, версию,полностью переписав продукт с языка C++ на Python и веб-технологии. Из-за изменившегося интерфейса pgAdmin 4поначалу был встречен достаточно прохладно, но продол-жает разрабатываться и совершенствоваться.

Установка

Чтобы запустить pgAdmin 4 на Windows, воспользуйтесьустановщиком на странице www.pgadmin.org/download/.Процесс установки прост и очевиден, все предлагаемыезначения можно оставить без изменений.

Для Debian и Ubuntu подключите репозиторий PostgreSQL(как описано на с. 33) и выполните команду

$ sudo apt-get install pgadmin4

Page 117: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

116viii

В списке доступных программ появится «pgAdmin4».

Пользовательский интерфейс программы полностью пе-реведен на русский язык нашей компанией. Чтобы сме-нить язык, нажмите значок Настроить pgAdmin (ConfigurepgAdmin) и в окне настроек выберите Разное→ Язык поль-зователя (Miscellaneous → User language). Затем переза-грузите страницу в веб-браузере.

Подключение к серверу

В первую очередь настроим подключение к серверу. На-жмите на значок Добавить новый сервер (Add New Server)и в появившемся окне на вкладке Общие (General) введитепроизвольное имя (Name) для соединения.

На вкладке Соединение (Connection) введите имя сер-вера (Host name/address), порт (Port), имя пользователя(Username) и пароль (Password).

Если не хотите вводить пароль каждый раз вручную, от-метьте флажок Сохранить пароль (Save password). Паролихранятся зашифрованными с помощью мастер-пароля, ко-торый pgAdmin попросит вас задать при первом запуске.

Обратите внимание, что у пользователя должен быть уста-новлен пароль. Например, для postgres это можно сделатьследующей командой:

postgres=# ALTER ROLE postgres PASSWORD 'p@ssw0rd';

При нажатии на кнопку Сохранить (Save) программа про-верит доступность сервера с указанными параметрами изапомнит новое подключение.

Page 118: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

117viii

Навигатор

В левой части окна находится навигатор объектов. Разво-рачивая пункты списка, вы можете спуститься до сервера,который мы назвали LOCAL. Ниже будут перечислены име-ющиеся в нем базы данных:

• appdb мы создали для проверки подключения к Post-greSQL из разных языков программирования;

• demo — демонстрационная база данных;

• postgres всегда создается при установке СУБД;

• test мы использовали, когда знакомились с SQL.

Page 119: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

118viii

Развернув пункт Схемы (Schemas) для базы данных demo,можно обнаружить все таблицы, посмотреть их столбцы,ограничения целостности, индексы, триггеры и т. п.

Для каждого типа объекта в контекстном меню (по правойкнопке мыши) приведен список действий, которые с нимможно совершить. Например, выгрузить в файл или загру-зить из файла, выдать привилегии, удалить.

В правой части окна на отдельных вкладках выводитсясправочная информация:

• Панель информации (Dashboard) — показывает графи-ки, отражающие активность системы;

• Свойства (Properties) — свойства выбранного объекта(для столбца будет показан тип его данных и т. п.);

• SQL — команда SQL для создания выбранного в навига-торе объекта;

Page 120: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

119viii

• Статистика (Statistics) — информация, которая исполь-зуется оптимизатором для построения планов выпол-нения запросов и может рассматриваться администра-тором СУБД для анализа ситуации;

• Зависимости, Зависимые (Dependencies, Dependents)показывают зависимости между выбранным объектоми другими объектами в базе данных.

Выполнение запросов

Чтобы выполнить запрос, откройте новую вкладку с окномSQL, выбрав в меню Инструменты — Запросник (Tools —Query tool).

Введите запрос в верхней части окна и нажмите F5. В ниж-ней части окна на вкладке Результат (Data Output) появитсярезультат запроса.

Page 121: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

120viii

Вы можете вводить следующий запрос на новой строке, нестирая предыдущий; просто выделите нужныйфрагмент ко-да перед тем, как нажимать F5. Таким образом история ва-ших действий всегда будет у вас перед глазами — обычноэто удобнее, чем искать нужный запрос в истории командна вкладке История запросов (Query History).

Другое

Программа pgAdmin предоставляет графический интер-фейс для стандартных утилит PostgreSQL, информации си-стемного каталога, административных функций и командSQL. Особо отметим встроенный отладчик PL/pgSQL-кода.Со всеми возможностями этой программы вы можете по-знакомиться на сайте продукта www.pgadmin.org, либов справочной системе самой программы.

Page 122: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

IX Дополнительныевозможности

Полнотекстовый поиск

Несмотря на мощь языка запросов SQL, его возможностейне всегда достаточно для эффективной работы с данными.Особенно это стало заметно в последнее время, когда лави-ны данных, обычно плохо структурированных, заполнилихранилища информации. Изрядная доля Больших Данныхприходится на тексты, плохо поддающиеся разбиению наполя баз данных. Поиск документов на естественных язы-ках, обычно с сортировкой результатов по релевантностипоисковому запросу, называют полнотекстовым поиском.В самом простом и типичном случае запросом считаетсянабор слов, а соответствие определяется частотой словв документе. Примерно таким поиском мы занимаемся, на-бирая фразу в поисковике Google или Яндекс.

Существует большое количество поисковиков, как платных,так и бесплатных, которые позволяют индексировать всювашу коллекцию документов и организовать вполне ка-чественный поиск. В этих случаях индекс — важнейшийинструмент и ускоритель поиска — не является частью ба-зы данных. А это значит, что такие ценимые пользовате-лями СУБД особенности, как синхронизация содержимого

Page 123: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

122ix

БД, транзакционность, доступ к метаданным и использо-вание их для ограничения области поиска, организациябезопасной политики доступа к документам и многое дру-гое, оказываются недоступны.

Недостатки у все более популярных документо-ориентиро-ванных СУБД обычно в той же области: у них есть развитыесредства полнотекстового поиска, но безопасность и за-боты о синхронизации для них не приоритетны. К томуже обычно они (MongoDB, например) принадлежат классуNoSQL СУБД, а значит по определению лишены всей деся-тилетиями накопленной мощи SQL.

С другой стороны традиционные SQL-СУБД имеют встро-енные средства текстового поиска. Оператор LIKE входитв стандартный синтаксис SQL, но гибкость его явно недоста-точна. В результате производителям СУБД приходилось до-бавлять собственные расширения к стандарту SQL. У Post-greSQL это операторы сравнения ILIKE, ~, ~*, но и они нерешают всех проблем, так как не умеют учитывать грамма-тические вариации слов, не приспособлены для ранжиро-вания и не слишком быстро работают.

Если говорить об инструментах собственно полнотекстово-го поиска, то важно понимать, что до их стандартизациипока далеко, в каждой реализации СУБД свой синтаксис исвои подходы. В этом контексте российский пользовательPostgreSQL получает немалые преимущества: расширенияполнотекстового поиска для этой СУБД созданы россий-скими разработчиками, поэтому возможность прямого кон-такта со специалистами или даже посещение их лекцийпоможет углубиться в технологические детали, если в этомвозникнет потребность. Здесь же мы ограничимся просты-ми примерами.

Page 124: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

123ix

Для изучения возможностей полнотекстового поиска со-здадим еще одну таблицу в демонстрационной базе дан-ных. Пусть это будут наброски конспекта лекций препода-вателя курсов, разбитые на главы-лекции:

test=# CREATE TABLE course_chapters(c_no text REFERENCES courses(c_no),ch_no text,ch_title text,txt text,CONSTRAINT pkt_ch PRIMARY KEY(ch_no, c_no)

);

CREATE TABLE

Введем в таблицу тексты первых лекций по знакомым намспециальностям CS301 и CS305:

test=# INSERT INTO course_chapters(c_no, ch_no,ch_title, txt)

VALUES('CS301', 'I', 'Базы данных','С этой главы начинается наше знакомство ' ||'с увлекательным миром баз данных'),

('CS301', 'II', 'Первые шаги','Продолжаем знакомство с миром баз данных. ' ||'Создадим нашу первую текстовую базу данных'),

('CS305', 'I', 'Локальные сети','Здесь начнется наше полное приключений ' ||'путешествие в интригующий мир сетей');

INSERT 0 3

Проверим результат:

test=# SELECT ch_no AS no, ch_title, txtFROM course_chapters \gx

Page 125: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

124ix

-[ RECORD 1 ]-----------------------------------------no | Ich_title | Базы данныхtxt | С этой главы начинается наше знакомство с

увлекательным миром баз данных

-[ RECORD 2 ]-----------------------------------------no | IIch_title | Первые шагиtxt | Продолжаем знакомство с миром баз данных.

Создадим нашу первую текстовую базу данных-[ RECORD 3 ]-----------------------------------------no | Ich_title | Локальные сетиtxt | Здесь начнется наше полное приключений

путешествие в интригующий мир сетей

Найдем в таблице информацию по базам данных традици-онными средствами SQL, используя оператор LIKE:

test=# SELECT txtFROM course_chaptersWHERE txt LIKE '%базы данных%' \gx

Мы получим предсказуемый ответ: 0 строк. Ведь LIKE незнает, что в родительном падеже следует искать «баз дан-ных» или «базу данных» в творительном. Запрос

test=# SELECT txtFROM course_chaptersWHERE txt LIKE '%базу данных%' \gx

выдаст строку из главы II (но не из главы I, где база в другомпадеже):

-[ RECORD 1 ]-----------------------------------------txt | Продолжаем знакомство с миром баз данных.

Создадим нашу первую текстовую базу данных

Page 126: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

125ix

В PostgreSQL есть оператор ILIKE, который позволяет незаботиться о регистрах, а то бы пришлось еще думать ио прописных и строчных буквах. Конечно, в распоряжениизнатока SQL есть и регулярные выражения (шаблоны поис-ка), составление которых занятие увлекательное, сродниискусству. Но когда не до искусства, хочется иметь инстру-мент, который думал бы за тебя.

Поэтому мы добавим к таблице глав еще один столбец соспециальным типом данных — tsvector:

test=# ALTER TABLE course_chaptersADD txtvector tsvector;

test=# UPDATE course_chaptersSET txtvector = to_tsvector('russian',txt);

test=# SELECT txtvectorFROM course_chapters \gx

-[ RECORD 1 ]-----------------------------------------txtvector | 'баз':10 'глав':3 'дан':11 'знакомств':6

'мир':9 'начина':4 'наш':5 'увлекательн':8-[ RECORD 2 ]-----------------------------------------txtvector | 'баз':5,11 'дан':6,12 'знакомств':2

'мир':4 'наш':8 'перв':9 'продолжа':1'создад':7 'текстов':10

-[ RECORD 3 ]-----------------------------------------txtvector | 'интриг':8 'мир':9 'начнет':2 'наш':3

'полн':4 'приключен':5 'путешеств':6'сет':10

Мы видим, что в строках:

1. слова сократились до своих неизменяемых частей(лексем),

2. появились цифры, означающие позицию вхожденияслова в текст (видно, что некоторые слова вошли двараза),

Page 127: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

126ix

3. в строку не вошли предлоги (а также не вошли бысоюзы и прочие не значимые для поиска единицыпредложения — так называемые стоп-слова).

Для более продвинутого поиска нам хотелось бы включитьв поисковую область и названия глав. Причем, дабы под-черкнуть их важность, мы наделим их весом при помощифункции setweight. Поправим таблицу:

test=# UPDATE course_chaptersSET txtvector =

setweight(to_tsvector('russian',ch_title),'B')|| ' ' ||setweight(to_tsvector('russian',txt),'D');

UPDATE 3

test=# SELECT txtvectorFROM course_chapters \gx

-[ RECORD 1 ]-----------------------------------------txtvector | 'баз':1B,12 'глав':5 'дан':2B,13

'знакомств':8 'мир':11 'начина':6 'наш':7'увлекательн':10

-[ RECORD 2 ]-----------------------------------------txtvector | 'баз':7,13 'дан':8,14 'знакомств':4

'мир':6 'наш':10 'перв':1B,11 'продолжа':3'создад':9 'текстов':12 'шаг':2B

-[ RECORD 3 ]-----------------------------------------txtvector | 'интриг':10 'локальн':1B 'мир':11

'начнет':4 'наш':5 'полн':6 'приключен':7'путешеств':8 'сет':2B,12

У лексем появился относительный вес — B и D (из четырехвозможных — A, B, C, D). Реальный вес мы будем задаватьпри составлении запросов. Это придаст им дополнитель-ную гибкость.

Во всеоружии вернемся к поиску. Функции to_tsvector

симметрична функция to_tsquery, приводящая символь-ное выражение к типу данных tsquery, который использу-ют в запросах.

Page 128: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

127ix

test=# SELECT ch_titleFROM course_chaptersWHERE txtvector @@

to_tsquery('russian','базы & данные');

ch_title-------------Базы данныхПервые шаги

(2 rows)

Можно убедиться, что поисковый запрос 'база & данных'

и другие его грамматические вариации дадут тот же ре-зультат. Мы использовали оператор сравнения @@ (две со-баки), выполняющий работу, аналогичную LIKE. Синтаксисоператора не допускает выражение естественного языкас пробелами, такие как «база данных», поэтому слова со-единяются логическим оператором «и».

Аргумент russian указывает на конфигурацию, которую ис-пользует СУБД. Она определяет подключаемые словари ипарсер, разбивающий фразу на отдельные лексемы.

Словари, несмотря на такое название, позволяют выпол-нять любые преобразования лексем. Например, простойсловарь-стеммер типа snowball, используемый по умол-чанию, оставляет от слова только неизменяемую часть —именно поэтому поиск игнорирует окончания слов в запро-се. Можно подключать и другие, например

• «обычные» словари, такие как ispell, myspell илиhunspell, для более точного учета морфологии;

• словари синонимов;• тезаурус;• unaccent, чтобы превратить букву «ё» в «е».

Введенные нами веса позволяют вывести записи по резуль-татам рейтинга:

Page 129: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

128ix

test=# SELECT ch_title,ts_rank_cd('{0.1, 0.0, 1.0, 0.0}', txtvector, q)

FROM course_chapters,to_tsquery('russian','базы & данных') q

WHERE txtvector @@ qORDER BY ts_rank_cd DESC;

ch_title | ts_rank_cd-------------+------------Базы данных | 1.11818Первые шаги | 0.22

(2 rows)

Массив {0.1, 0.0, 1.0, 0.0} задает веса. Это не обязательныйаргумент функции ts_rank_cd, по умолчанию массив {0.1,0.2, 0.4, 1.0} соответствует D, C, B, A. Вес слова влияет назначимость найденной строки.

В заключительном эксперименте модифицируем выдачу.Будем считать, что найденные слова мы хотим выделитьжирным шрифтом в странице html. Функция ts_headlineзадает наборы символов, обрамляющих слово, а также ми-нимальное и максимальное количество слов в строке:

test=# SELECT ts_headline('russian',txt,to_tsquery('russian', 'мир'),'StartSel=<b>, StopSel=</b>, MaxWords=50, MinWords=5'

)FROM course_chaptersWHERE to_tsvector('russian', txt) @@

to_tsquery('russian', 'мир');

-[ RECORD 1 ]-----------------------------------------ts_headline | знакомство с увлекательным <b>миром</b>

баз данных-[ RECORD 2 ]-----------------------------------------ts_headline | <b>миром</b> баз данных. Создадим нашу-[ RECORD 3 ]-----------------------------------------ts_headline | путешествие в интригующий <b>мир</b>

сетей

Page 130: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

129ix

Для ускорения полнотекстового поиска используются спе-циальные индексы GiST, GIN и RUM, отличные от обычныхиндексов в базах данных. Но они, как и многие другиеполезные знания о полнотекстовом поиске, останутся внерамок этого краткого руководства.

Более подробно о полнотекстовом поиске можно прочи-тать в документации PostgreSQL: www.postgrespro.ru/doc/textsearch.html.

Работа с JSON и JSONB

Реляционные базы данных, использующие SQL, создава-лись с большим запасом прочности: первой заботой ихпотребителей была целостность и безопасность данных,а объемы информации были несравнимы с современными.Когда появилось новое поколение СУБД — NoSQL, сообще-ство призадумалось: куда более простая структура данных(вначале это были прежде всего огромные таблицы с все-го двумя колонками: ключ-значение) позволяла ускоритьпоиск на порядки. Они могли обрабатывать небывалыеобъемы информации и легко масштабировались, вовсю ис-пользуя параллельные вычисления. В NoSQL-базах не былонеобходимости хранить информацию по строкам, а хране-ние по столбцам для многих задач позволяло еще большеускорить и распараллелить вычисления.

Когда прошел первый шок, стало понятно, что для боль-шинства реальных задач простой структурой не обойтись.Стали появляться сложные ключи, потом группы ключей.Реляционные СУБД не желали отставать от жизни и началидобавлять возможности, типичные для NoSQL.

Page 131: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

130ix

Поскольку в реляционных СУБД изменение схемы данныхсвязано с большими издержками, оказался как никогдакстати новый тип данных — JSON. Изначально он пред-назначался для JS-программистов, в том числе для AJAX-приложений, отсюда JS в названии. Он как бы брал слож-ность добавляемых данных на себя, позволяя создаватьлинейные и иерархические структуры-объекты, добавле-ние которых не требовало пересчета всей базы.

Тем, кто делал приложения, уже не было необходимостимодифицировать схему базы данных. Синтаксис JSON по-хож на XML своим строгим соблюдением иерархии данных.JSON достаточно гибок для того, чтобы работать с разнород-ной, иногда непредсказуемой структурой данных.

Допустим, в нашей демобазе студентов появилась возмож-ность ввести личные данные: запустили анкету, расспро-сили преподавателей. В анкете не обязательно заполнятьвсе пункты, а некоторые из них включают графу «другое»и «добавьте о себе данные по вашему усмотрению».

Если бы мы добавили в базу новые данные в привычнойманере, то в многочисленных появившихся столбцах илидополнительных таблицах было бы большое количествопустых полей. Но еще хуже то, что в будущеммогут появить-ся новые столбцы, а тогда придется существенно переде-лывать всю базу.

Мы решим эту проблему, используя тип json и появивший-ся позже jsonb, в котором данные хранятся в экономичномбинарном виде, и который, в отличие от json, приспособ-лен к созданию индексов, ускоряющих поиск иногда напорядки.

Page 132: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

131ix

Создадим таблицу с объектами JSON:

test=# CREATE TABLE student_details(de_id int,s_id int REFERENCES students(s_id),details json,CONSTRAINT pk_d PRIMARY KEY(s_id, de_id)

);

test=# INSERT INTO student_details(de_id, s_id, details)

VALUES(1, 1451,'{ "достоинства": "отсутствуют",

"недостатки":"неумеренное употребление мороженого"

}'),(2, 1432,'{ "хобби":

{ "гитарист":{ "группа": "Постгрессоры",

"гитары":["страт","телек"]}

}}'),(3, 1556,'{ "хобби": "косплей",

"достоинства":{ "мать-героиня":

{ "Вася": "м","Семен": "м","Люся": "ж","Макар": "м","Саша":"сведения отсутствуют"

}}

}'),(4, 1451,'{ "статус": "отчислена"}');

Page 133: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

132ix

Проверим, все ли данные на месте. Для удобства соеди-ним таблицы student_details и students при помощиконструкции WHERE, ведь в новой таблице отсутствуют име-на студентов:

test=# SELECT s.name, sd.detailsFROM student_details sd, students sWHERE s.s_id = sd.s_id\gx

-[ RECORD 1 ]--------------------------------------name | Аннаdetails | { "достоинства": "отсутствуют", +

| "недостатки": +| "неумеренное употребление мороженого" +| }

-[ RECORD 2 ]--------------------------------------name | Викторdetails | { "хобби": +

| { "гитарист": +| { "группа": "Постгрессоры", +| "гитары":["страт","телек"] +| } +| } +| }

-[ RECORD 3 ]--------------------------------------name | Нинаdetails | { "хобби": "косплей", +

| "достоинства": +| { "мать-героиня": +| { "Вася": "м", +| "Семен": "м", +| "Люся": "ж", +| "Макар": "м", +| "Саша":"сведения отсутствуют" +| } +| } +| }

-[ RECORD 4 ]--------------------------------------name | Аннаdetails | { "статус": "отчислена" +

| }

Page 134: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

133ix

Допустим, нас интересуют записи, содержащие информа-цию о достоинствах студентов. Мы можем обратиться к со-держанию ключа «достоинство», используя специальныйоператор ->>:

test=# SELECT s.name, sd.detailsFROM student_details sd, students sWHERE s.s_id = sd.s_idAND sd.details ->> 'достоинства' IS NOT NULL\gx

-[ RECORD 1 ]--------------------------------------name | Аннаdetails | { "достоинства": "отсутствуют", +

| "недостатки": +| "неумеренное употребление мороженого" +| }

-[ RECORD 2 ]--------------------------------------name | Нинаdetails | { "хобби": "косплей", +

| "достоинства": +| { "мать-героиня": +| { "Вася": "м", +| "Семен": "м", +| "Люся": "ж", +| "Макар": "м", +| "Саша":"сведения отсутствуют" +| } +| } +| }

Мы убедились, что две записи имеют отношение к достоин-ствам Анны и Нины, однако такой ответ нас вряд ли удов-летворит: на самом деле достоинства Анны «отсутствуют».Скорректируем запрос:

test=# SELECT s.name, sd.detailsFROM student_details sd, students sWHERE s.s_id = sd.s_idAND sd.details ->> 'достоинства' IS NOT NULLAND sd.details ->> 'достоинства' != 'отсутствуют';

Page 135: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

134ix

Убедитесь, что этот запрос оставит в списке только Нину,обладающую реальными, а не отсутствующими достоин-ствами.

Но такой способ срабатывает не всегда. Попробуем найти,на каких гитарах играет музыкант Витя:

test=# SELECT sd.de_id, s.name, sd.detailsFROM student_details sd, students sWHERE s.s_id = sd.s_idAND sd.details ->> 'гитары' IS NOT NULL\gx

Запрос ничего не выдаст. Дело в том, что соответствующаяпара ключ-значение находится внутри иерархии JSON, вло-жена в пары более высокого уровня:

name | Викторdetails | { "хобби": +

| { "гитарист": +| { "группа": "Постгрессоры", +| "гитары":["страт","телек"] +| } +| } +| }

Чтобы добраться до гитар, воспользуемся оператором #>

и спустимся с «хобби» вниз по иерархии:

test=# SELECT sd.de_id, s.name,sd.details #> '{хобби,гитарист,гитары}'

FROM student_details sd, students sWHERE s.s_id = sd.s_idAND sd.details #> '{хобби,гитарист,гитары}'

IS NOT NULL\gx

Page 136: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

135ix

и убедимся, что Виктор фанат фирмы Fender:

de_id | name | ?column?-------+--------+-------------------

2 | Виктор | ["страт","телек"]

У типа данных json есть младший брат jsonb. Буква «b»подразумевает бинарный (а не текстовый) способ хране-ния данных. Такие данные можно плотно упаковать и поискпо ним работает быстрее. Последнее время jsonb исполь-зуется намного чаще, чем json.

test=# ALTER TABLE student_detailsADD details_b jsonb;

test=# UPDATE student_detailsSET details_b = to_jsonb(details);

test=# SELECT de_id, details_bFROM student_details \gx

-[ RECORD 1 ]--------------------------------------de_id | 1details_b | {"недостатки": "неумеренное

употребление мороженого","достоинства": "отсутствуют"}

-[ RECORD 2 ]--------------------------------------de_id | 2details_b | {"хобби": {"гитарист": {"гитары":

["страт", "телек"], "группа":"Постгрессоры"}}}

-[ RECORD 3 ]--------------------------------------de_id | 3details_b | {"хобби": "косплей", "достоинства":

{"мать-героиня": {"Вася": "м", "Люся":"ж", "Саша": "сведения отсутствуют","Макар": "м", "Семен": "м"}}}

-[ RECORD 4 ]--------------------------------------de_id | 4details_b | {"статус": "отчислена"}

Page 137: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

136ix

Можно заметить, что, кроме иной формы записи, изменил-ся порядок значений в парах: Саша, сведения о которой,как мы помним, отсутствуют, заняла теперь место в спис-ке перед Макаром. Это не недостаток jsonb относительноjson, а особенность хранения информации.

Для работы с jsonb набор операторов больше. Один изполезнейших операторов — оператор вхождения в объект@>. Он напоминает #> для json.

Например, найдем запись, где упоминается дочь матери-героини Люся:

test=# SELECT s.name,jsonb_pretty(sd.details_b) json

FROM student_details sd, students sWHERE s.s_id = sd.s_idAND sd.details_b @>

'{"достоинства":{"мать-героиня":{}}}'\gx

-[ RECORD 1 ]-------------------------------------name | Нинаjson | { +

| "хобби": "косплей", +| "достоинства": { +| "мать-героиня": { +| "Вася": "м", +| "Люся": "ж", +| "Саша": "сведения отсутствуют",+| "Макар": "м", +| "Семен": "м" +| } +| } +| }

Мы использовали функцию jsonb_pretty(), которая фор-матирует вывод типа jsonb.

Page 138: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

137ix

Или можно воспользоваться функцией jsonb_each(), раз-ворачивающей пары ключ-значение:

test=# SELECT s.name,jsonb_each(sd.details_b)

FROM student_details sd, students sWHERE s.s_id = sd.s_idAND sd.details_b @>

'{"достоинства":{"мать-героиня":{}}}'\gx

-[ RECORD 1 ]-------------------------------------name | Нинаjsonb_each | (хобби,"""косплей""")-[ RECORD 2 ]-------------------------------------name | Нинаjsonb_each | (достоинства,"{""мать-героиня"":

{""Вася"": ""м"", ""Люся"": ""ж"",""Саша"": ""сведения отсутствуют"",""Макар"": ""м"", ""Семен"":""м""}}")

Между прочим, вместо имени ребенка Нины в запросе бы-ло оставлено пустое место {}. Такой синтаксис добавляетгибкости процессу разработки реальных приложений.

Но главное, пожалуй, возможность создавать для jsonb ин-дексы, поддерживающие оператор @>, обратный ему <@ имногие другие. Среди имеющихся для jsonb индексов, какправило, лучше всего подходит GIN. Для json индексы неподдерживаются, поэтому для приложений с серьезной на-грузкой как правило лучше выбирать jsonb, а не json.

Подробнее о типах json и jsonb и о функциях для рабо-ты с ними можно узнать на страницах документации Post-greSQL postgrespro.ru/doc/datatype-json и postgrespro.ru/doc/functions-json.

Page 139: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

138ix

Однако пользователям нужна была более развитая функ-циональность, и еще в 2014-м году для версии 9.4 Ф. Сига-евым, А. Коротковым и О. Бартуновым было разработанорасширение jsquery. Это расширение определяет язык за-просов для извлечения данных из jsonb и индексы дляускорения этих запросов. Для этого появился новый типданных — jsquery.

С помощью языка запросов можно, например, искать запи-си, указывая путь. Нотация с точками отображает иерархиювнутри jsonb:

test=# SELECT *FROM student_detailsWHERE details::jsonb @@

'хобби.гитарист.группа=Постгрессоры'::jsquery;

В случае, когда мы не знаем путь, можно подменить ветвизвездочкой:

test=# SELECT s_id, detailsFROM student_detailsWHERE details::jsonb @@

'хобби.*.группа=Постгрессоры'::jsquery;

Но при этом без знания иерархи работать с нужным значе-нием очень сложно.

Когда вышел стандарт SQL:2016, в который входит и языкпутей SQL/JSON Path, в Postgres Professional был разрабо-тана его реализация, добавляющая тип jsonpath и наборфункций для работы с JSON с помощью этого языка. Этивозможности вошли в PostgreSQL 12.

Нотация в SQL/JSON Path отличается от обычных операто-ров PostgreSQL для JSON. К нотации расширения jsquery

Page 140: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

139ix

она ближе: иерархию тоже размечают точками. Но грамма-тика SQL/JSON Path более развитая.

• $.a.b.c — в версии PostgreSQL 11 пришлось бы напи-сать ’a’->’b’->’c’.

• $— текущий контекст элемента. Фактически выражениес $ задает область JSON, которая подлежит обработке,в том числе фигурирует в фильтре. Остальная часть вэтом случае для работы недоступна.

• @ — текущий контекст в выражении-фильтре. Перебира-ются пути, доступные в выражении с $.

• *—метасимвол (wildcard). В выражениях с $ или @ озна-чает любое значение участка пути, но при этом с учетомиерархии.

• ** — как часть выражения с $ или @ может означать лю-бое значение участка пути без учета иерархии. Удобноиспользовать, если не знаем уровень вложенности эле-ментов.

• Оператор ? позволяет организовать фильтр, аналогич-ный WHERE, например $.a.b.c ? (@.x > 10).

Запрос с функцией jsonb_path_query() для поиска увле-кающихся косплеем может выглядеть так:

test=# SELECT s_id, jsonb_path_query(details::jsonb,'$.хобби ? (@ == "косплей")'

)FROM student_details;

s_id | jsonb_path_query------+------------------1556 | "косплей"

(1 row)

Page 141: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

140ix

Этот запрос перебирает не все подряд записи JSON, а толь-ко их ветви с ключом «хобби», проверяя, равно ли косплеюсоответствующее ему значение. Но если мы заменим «кос-плей» на «гитарист», ни одна запись не будет возвращена,так как в нашей таблице «гитарист» — не значение, а ключвложенной записи.

В запросе используются две иерархии: одна действует внут-ри выражения $, ограничивающего поиск, а вторая внутри@, то есть выражения, подставляемого при переборе. Этопозволяет добиваться одной цели разными способами.

Например, такой запрос

test=# SELECT s_id, jsonb_path_query(details::jsonb,'$.хобби.гитарист.группа?(@=="Постгрессоры")'

)FROM student_details;

и такой

test=# SELECT s_id, jsonb_path_query(details::jsonb,'$.хобби.гитарист?(@.группа=="Постгрессоры").группа'

)FROM student_details;

дадут одинаковый результат:

s_id | jsonb_path_query------+------------------1432 | "Постгрессоры"

(1 row)

Первый раз мы задавали для каждой записи область по-иска внутри ветви «хобби.гитарист.группа», которой, если

Page 142: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

141ix

взглянуть на сам JSON, соответствует единственное значе-ние — «Постгрессоры», так что и перебирать было нечего.Во втором варианте перебирать надо было все ветви, иду-щие от гитариста, но в выражении фильтра мы прописалипуть-ветвь «группа» — иначе запись не была бы найде-на. В такой синтаксической конструкции нам надо заранеезнать иерархию внутри JSON. Но что делать, если иерархиюмы не знаем?

В этом случае подойдет двойной метасимвол **. Чрезвы-чайно полезная возможность! Допустим, мы забыли, чтотакое «страт» — то ли высоко летающий воздушный шар, толи гитара, то ли представитель высшей социальной страты,но нам надо выяснить, есть ли вообще это слово в нашейтаблице. В предыдущих реализациях операций с JSON при-шлось бы делать сложный перебор (если работать с типомjsonb, не преобразуя его в текст). Теперь можно сказатьтак:

test=# SELECT s_id, jsonb_path_exists(details::jsonb,'$.** ? (@ == "страт")'

)FROM student_details;

s_id | jsonb_path_exists------+-------------------1451 | f1432 | t1556 | f1451 | f

(4 rows)

С возможностями SQL/JSON Path можно ознакомиться нетолько в документации (postgrespro.ru/docs/postgresql/12/datatype-json#DATATYPE-JSONPATH), но также и в статье«Что заморозили на feature freeze 2019. Часть I. JSONPath»(habr.com/ru/company/postgrespro/blog/448612/).

Page 143: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

142ix

Интеграция с внешними системами

Приложения живут не в изолированном мире и зачастуюим приходится обмениваться информацией между собой.Взаимодействие можно реализовать средствами самихприложений, например при помощи веб-сервисов или об-мена файлами, а можно воспользоваться инструментамиСУБД.

В PostgreSQL реализована поддержка стандарта ISO/IEC9075-9 (SQL/MED, Management of External Data) по работев SQL с внешними источниками информации через специ-альный механизм оберток сторонних данных (foreign datawrapper).

Идея механизма в том, чтобы к внешним (сторонним) дан-ным можно было обращаться как к обычным таблицам.Для этого предварительно создаются сторонние таблицы(foreign table), которые сами не содержат данных, а пере-направляют все обращения к внешнему источнику. Такойподход упрощает разработку приложений, так как не тре-бует знания специфики работы с конкретным внешним ис-точником.

Процесс создания сторонних таблиц состоит из несколькихпоследовательных действий.

1. Командой CREATE FOREIGN DATA WRAPPER подключа-ем библиотеку для работы с конкретным источникомданных.

2. Командой CREATE SERVER определяем сервер, где на-ходится источник внешних данных. Для этого в ко-манде обычно указывают такие параметры, как имясервера, номер порта, имя базы данных.

Page 144: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

143ix

3. Разные пользователи PostgreSQL могут подключать-ся к одному и тому же внешнему источнику от име-ни разных удаленных пользователей, поэтому коман-дой CREATE USER MAPPING указываем сопоставлениеимен.

4. Для необходимых таблиц и представлений удален-ного сервера создаем сторонние таблицы командойCREATE FOREIGN TABLE. А команда IMPORT FOREIGN

SCHEMA позволяет импортировать описания всех иличасти таблиц из указанной схемы.

Мы рассмотрим интеграцию PostgreSQL с наиболее попу-лярными СУБД: Oracle, MySQL, SQL Server и PostgreSQL. Носначала нужно установить соответствующие библиотекидля работы с базами данных.

Установка расширений

В дистрибутив PostgreSQL входят две обертки стороннихданных: postgres_fdw и file_fdw. Первая предназначе-на для работы с удаленными базами PostgreSQL, вторая —с файлами на сервере. Помимо этого сообществом раз-работаны и поддерживаются библиотеки для доступа комногим распространенным базам данных. Их список мож-но посмотреть на сайте pgxn.org/tag/fdw.

Обертки сторонних данных для Oracle, MySQL и SQL Serverдоступны в виде расширений:

1. Oracle — github.com/laurenz/oracle_fdw;

2. MySQL — github.com/EnterpriseDB/mysql_fdw;

3. SQL Server — github.com/tds-fdw/tds_fdw.

Page 145: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

144ix

Следуйте инструкциям с этих сайтов, и сборка и установ-ка не вызовет затруднений. Если все было сделано пра-вильно, то в списке доступных расширений появятся соот-ветствующие обертки сторонних данных. Например, дляoracle_fdw:

test=# SELECT name, default_versionFROM pg_available_extensionsWHERE name = 'oracle_fdw' \gx

-[ RECORD 1 ]---+-----------name | oracle_fdwdefault_version | 1.1

Oracle

Вначале устанавливаем расширение, которое в свою оче-редь создаст обертку сторонних данных:

test=# CREATE EXTENSION oracle_fdw;

CREATE EXTENSION

Проверим, что соответствующая обертка создана:

test=# \dew

List of foreign-data wrappers-[ RECORD 1 ]-------------------Name | oracle_fdwOwner | postgresHandler | oracle_fdw_handlerValidator | oracle_fdw_validator

Следующий шаг — создание сервера сторонних данных.В предложении OPTIONS указывается параметр dbserver,определяющий специфическую для подключения к экзем-пляру Oracle информацию: имя сервера, номер порта иназвание экземпляра.

Page 146: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

145ix

test=# CREATE SERVER oracle_srvFOREIGN DATA WRAPPER oracle_fdwOPTIONS (dbserver '//localhost:1521/orcl');

CREATE SERVER

Пользователь PostgreSQL postgres будет подключатьсяк экземпляру Oracle как scott.

test=# CREATE USER MAPPING FOR postgresSERVER oracle_srvOPTIONS (user 'scott', password 'tiger');

CREATE USER MAPPING

Сторонние таблицы будем импортировать в отдельную схе-му. Создадим ее:

test=# CREATE SCHEMA oracle_hr;

CREATE SCHEMA

Импортируем описания удаленных таблиц. Ограничимсядвумя популярными таблицами dept и emp:

test=# IMPORT FOREIGN SCHEMA "SCOTT"LIMIT TO (dept, emp)FROM SERVER oracle_srvINTO oracle_hr;

IMPORT FOREIGN SCHEMA

Заметим, что названия объектов в словаре данных Oracleхранятся в верхнем регистре, а в системном каталоге Post-greSQL— в нижнем. Поэтому, работая с внешними даннымив PostgreSQL, имя схемы Oracle нужно писать заглавнымибуквами и в двойных кавычках, чтобы избежать преобра-зования в нижний регистр.

Page 147: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

146ix

Смотрим список сторонних таблиц:

test=# \det oracle_hr.*

List of foreign tablesSchema | Table | Server

-----------+-------+------------oracle_hr | dept | oracle_srvoracle_hr | emp | oracle_srv

(2 rows)

Теперь для обращения к удаленным данным выполняемзапросы к сторонним таблицам:

test=# SELECT * FROM oracle_hr.emp LIMIT 1 \gx

-[ RECORD 1 ]-------------------empno | 7369ename | SMITHjob | CLERKmgr | 7902hiredate | 1980-12-17sal | 800.00comm |deptno | 20

Можно не только читать данные, но и делать изменения:

test=# INSERT INTO oracle_hr.dept(deptno, dname, loc)VALUES (50, 'EDUCATION', 'MOSCOW');

INSERT 0 1

test=# SELECT * FROM oracle_hr.dept;

deptno | dname | loc--------+------------+----------

10 | ACCOUNTING | NEW YORK20 | RESEARCH | DALLAS30 | SALES | CHICAGO40 | OPERATIONS | BOSTON50 | EDUCATION | MOSCOW

(5 rows)

Page 148: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

147ix

MySQL

Создаем расширение и вместе с ним обертку стороннихданных:

test=# CREATE EXTENSION mysql_fdw;

CREATE EXTENSION

Сторонний сервер, описывающий экземпляр, определяет-ся параметрами host и port:

test=# CREATE SERVER mysql_srvFOREIGN DATA WRAPPER mysql_fdwOPTIONS (host 'localhost', port '3306');

CREATE SERVER

Подключаться будем под суперпользователем MySQL:

test=# CREATE USER MAPPING FOR postgresSERVER mysql_srvOPTIONS (username 'root', password 'p@ssw0rd');

CREATE USER MAPPING

Обертка поддерживает команду IMPORT FOREIGN SCHEMA,но покажем, каким образом можно создать внешнюю таб-лицу вручную:

test=# CREATE FOREIGN TABLE employees (emp_no int,birth_date date,first_name varchar(14),last_name varchar(16),gender varchar(1),hire_date date)

SERVER mysql_srvOPTIONS (dbname 'employees',

table_name 'employees');

CREATE FOREIGN TABLE

Page 149: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

148ix

Проверяем:

test=# SELECT * FROM employees LIMIT 1 \gx

-[ RECORD 1 ]----------emp_no | 10001birth_date | 1953-09-02first_name | Georgilast_name | Facellogender | Mhire_date | 1986-06-26

Как и для Oracle, обертка mysql_fdw разрешает не толькочтение, но и изменение данных.

SQL Server

Создаем расширение и вместе с ним обертку стороннихданных:

test=# CREATE EXTENSION tds_fdw;

CREATE EXTENSION

Создаем сторонний сервер:

test=# CREATE SERVER sqlserver_srvFOREIGN DATA WRAPPER tds_fdwOPTIONS (servername 'localhost', port '1433',

database 'AdventureWorks');

CREATE SERVER

Предоставляемая информация не меняется: нужно указатьимя сервера, номер порта, базу данных. Но количество иназвания параметров в предложении OPTIONS отличаютсяот того, что мы видели для oracle_fdw и mysql_fdw.

Page 150: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

149ix

Будем подключаться под учетной записью суперпользова-теля SQL Server:

test=# CREATE USER MAPPING FOR postgresSERVER sqlserver_srvOPTIONS (username 'sa', password 'p@ssw0rd');

CREATE USER MAPPING

Создадим отдельную схему для сторонних таблиц:

test=# CREATE SCHEMA sqlserver_hr;

CREATE SCHEMA

Импортируем целиком схему HumanResources в созданнуюсхему PostgreSQL:

test=# IMPORT FOREIGN SCHEMA HumanResourcesFROM SERVER sqlserver_srvINTO sqlserver_hr;

IMPORT FOREIGN SCHEMA

Список импортированных таблиц можно проверить коман-дой \det, а можно найти в системном каталоге следующимзапросом:

test=# SELECT ft.ftrelid::regclass AS "Table"FROM pg_foreign_table ft;

Table----------------------------------------sqlserver_hr.Departmentsqlserver_hr.Employeesqlserver_hr.EmployeeDepartmentHistorysqlserver_hr.EmployeePayHistorysqlserver_hr.JobCandidatesqlserver_hr.Shift

(6 rows)

Page 151: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

150ix

Имена объектов созданы с учетом регистра символов, по-этому обращаться к ним в PostgreSQL следует в двойныхкавычках:

test=# SELECT "DepartmentID", "Name", "GroupName"FROM sqlserver_hr."Department"LIMIT 4;

DepartmentID | Name | GroupName--------------+-------------+-------------------------

1 | Engineering | Research and Development2 | Tool Design | Research and Development3 | Sales | Sales and Marketing4 | Marketing | Sales and Marketing

(4 rows)

В настоящий момент tds_fdw поддерживает только чтение,но не изменение данных.

PostgreSQL

Создаем расширение и обертку:

test=# CREATE EXTENSION postgres_fdw;

CREATE EXTENSION

Будем подключаться к другой базе этого же экземпляра,например, из базы данных test к демонстрационной ба-зе. Поэтому при создании стороннего сервера достаточноуказать только параметр dbname, а параметры host, port идругие можно опустить:

test=# CREATE SERVER postgres_srvFOREIGN DATA WRAPPER postgres_fdwOPTIONS (dbname 'demo');

CREATE SERVER

Page 152: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

151ix

При сопоставлении пользователей этого же кластера базданных не нужно указывать пароль:

test=# CREATE USER MAPPING FOR postgresSERVER postgres_srvOPTIONS (user 'postgres');

CREATE USER MAPPING

Импортируем все таблицы и представления, принадлежа-щие схеме bookings:

test=# IMPORT FOREIGN SCHEMA bookingsFROM SERVER postgres_srvINTO public;

IMPORT FOREIGN SCHEMA

Проверяем:

test=# SELECT * FROM bookings LIMIT 3;

book_ref | book_date | total_amount----------+------------------------+--------------000004 | 2015-10-12 14:40:00+03 | 55800.0000000F | 2016-09-02 02:12:00+03 | 265700.00000010 | 2016-03-08 18:45:00+03 | 50900.00000012 | 2017-07-14 09:02:00+03 | 37900.00000026 | 2016-08-30 11:08:00+03 | 95600.00

(5 rows)

Подробнее про postgres_fdw можно почитать в докумен-тации: postgrespro.ru/doc/postgres-fdw.html.

Механизм оберток сторонних данных интересен и тем, чторассматривается сообществом как основа для созданиявстроенного в PostgreSQL шардинга. Шардирование напо-минает секционирование: и в том, и в другом случае табли-ца разделяется по какому-то признаку на несколько частей,

Page 153: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

152ix

которые хранятся независимо. Разница в том, что секциирасполагаются на том же сервере, а шарды — на разных.Возможность секционирования существует в PostgreSQLдовольно давно. Начиная с версии 10 этот механизм актив-но развивается: добавлен декларативный синтаксис, ди-намическое исключение секций, параллельная обработкаи сделаны другие улучшения. В качестве секций можноиспользовать и внешние таблицы, и таким образом секци-онирование превращается в шардирование.

На этом пути еще предстоит многое сделать, чтобы шарди-рованием действительно можно было пользоваться:

• в настоящее время обертки сторонних данных не под-держивают параллельные планы выполнения, поэтомувсе секции-шарды перебираются последовательно;

• не гарантируется согласованность: работа с внешнимисерверами ведется не в единой распределенной тран-закции, а в отдельных локальных транзакциях;

• отсутствует возможность дублировать одни и те же дан-ные на нескольких серверах для улучшения отказо-устойчивости;

• все необходимые действия по созданию таблиц на шар-дах и соответствующих внешних таблиц пока приходит-ся выполнять вручную.

Часть из перечисленных задач уже решена в нашем экс-периментальном расширении pg_shardman, доступном наgithub.com/postgrespro/pg_shardman.

Для взаимодействия с базами PostgreSQL существует ещеодно расширение, входящее в дистрибутив — dblink. Онопозволяет явно управлять соединениями (подключаться,отключаться), выполнять запросы и получить результатыасинхронно: postgrespro.ru/doc/dblink.html.

Page 154: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

X Обучениеи сертификация

Документация

Для серьезной работы с PostgreSQL не обойтись без чтениядокументации. Это не только описание всех возможностейСУБД, но и исчерпывающее справочное руководство, кото-рое всегда должно быть под рукой. Читая документацию,вы получаете емкуюи точнуюинформациюиз первых рук—она написана самими разработчиками и всегда аккуратноподдерживается в актуальном состоянии.

В нашей компании Postgres Professional выполнен переводвсего комплекта документации PostgreSQL, включая самуюпоследнюю версию, на русский язык — он доступен на сай-те www.postgrespro.ru/docs.

Глоссарий, составленный нами для перевода, опублико-ван по адресу postgrespro.ru/education/glossary. Мы реко-мендуем использовать его, чтобы грамотно переводить ан-глоязычные документы и использовать единую, понятнуювсем терминологию для материалов на русском языке.

Предпочитающие оригинальную документацию на англий-ском языке найдут ее как на нашем сайте, так и по адресуwww.postgresql.org/docs.

Page 155: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

154x

Учебные курсы

Помимо документации, мы занимаемся разработкой учеб-ных курсов для администраторов баз данных и разработ-чиков приложений:

• DBA1. Базовый курс по администрированию;

• DBA2. Настройка и мониторинг;

• DBA3. Резервное копирование и репликация;

• DEV1. Базовый курс для разработчиков серверной частиприложения;

• DEV2. Расширенный курс для разработчиков сервернойчасти приложения (в разработке);

• QPT. Оптимизация запросов.

Документация PostgreSQL содержит полные детальные све-дения, которые, однако, разбросаны по разным главам итребуют многократного внимательного прочтения. В отли-чие от документации, курсы состоят из модулей, после-довательно и связно раскрывающих содержание. Акцентделается не на полноте охвата, а на выделении важной ипрактически полезной информации. Таким образом, курсыпризваны не заменить документацию, а дополнить ее.

Каждая тема курса состоит из теоретической части и прак-тики. Теория — это не только презентация, но в большин-стве случаев еще и демонстрация работы на «живой» си-стеме. Слушатели курса получают презентации с подроб-ными комментариями к каждому слайду, результат работыдемонстрационных скриптов, решения практических зада-ний, а в некоторых случаях и дополнительные справочныематериалы.

Page 156: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

155x

Где и как пройти обучение

Для самостоятельного обучения и некоммерческого ис-пользования все материалы курсов, включая видеозаписи,доступны на нашем сайте всем желающим. Вы найдете ихпо адресу postgrespro.ru/education/courses.

Также вы можете пройти обучение по перечисленным кур-сам в одном из специализированных учебных центров подруководством опытного преподавателя. По окончании кур-са выдается сертификат слушателя. Список авторизован-ных нами учебных центров: www.postgrespro.ru/education/where.

DBA1. Базовый курс по администрированиюPostgreSQL

Продолжительность: 3 дня

Предварительные знания:

Минимальные сведения о базах данных и SQL.Знакомство с Unix.

Какие навыки будут получены:

Общее сведения об архитектуре PostgreSQL.Установка, базовая настройка, управление сервером.Организация данных на логическом и физическом уров-нях.Базовые задачи администрирования.Управление пользователями и доступом.Представление о резервном копировании, восстановле-нии и репликации.

Page 157: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

156x

Темы:

Базовый инструментарий

1. Установка и управление сервером2. Использование psql3. Конфигурирование

Архитектура

4. Общее устройство PostgreSQL5. Изоляция и многоверсионность6. Буферный кэш и журнал

Организация данных

7. Базы данных и схемы8. Системный каталог9. Табличные пространства10. Низкий уровень

Задачи администрирования

11. Мониторинг12. Сопровождение

Управление доступом

13. Роли и атрибуты14. Привилегии15. Политики защиты строк16. Подключение и аутентификация

Резервное копирование

17. Обзор

Репликация

18. Обзор

Материалы учебного курса доступны для самостоятель-ного изучения по адресу: www.postgrespro.ru/education/courses/DBA1.

Page 158: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

157x

DBA2. Настройка и мониторинг PostgreSQL

Продолжительность: 4 дня

Предварительные знания:

Основы языка SQL.Владение ОС Unix.Знакомство с PostgreSQL в объеме курса DBA1.

Какие навыки будут получены:

Настройка различных конфигурационных параметровисходя из понимания внутреннего устройства сервера.Мониторинг сервера и его использование полученныхданных для итеративной настройки параметров.Настройки, связанные с локализацией.Управление расширениями и знакомство с процедуройобновления сервера.

Темы:

Многоверсионность

1. Изоляция2. Страницы и версии строк3. Снимки данных4. HOT-обновления5. Очистка6. Автоочистка7. Заморозка

Журналирование

8. Буферный кэш9. Журнал предзаписи10. Контрольная точка11. Настройка журнала

Page 159: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

158x

Блокировки

12. Блокировки объектов13. Блокировки строк14. Блокировки в оперативной памяти

Задачи администрирования

15. Управление расширениями16. Локализация17. Обновление сервера

Материалы учебного курса доступны для самостоятель-ного изучения по адресу: www.postgrespro.ru/education/courses/DBA2.

DBA3. Резервное копирование и репликацияPostgreSQL

Продолжительность: 2 дня

Предварительные знания:

Основы языка SQL.Владение ОС Unix.Знакомство с PostgreSQL в объеме курса DBA1.

Какие навыки будут получены:

Выполнение резервного копирования.Настройка серверов для физической и логической ре-пликации.Знакомство со сценариями использования репликации.Представление о способах построения кластеров.

Page 160: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

159x

Темы:

Резервное копирование

1. Логическое резервирование2. Базовая резервная копия3. Архив журнала предзаписи

Репликация

4. Физическая репликация5. Переключение на реплику6. Логическая репликация7. Сценарии использования

Кластерные технологии

8. Обзор

Материалы учебного курса доступны для самостоятель-ного изучения по адресу: www.postgrespro.ru/education/courses/DBA3.

DEV1. Базовый курс по разработке сервернойчасти приложений

Продолжительность: 4 дня

Предварительные знания:

Основы языка SQL.Опыт работы с каким-нибудь процедурным языкомпрограммирования.Минимальные сведения о работе в Unix.

Page 161: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

160x

Какие навыки будут получены:

Общие сведения об архитектуре PostgreSQL.Использование основных объектов БД.Программирование на стороне сервера на языках SQLи PL/pgSQL.Использование основных типов данных, включая запи-си и массивы.Организация взаимодействия с клиентской частью.

Темы:

Базовый инструментарий

1. Установка и управление, psql

Архитектура

2. Общее устройство PostgreSQL3. Изоляция и многоверсионность4. Буферный кэш и журнал

Организация данных

5. Логическая структура6. Физическая структура

Приложение «Книжный магазин»

7. Схема данных приложения8. Взаимодействие клиента с СУБД

SQL

9. Функции10. Составные типы

PL/pgSQL

11. Обзор и конструкции языка12. Выполнение запросов

Page 162: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

161x

13. Курсоры14. Динамические команды15. Массивы16. Обработка ошибок17. Триггеры18. Отладка

Разграничение доступа

19. Обзор

Материалы учебного курса доступны для изучения по ад-ресу: www.postgrespro.ru/education/courses/DEV1.

QPT. Оптимизация запросов PostgreSQL

Продолжительность: 2 дня

Предварительные знания:

Знакомство с OC Unix.Уверенное владение SQL.Владение языком PL/pgSQL будет полезно, но не явля-ется обязательным.Знакомство с PostgreSQL в объеме курса DBA1 (для ад-министраторов) или DEV1 (для разработчиков).

Какие навыки будут получены:

Детальное понимание механизмов планирования и вы-полнения запросов.Настройка параметров экземпляра, связанных с произ-водительностью.Поиск проблемных запросов и их оптимизация.

Page 163: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

162x

Темы:

1. Демобаза «Авиаперевозки»2. Выполнение запросов3. Последовательный доступ4. Индексный доступ5. Сканирование по битовой карте6. Соединение вложенным циклом7. Соединение хешированием8. Соединение слиянием9. Статистика10. Профилирование11. Приемы оптимизации

Материалы учебного курса доступны для самостоятель-ного изучения по адресу: www.postgrespro.ru/education/courses/QPT.

Профессиональная сертификация

В 2019 году компания Postgres Professional запустила про-грамму сертификации специалистов по СУБД PostgreSQL.

Программа сертификации полезна как самим специали-стам, так и работодателям. Владельцы сертификатов могутполучить дополнительные преимущества при поиске ра-боты и обсуждении уровня оплаты труда. К тому же этовозможность подтвердить свой уровень знаний, пользуясьнезависимой системой оценки.

Для работодателей программа облегчает поиск новых спе-циалистов и позволяет проверить уровень владения Post-greSQL у имеющихся, дает возможность контролировать

Page 164: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

163x

качество полученных знаний при направлении сотрудни-ков на обучение, позволяет убедиться в компетентностисотрудников компаний-партнеров и поставщиков услуг.

В настоящее время сертификация доступна только для ад-министраторов баз данных PostgreSQL. В дальнейшем пла-нируется расширить программу и для разработчиков при-ложений PostgreSQL.

Сертификация предполагает три уровня, для достижениякаждого из которых потребуется пройти ряд тестов.

Уровень «Профессионал» подтверждает знания в следую-щих областях:

• общие сведения об архитектуре PostgreSQL;• варианты установки сервера, навыки работы в psql,

управление настройками конфигурации;• организация данных на логическом и физическом

уровне;• управление пользователями и доступом;• общие сведения о резервном копировании и реплика-

ции баз данных.

Для получения сертификата необходимо успешно пройтитест по курсу DBA1.

Уровень «Эксперт» дополнительно подтверждает знанияв следующих областях:

• внутреннее устройство PostgreSQL;• мониторинг и настройка сервера, выполнение задач со-

провождения;• решение задач оптимизации производительности, на-

стройки запросов;• выполнение резервного копирования;

Page 165: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

164x

• настройка серверов для физической и логической ре-пликации для различных сценариев использования.

Для получения сертификата необходимо иметь сертификатуровня «Профессионал» и успешно пройти тесты по курсамDBA2, DBA3, QPT.

Уровень «Мастер» дополнительно подтверждает практиче-ские навыки администрирования PostgreSQL.

Для получения сертификата необходимо иметь сертификатуровня «Эксперт» и успешно пройти практический тест. Этоттип сертификации находится в разработке.

Зарегистрируйтесь на postgrespro.ru/user и запишитесь натестирование в личном кабинете.

Для успешной сдачи теста необходимо:

• уверенно владеть материалом соответствующих курсови быть знакомым с разделами документации, на кото-рые в курсах приводятся ссылки;

• иметь навыки практической работы с PostgreSQL в сре-де psql.

Во время тестирования доступны материалы курсов и доку-ментация к PostgreSQL, но любыми другими источникамиинформации пользоваться запрещено.

Достижение очередного уровня подтверждается сертифи-катом. Сертификат бессрочен, но привязан к конкретнойверсии сервера и устаревает вместе с ней. Через несколь-ко лет это может послужить причиной получения новогосертификата по более актуальной версии PostgreSQL.

Подробнее о программе сертификации читайте на сайтеpostgrespro.ru/education/cert.

Page 166: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

165x

Курсы для вузов

Одним из важнейших направлений деятельности нашейкомпании является подготовка кадров в области системуправления базами данных. Начинать готовить будущихспециалистов необходимо уже с учебной скамьи, а это воз-можно только при взаимодействии с высшими учебнымизаведениями.

Мы предлагаем несколько учебных курсов, которые яв-ляются результатом сотрудничества компании с опытны-ми преподавателями ведущих вузов. Материал рассчитанна студентов бакалавриата, имеющих базовую подготовкупо программированию. Все курсы свободны для исполь-зования в образовательной деятельности. В распоряже-нии преподавателей — учебные пособия, слайды презен-таций и видеозапись лекций, другие учебные материалы,представленные на нашем сайте postgrespro.ru/education/university.

Курсы, разработанные при участии компании, читаютсяв Московском Государственном Университете им. М. В. Ло-моносова, Высшей Школе Экономики, Московском авиаци-онном институте, Сибирском государственном универси-тете науки и технологий им. М. Ф. Решетнева, Сибирскомфедеральном университете. Если вы являетесь представи-телем вуза и заинтересованы во внедрении курсов по ба-зам данных в учебный план, свяжитесь с нами.

Также мы приглашаем к сотрудничеству преподавателей,готовых разрабатывать новые авторские курсы с исполь-зованием PostgreSQL. Мы, в свою очередь, оказываем под-держку, консультируем, редактируем рукописи и доводимих до публикации, организуем для авторов открытые лек-ции в ведущих вузах страны.

Page 167: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

166x

Основы языка SQL

Слушатели курса без предварительной подготовки смогутразобраться, что представляет собой система PostgreSQL,и научатся с ней работать. Начиная с разработки простыхзапросов на языке SQL слушатели постепенно осваива-ют более сложные конструкции, знакомятся с концепциейтранзакций и оптимизацией производительности.

В основе курса лежит учебное пособие «PostgreSQL. Осно-вы языка SQL».

Содержание:

Введение.Создание рабочейсреды.Основные операции.Типы данных.Основы языка определе-ния данных.Запросы.Изменение данных.Индексы.Транзакции.Повышение производи-тельности.

Моргунов Е. П.PostgreSQL. Основы языка SQL: учеб. пособие / Е. П. Мор-гунов; под ред. Е. В. Рогова, П. В. Лузанова. — СПб.: БХВ-Петербург, 2018. — 336 с.ISBN 978-5-9775-4022-3 (печатное издание)ISBN 978-5-6041193-2-7 (электронное издание)

Page 168: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

167x

В электронном виде книга доступна на нашем сайте:postgrespro.ru/education/books/sqlprimer.

Курс состоит из 36 часов лекционных и практических заня-тий. На протяжении нескольких лет он постоянно читаетсяавтором в ведущих вузах Москвы и Красноярска. Матери-алы курса доступны по адресу postgrespro.ru/education/university/sqlprimer.

Евгений Павлович Моргунов, кан-дидат технических наук, доценткафедры информатики и вычис-лительной техники Сибирского го-сударственного университета нау-ки и технологий имени академикаМ. Ф. Решетнева.

Живет в Красноярске. До переходав вуз в 2000-ом году более 10 летработал программистом, в том чис-ле занимался разработкой прикладной системы для банка.Познакомился с СУБД PostgreSQL в 1998 году. Сторонник ис-пользования в учебном процессе открытого и свободногопрограммного обеспечения. По его инициативе в ходе изу-чения дисциплины «Технология программирования» ста-ли применяться операционная система FreeBSD и системауправления базами данных PostgreSQL. Член Международ-ного общества инженерной педагогики (IGIP). Опыт исполь-зования PostgreSQL в преподавании составляет более 17лет.

Page 169: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

168x

Основы технологий баз данных

Современный университетский курс, сочетающий глубо-кую теоретическую составляющую с актуальными практи-ческими аспектами применения и проектирования системуправления базами данных.

Первая часть содержитосновные сведения о си-стемах управления база-ми данных: реляционнаямодель данных, язык SQL,обработка транзакций.

Во второй части подроб-но рассмотрены техно-логии, лежащие в основефункционирования СУБД,и тенденции их развития.Некоторые темы изуча-ются повторно на болееглубоком уровне.

Новиков Б. А.Основы технологий баз данных: учеб. пособие / Б. А. Нови-ков, Е. А. Горшкова, Н. Г. Графеева; под ред. Е. В. Рогова. —2-е изд. — М.: ДМК Пресс, 2020. — 582 с.ISBN 978-5-97060-841-8 (печатное издание)ISBN 978-5-6041193-5-8 (электронное издание)

Page 170: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

169x

Содержание книги:

Часть I. От теории к практике

Введение.Теоретические основы БД.Знакомимся с базой данных.Введение в SQL.Управление доступом в базах данных.Транзакции и согласованность базы данных.Разработка приложений СУБД.Расширения реляционной модели.Разновидности СУБД.

Часть II. От практики к мастерству

Архитектура СУБД.Структуры хранения и основные алгоритмы СУБД.Выполнение и оптимизация запросов.Управление транзакциями.Надежность баз данных.Дополнительные возможности SQL.Функции и процедуры в базе данных.Расширяемость PostgreSQL.Полнотекстовый поиск.Безопасность данных.Администрирование баз данных.Репликация баз данных.Параллельные и распределенные СУБД.

В электронном виде книга доступна на нашем сайте:postgrespro.ru/education/books/dbtech.

Page 171: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

170x

Курс рассчитан на 24 часа лекционных и 8 часов прак-тических занятий. Он был прочитан Борисом АсеновичемНовиковым на факультете ВМК МГУ им. М. В. Ломоносо-ва. Материалы курса доступны по адресу postgrespro.ru/education/university/dbtech.

Борис Асенович Новиков, докторфизико-математических наук, про-фессор департамента информати-ки НИУ ВШЭ в Санкт-Петербурге.

Научные интересы в основном свя-заны с различными аспектами про-ектирования, разработки и приме-нения систем управления базами данных и их приложений,а также распределенных масштабируемых систем для об-работки и анализа больших потоков данных.

Горшкова Екатерина Александровна, кандидат физико-математических наук.

Специалист в проектировании высоконагруженных прило-жений с интенсивным использованием данных. В областьнаучных интересов входит машинное обучение, анализ по-токовых данных, информационный поиск.

Графеева Наталья Генриховна, кандидат физико-матема-тических наук, доцент кафедры информационно-аналити-ческих систем СПбГУ.

Научные интересы связаны с базами данных, информаци-онным поиском, большими данными и интеллектуальныманализом данных. Имеет значительный опыт разработки,проектирования и сопровождения информационных си-стем, разработки и преподавания учебных курсов.

Page 172: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

XI Путеводительпо галактике

Новости и обсуждения

Если вы собираетесь работать с PostgreSQL, вам захочет-ся быть в курсе событий, узнавать о новых возможностяхпредстоящего выпуска, знакомиться с другими новостями.Много людей ведут свои блоги, публикуя интересные и по-лезные материалы.

Удобный способ получить все англоязычные заметки в од-ном месте — читать сайт-агрегатор planet.postgresql.org.Большое количество статей на русском языке публикует-ся на сайте habr.com/hub/postgresql, в том числе и нашейкомпанией.

Не забывайте и про wiki.postgresql.org — сборник статей,поддерживаемый и развиваемый сообществом. Здесь вынайдете ответы на часто задаваемые вопросы, обучаю-щие материалы, статьи про настройку и оптимизацию, проособенности миграции с разных СУБД и многое другое.Часть материалов этого сайта доступна и на русском языке:wiki.postgresql.org/wiki/Russian. Вы тоже можете помощьсообществу, переведя заинтересовавшую вас англоязыч-ную статью.

Page 173: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

172xi

Более двух с половиной тысяч русскоязычных пользовате-лей PostgreSQL входят в группу «PostgreSQL в России» нафейсбуке: www.facebook.com/groups/postgresql.

Свой вопрос можно задать и на профильных сайтах. На-пример, на stackoverflow.com на английском языке илиru.stackoverflow.com на русском (не забудьте поставитьметку «postgresql»), или на форуме www.sql.ru/forum/postgresql.

Новости нашей компании Postgres Professional вы найдетепо адресу postgrespro.ru/blog.

Списки рассылки

Если вы хотите узнавать обо всем первым, не дожидаясь,пока кто-нибудь напишет заметку в блоге, читайте спис-ки рассылки. Разработчики PostgreSQL по старой традицииобсуждают между собой все вопросы исключительно поэлектронной почте. Для этого используется список рассыл-ки pgsql-hackers (часто называемый просто «hackers»).

Полный перечень всех списков рассылки находится по ад-ресу www.postgresql.org/list. Среди них:

• pgsql-general для обсуждения общих вопросов,

• pgsql-bugs для сообщений о найденных ошибках,

• pgsql-docs для обсуждения документации,

• pgsql-announce для новостей о выходе новых версийпродуктов

и многие другие.

Page 174: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

173xi

На любой список может подписаться каждый желающий,чтобы регулярно получать сообщения по электронной по-чте и при необходимости принять участие в дискуссии.

Другой вариант — время от времени читать архив сооб-щений на www.postgresql.org/list, или, в несколько болееудобном виде, на www.postgresql-archive.org.

Commitfest

Еще один способ быть в курсе событий, не тратя на этомного времени— заглядывать на commitfest.postgresql.org.В этой системе периодически открываются «окна», в ко-торых разработчики должны регистрировать свои патчи.Например, окно 01.03.2019–31.03.2019 относилось к вер-сии PostgreSQL 12, а следующее за ним окно 01.07.2019–31.07.2019— уже к следующей. Это делается для того, чтобыпримерно за полгода до выхода новой версии PostgreSQLпрекратить прием новых возможностей и успеть стабили-зировать код.

Патчи проходят несколько этапов: рецензируются и ис-правляются по результатам рецензии, потом либо прини-маются, либо переносятся в следующее окно, либо — еслисовсем не повезло — отвергаются.

Таким образом вы можете быть в курсе возможностей, ко-торые уже включены или только предполагаются к включе-нию в еще не вышедшую версию.

Page 175: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

174xi

Конференции

В России регулярно проводятся две крупные международ-ные конференции, собирающие сотни пользователей и раз-работчиков PostgreSQL:

PGConf в Москве (pgconf.ru);

PGDay в Санкт-Петербурге (pgday.ru).

Периодически проходят и региональные конференцииPGConf; например, PGConf.Сибирь проводилась в Новоси-бирске и Красноярске.

Кроме того, в разных городах России проводятся конфе-ренции с более широкой тематикой, на которых представ-лено направление баз данных и, в том числе, PostgreSQL.Отметим лишь несколько:

CodeFest в Новосибирске (codefest.ru);

HighLoad++ в Москве и других городах (highload.ru).

Разумеется, конференции по PostgreSQL проводятся и вовсем мире. К самым крупным из них относятся:

PGCon в Оттаве (pgcon.org);

PGConf Europe, в 2020 году в Берлине (pgconf.eu).

Помимо конференций проходят и неофициальные регу-лярные встречи, в том числе онлайн: www.meetup.com/postgresqlrussia.

Page 176: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

XII О компании

Компания Postgres Professional была основана в 2015 годуи объединила ключевых российских разработчиков, вкладкоторых в развитие PostgreSQL признан мировым сообще-ством. Компания развивает отечественную экспертизу в об-ласти разработки СУБД. В настоящее время в ней работаетболее 50 программистов, архитекторов и инженеров.

Postgres Professional выпускает несколько версий системыPostgres Pro, построенной на основе PostgreSQL, и выполня-ет разработки на уровне ядра СУБД и расширений, оказы-вает услуги по проектированию и поддержке прикладныхсистем, миграции на PostgreSQL.

Компания уделяет большое внимание образовательной де-ятельности, организует крупнейшую ежегодную междуна-родную конференцию PgConf.Russia в Москве и принимаетучастие в конференциях по всему миру.

Контактная информация:

117036, г. Москва, ул. Дмитрия Ульянова, д. 7А

+7 495 150-06-91

[email protected]

Page 177: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

176xii

СУБД Postgres Pro

Postgres Pro — российская коммерческая СУБД, разрабо-танная компанией Postgres Professional с использованиемсвободно распространяемой СУБД PostgreSQL, значитель-но переработанная для соответствия требованиям корпо-ративных заказчиков. Postgres Pro входит в реестр россий-ского ПО.

Postgres Pro Standard содержит все функциональные воз-можности PostgreSQL с дополнительными патчами ядра,которые скоро будут приняты сообществом, а также расши-рениями и патчами, разработанными Postgres Professional.Таким образом, клиенты могут получить доступ к полезнойфункциональности и получить выигрыш в производитель-ности, не дожидаясь очередного релиза PostgreSQL.

Postgres Pro Enterprise представляет собой глубоко перера-ботанную версию СУБД, содержащую существенные изме-нения, повышающие ее надежность, производительностьи применимость для серьезных промышленных задач.

Обе версии Postgres Pro, дополненные необходимымисредствами защиты информации, прошли сертификациюФСТЭК.

Для использования любой версии Postgres Pro необходимоприобрести лицензию. Можно бесплатно получить инте-ресующую вас версию СУБД для тестирования, изучениявозможностей СУБД и разработки прикладного программ-ного обеспечения.

Подробнее о возможностях и отличиях версий Postgres Proчитайте на сайте: postgrespro.ru/products/postgrespro

Page 178: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

177xii

Услуги

Отказоустойчивые решения для СУБД Postgres

Проектирование и участие в создании высоконагружен-ных, высокопроизводительных и отказоустойчивых про-мышленных систем; консалтинговые услуги. ВнедрениеСУБД Postgres и оптимизация конфигурации.

Вендорская техническая поддержка

Техподдержка Postgres Pro и PostgreSQL в режиме 24x7.Мониторинг, восстановление работоспособности, анализнепредвиденных обстоятельств, повышение производи-тельности, исправление ошибок в СУБД и расширениях.

Миграция прикладных систем на СУБД Postgres

Оценка сложности миграции с других СУБД на Postgres. Раз-работка архитектуры нового решения и необходимых до-работок. Миграция прикладных систем на СУБД Postgres иподдержка в процессе миграции.

Обучение Postgres

Обучение администраторов баз данных, разработчиков иархитекторов прикладных систем особенностям СУБД Post-gres и эффективному использованию ее достоинств.

Аудит СУБД

Привлечение экспертов Postgres Professional для оценкисостояния СУБД. Аудит информационной безопасности си-стем на основе Postgres.

Полное описание услуг: postgrespro.ru/services

Page 179: Предисловие - Postgres Professional · держку PostgreSQL. В России такой компанией является Postgres Professional (), предоставляя

Лузанов Павел ВениаминовичРогов Егор Валерьевич

Лёвшин Игорь Викторович

Postgres. Первое знакомство

Дизайнер обложки А. В. Климковский6-е издание, переработанное и дополненное

postgrespro.ru/education/books/introbook

© ООО «ППГ», 2016–2020

Москва, «Постгрес Профессиональный», 2020

ISBN 978-5-6041193-6-5