О 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 или новые приключения