Привет, Хабр! Приглашаем на бесплатный Demo-урок «Параллельный кластер CockroachDB», который пройдёт в рамках курса «PostgreSQL». Также публикуем перевод статьи Тома Брауна — Principal Systems Engineer at EnterpriseDB.  В этой статье рассмотрим несколько полезных советов по работе с PostgreSQL: Ссылка на всю строку целиком Сравнение нескольких столбцов Общие табличные выражения Пользовательские параметры конфигурации Сравнение логических значений без "равно" Изменение типа столбца без лишних затрат Информация о секции, в которой находится строка Таблицы — это типы Вы когда-нибудь пробовали выполнить подобный запрос? Запрос выглядит странно. Он возвращает все столбцы таблицы в виде одного столбца. Зачем это может понадобиться? Что ж, я думаю, вы не раз ссылались на таблицы следующим образом: Здесь есть ссылка на строку, но только один столбец. И здесь ничего необычного нет. А как насчет этого? Здесь есть таблица data и ее резервная копия backup_data. И что, если мы хотим увидеть разницу между ними: найти изменения с момента резервного копирования и узнать не потеряли ли мы какие-то строки в резервной копии? Для демонстрации создадим таблицу и вставим три строки: Теперь создадим идентичную копию таблицы и скопируем в нее данные: Мы хотим, чтобы таблицы были разными, поэтому одну строку удалим и одну строку добавим: Давайте посмотрим, что произойдет, если мы запустим запрос для сравнения таблиц: Мы видим, что таблица backup_data содержит строку, которая отсутствует в таблице data, и наоборот. Можно использовать эту возможность и так: Мы превратили все наши данные в JSON! Это очень интересный трюк, с помощью которого можно сделать запросы короче и читабельнее. Допустим, у нас есть следующий запрос: Мы можем избавиться от AND: И также можем использовать IN для условий OR: Этот запрос можно сократить: Допустим, у вас есть доступ к базе данных только для чтения и вы не можете создавать таблицы. И также у вас есть небольшой набор данных, который вы бы хотели соединить (join) с существующими таблицами. Допустим, вы хотите получить представление о том, насколько тепло или холодно на каждой из станций. Тогда можно сделать примерно такой запрос:  В данном способе неудобно добавлять условия. Это можно упростить, создав псевдо-таблицу с использованием общих табличных выражений (CTE, common table expression): Если вы не знакомы с диапазонными типами, то вас могут смутить "numrange". Это один из диапазонных типов, предназначенный для представления диапазона чисел. Круглые скобки означают исключение границы, квадратные — включение. Таким образом, '(0,10]' означает "от 0, но не включая 0, и до 10 включительно". Отсутствующая левая граница диапазона означает все значения меньше указанного числа, а отсутствующая правая — больше указанного числа. Postgres поставляется с большим набором параметров, которые позволяют настраивать все аспекты системы базы данных, но вы также можете добавлять свои параметры и называть их так, как вам удобно, при условии, что вы укажите префикс. Например, можно добавить в postgresql.conf следующий параметр: А затем получить его значение с помощью команды SHOW. Обратите внимание, что эти параметры не отображаются в каталоге pgsettings и не выводятся командой SHOW ALL. Так почему мы должны обязательно указывать префикс конфигурации? До PostgreSQL 9.2 был параметр customvariable_classes, который принимал список классов, которые могли использоваться расширениями для их собственных параметров. Вам нужно было добавить класс расширения в этот список, если вы хотели настроить его через postgresql.conf. Однако это требование было убрано в более поздних версиях, и вам больше не нужно объявлять их явно. Встроенные параметры не имеют префиксов, поэтому любые пользовательские параметры должны иметь префиксы, иначе они не будут приниматься. Такие параметры удобно использовать для предоставления метаданных о кластере. Вероятно, вы писали подобные запросы: Знаете ли вы, что вам не нужно писать "= true"? Можно упростить: Это работает, потому что булевы значения не нужно сравнивать с другим булевым значением, поскольку выражения в любом случае возвращают true или false. Отрицание можно написать так: Это тоже читается лучше. Часто при изменении типа столбца в таблице с данными, необходимо пересоздавать всю таблицу. Но во многих случаях этого не происходит.  И мы можем найти такие типы: Этот запрос вернет относительно небольшой список типов с информацией о том, в какие "бинарно совместимые" типы они могут быть преобразованы. Из результатов вы увидите, что типы text, xml, char и varchar являются взаимозаменяемыми. Поэтому если у вас есть таблица, содержащая XML-данные в столбце text, не бойтесь его преобразовывать (обратите внимание, что при невалидном XML Postgres возвратит ошибку). Таблица может быть секционирована и вам может понадобиться узнать, в какой секции находится строка? Это легко: просто добавьте tableoid :: regclass в SELECT. Например: Здесь tableoid - это скрытый системный столбец, который просто нужно явно указать в SELECT. Он возвращает OID (Object Identifier) таблицы, к которой принадлежит строка. Если вы приведете его к типу regclass, то получите имя таблицы. Да, вы все правильно услышали. Каждый раз, когда вы создаете таблицу, вы фактически  также создаете новый тип. Смотрите: Мы можем использовать этот тип таблицы при создании другой таблицы, как параметр функции или в качестве возвращаемого типа: Затем можно вставить данные: Чтобы получить отдельные столбцы из табличного значения, можно выбрать столбец из столбца: Теперь я знаю, о чем вы думаете: таблица, содержит табличный тип, который содержит типы, также является типом? Да, но давайте не будем углубляться в эти детали, иначе мы окажемся в запутанной ситуации в Inception-стиле. И как я уже упоминал в "Ссылка на всю строку целиком", вы можете преобразовать всю строку в JSON: Эту функциональность можно использовать для создания схем с данными в виде JSON, чтобы получить NoSQL-подобную функциональность, но с данными, имеющими определенную структуру. Но подождите, а что, если я хочу хранить и запрашивать все мои любимые книги, песни и фильмы, а не только одну запись? Это тоже работает. Любой тип, в том числе и табличный, можно превратить в массив, добавив [] после имени типа данных. Вместо того чтобы заново создавать таблицу, давайте просто преобразуем столбцы массивы, а затем добавим еще одну книгу:  Добавляем еще одну книгу: Теперь результат выглядит следующим образом: Теперь запрос выводит массив книг и это без каких-либо его изменений. Надеюсь, эти советы помогут вам использовать Postgres более эффективно! Чтобы узнать больше, ознакомьтесь с нашей новой электронной книгой 5 Ways to Get More from PostgreSQL (Пять способов получить больше от PostgreSQL). Интересно развиваться в данном направлении? Запишитесь на бесплатный Demo-урок «Секционирование таблиц PostgreSQL» и участвуйте в онлайн-встрече с Евгением Аристовым — руководителем образовательной программы «PostgreSQL» и курсов «Базы данных», «Software Architect», «MS SQL Server Developer», «Нереляционные базы данных». CRM/Email-маркетолог