PostgreSQL — не Rocket Science. Почем сейчас яйца?

e4adc99677e74469aacf11c2ad26d929.jpg

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

Начну очень из далека

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

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

Чтобы получить ОПТИМАЛЬНЫЙ результат, вам нужно объездить ВСЕ магазины, сравнить цены, качество, послушать отзывы покупателей и наконец выбрать приемлимый для вас товар по минимальной цене. Естественно, никто так не делает, потому что есть большая вероятность умереть от голода, пока всё это осуществляешь.

Или, например, вы сделали наикрутейший стартап, некий сайт, который должен перевернуть мир. Но если о нем никто не знает, то это всё равно что его вообще нет. Нужна реклама, маркетинг и т.д.

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

На прошлом pgday Олег Бунин выступил с речью, в которой было сказано много правильных вещей о том, что PostgreSQL, несмотря на всю свою крутость, незаслуженно мало используется в проектах. Приводились разные причины, с большинством из которых я полностью согласен.

Но! При этом Олег привел пример из своей практики, когда он скрепя сердце посоветовал своему клиенту использовать для нового проекта MySQL, потому что нельзя вот так взять и всю команду (которая уже умеет мускуль) с нуля переучить писать на PostgreSQL. Мало книг, курсов, и т.д. И в итоге бизнес от этого пострадает.

Я считаю, что это не совсем соответствует действительности.

Возьмем типичный проект на MySQL. Что там используется? В 99% случаев это простейшие запросы, потому что в этой базе пока что нет ни рекурсивных CTE, ни оконных функций (хотя планируют в будущих версиях), ни кастомных типов данных, ни продвинутой работы с массивами, ни индексов по выражениям, и т.д и т.п.

Давайте проведем сравнение синтаксиса простых запросов на разных базах.

MySQL:

SELECT name FROM users  WHERE id = 5;
UPDATE users SET name = 'Иван' WHERE id = 5;
INSERT INTO users (name) VALUES ('Петя');

Postgres:

-- внезапно
SELECT name FROM users  WHERE id = 5;
UPDATE users SET name = 'Иван' WHERE id = 5;
INSERT INTO users (name) VALUES ('Петя');

Этого функционала уже достаточно, чтобы написать очень много чего.

Ну ладно, ладно, есть некоторые нюансы.

В MySQL сложные идентификаторы можно экранировать с помощью `, а в посгресе для этого используется » (поэтому в строковых константах надо использовать одинарные кавычки)

В MySQL используется INSERT IGNORE…,
в posgres INSERT… ON CONFLICT…

В посгресе нет функции INET_NTOA, но есть куча способов как сделать тоже самое другими путями.

В MySQL термин называется DATABASE, в postgres тоже самое называется SCHEMA.

В MySQL вам надо писать BIGINT AUTO_INCREMENT, в посгресе bigserial

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

Но скажите, разве так немыслимо сложно разобраться в кавычках и других мелких нюансах?

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

И это отлично подтверждает практика: множество проектов так и переехали на postgres: сначала всё писали как привыкли 1:1 как на mysql, и только потом, по мере изучения разных фич, стали внедрять новый для себя функционал.

Еще один аргумент часто слышу: «О, ну это какой-то космолет, который я не осилю. Все эти CTE и Partial индексы, лень всё это изучать. Моему проекту достаточно возможностей MySQL ».

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

— упрощать сложнейшие запросы с помощью CTE
— делать сразу много всего одним запросом с помощью оконных функций.
— Возможность сделать несколько CREATE TABLE, ALTER TABLE и т.д. в рамках транзакции (и откатить на середине, если что-то пошло не так)
— CREATE INDEX CONCURRENTLY (создавать индекс на больших таблицах, не насилуя базу)
— Materialized View
— Индекс по выражению (вместо генерации и поддержки отдельной колонки для этого дела)
— Partial Index (для ускорения некоторых запросов или, например, для обеспечения уникальности по условию)
— и еще куча разных индексов (gist, gin, brin и т.д).
— работа с массивами, например использование функций unnest и array
— Репликация hot standby
— Наследование таблиц
— кастомные типы данных и правила по конвертации (create type, create cast). Куча расширений сделано на этот счет, например тип ip4r позволяет легко и быстро работать с диапазонами ip адресов (поиск ip в диапазонах можно индексировать gist-индексом)
— кастомные операторы (CREATE OPERATOR). Сам еще не пробовал, но смотрю в эту сторону
— хранимые процедуры на разных языках, например на javascript (plv8) или python
— время с таймзоной (timestamp with time zone)
— быстрое удаление и добавление колонок в таблицах
— индексируемый json (тип jsonb)
— проверка валидности данных через check (в нем можно, к примеру проверить наличие/отсутствие необходимых элементов в json)
— сиквенсы вместо auto_increment (можно делать зацикленные, общие для нескольких таблиц и т.д)
— Foreign Data Wrappers — можно заджойнить в одном запросе таблицу из посгреса, из mysql и csv-файл
— и еще 100500 других фич, расширений и даже форков. Я работаю с посгресом уже давно, но постоянно открываю новые возможности.

Справедливости ради нужно заметить, что mysql, кажется, начал хорошо развиваться и избавляться от легаси. Т.е то, что было в 5.5 и то, что есть сейчас — это уже существенная разница (например, strict mode по умолчанию). Говорят, в следующей версии откажутся от использования myisam в системных таблицах, добавят CTE и оконные функции — это большой шаг вперед. Но субъективно пока что это всё равно очень и очень сильно далеко позади посгреса. Который, тоже, в общем-то, не стоит на месте (wiki.postgresql.org/wiki/Todo)

Всё, что написано выше, справедливо с точки зрения разработчика. С точки зрения админов и дба базы отличаются, тут уж ничего не скажешь. Впрочем, для простого проекта опять же достаточно гугла и stackoverflow.

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

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

P.S. Если меня читают DBA, пожалуйста, напишите на хабр внятную статью для новичков «Как поставить и настроить PostgreSQL. Основы.». Имхо такая статья очень нужна.

© Habrahabr.ru