Add new comment

"Если б я имел слона..."

О PostgreSQL я достаточно подробно упомянул в книжке "СУБД для программиста". Несмотря на явное лидерство SQL Server в приводимых примерах программирования работы с СУБД, PostgreSQL занимал почетное второе место. Однако на практике, поддерживая работу приложений с несколькими СУБД, я бы поставил PostgreSQL на "первое" место с конца. Почему?


Фото А.Сасин, газета "Орловская правда"

Есть поговорка, в оригинале про коня, звучащая примерно так: "Если б я имел слона, это был бы номер. Если б слон..." Да, если б слон, в обратном направлении, то "я б, наверно, помер".

Обеспечивая совместимость работы с постгресом, меня не покидает ощущение, что "слон" втайне планирует совершить описанные в поговорке действия. Не со злым умыслом, конечно. Но в итоге-то, какая разница?

Почитывая русскую фейсбук-группу по постгресу "Слон в ушанке", я было вознамерился создать традицию пятничного вопроса об очередной "особенности", которую даже как-то неприлично называть ошибкой. Не комильфо. "Это не баг, это фича!" (с)

Предположим, запускаете вы такой запросец на четырех СУБД

SELECT id, ' ' AS col1 FROM mytable

Какой будет тип возвращаемой колонки col1? Не спешите с ответом.

SQL Server, Firebird и Oracle возвращают честный char(1). PostgreSQL возвращает неизвестный тип. Действительно, какой же тип может иметь строковый литерал? Только неизвестный. Проблема обходится явным приведением к нужному типу.

Теперь запускаем другой запрос на четырех СУБД (для SQL Server используется "+" вместо "||").

SELECT surname || name AS full_name FROM persons

Пусть колонки surname и name имеют тип varchar(30). Какой будет тип возвращаемой колонки full_name? И снова не спешите с ответом.

SQL Server, Firebird и Oracle возвращают ожидаемый varchar(60). PostgreSQL возвращает text, то есть строковый безразмерный тип. Действительно, если соединить две строки, имеющие максимум по 30 символов, то в военное время общая длина в символах может оказаться больше 60. Проблема снова обходится только явным приведением к нужному типу.

Есть ли в постгресе бинарный тип фиксированной длины? Нет, надо использовать безразмерный bytea. Неважно, что у тебя, скажем, ключи или хэш строго по 32 байта и что ты хочешь через метаданные СУБД как-то отличить их от безразмерных колонок, хранящих документы в двоичном формате. Эта проблема, к сожалению, уже не обходится никак.

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

SELECT * FROM prices WHERE price > 10

Error: operator does not exist: money > integer

Прозрачное для приложений секционирование таблиц на уровне хотя бы SQL Server 2005? Нет, не слышали. Зато есть три других способа, возвращающих разработчика куда-то в бурные 1990-е.

Последние годы в постгрес вносится много изменений, связанных с поддержкой неполно структурированных данных (XML, JSON). Само по себе неплохо, конкуренция с MongoDB и компанией, но, как видно, такая эволюция идет в ущерб привычным реляционным подходам.

Резюмируя.

Если приложение разрабатывается с привязкой к СУБД, то выбор постгреса не будет ничем особенно хуже, чем других. Постепенно вы научитесь обходить щедро раскиданные грабли и освоитесь с местным колоритным "вуду". С поправкой на то, что под Windows придется попрощаться с производительностью, достижимой под Linux. Со слов самих разработчиков, поддержка Windows в постгресе реализована с помощью костылей и подпорок, так как уровень знаний внутренностей Windows у программистов был недостаточен.

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

Да, чуть не забыл. Вчера, 12 апреля, спустя 11 лет закончилась поддержка SQL Server 2005. С днём космонавтики вас!

См. также pgAdmin 4 или новые приключения