Pull to refresh

Comments 54

Таблица с рангами DBMS довольно точно отражает реальность.

PostrgeSQL не очень хорошо подходит для крупных банков и телекомов. Там очень специфический набор требований.

Очень популярная тема замены Oracle на PostgerSQL вызвана в первую очередь уходом компании Oracle из России. Не во всех случаях она оправдана. Вот потому крупные компании просто не могут быстро перейти на что-то другое. Тут целый комплекс проблем.

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

Проще всего рассматривать PostgreSQL как середнячок. Для больших задач недостаточен, для маленьких - тяжеловат.

А что вы подразумеваете под «тяжеловат для маленьких»? Поставить не проблема, поддерживать что-то тоже не проблема, использовать прямо приятно и к условному mysql возвращаться не очень хочется

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

условный mysql быстрее

Когда-то был быстрее.

На практике видел только один запрос на котором мускуль был сильно быстрее: UPSERT одной строки во времена Postgres 9.6 или 10. В среднем же постгрес позволяет ускориться в 1,5 - 2 раза без особых усилий, а если активно использовать массивы/полнотекстовый поиск/частичные и функциональные индексы, то местами и в 10-100 раз ускориться можно.

В мускуле даже любимый всеми like '%text%' индексы не использует и чёрт знает когда сможет.

и не создает отдельных процессов для каждого подключения

Какая разница сколько процессов, если мускуль жрёт намного больше оперативки?

"В мускуле даже любимый всеми like '%text%' индексы не использует"

А что, кто-то с таким лайком может использовать индексы??

Да, в постгресе есть стандартное расширение pg_trgm (триграммы)

select * from place_europe_spain where name like '%Sil%';
create index test2 on place_europe_spain USING GIN (name gin_trgm_ops);
+----------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN                                                                                                            |
+----------------------------------------------------------------------------------------------------------------------+
|Seq Scan on place_europe_spain  (cost=0.00..11652.56 rows=746 width=1535) (actual time=4.303..46.607 rows=152 loops=1)|
|  Filter: (name ~~ '%Sil%'::text)                                                                                     |
|  Rows Removed by Filter: 81253                                                                                       |
|Planning Time: 0.224 ms                                                                                               |
|Execution Time: 46.679 ms                                                                                             |
+----------------------------------------------------------------------------------------------------------------------+
+-----------------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN                                                                                                                   |
+-----------------------------------------------------------------------------------------------------------------------------+
|Bitmap Heap Scan on place_europe_spain  (cost=17.78..2347.91 rows=746 width=1535) (actual time=0.288..1.882 rows=152 loops=1)|
|  Recheck Cond: (name ~~ '%Sil%'::text)                                                                                      |
|  Rows Removed by Index Recheck: 175                                                                                         |
|  Heap Blocks: exact=294                                                                                                     |
|  ->  Bitmap Index Scan on test2  (cost=0.00..17.59 rows=746 width=0) (actual time=0.223..0.224 rows=327 loops=1)            |
|        Index Cond: (name ~~ '%Sil%'::text)                                                                                  |
|Planning Time: 0.333 ms                                                                                                      |
|Execution Time: 1.993 ms                                                                                                     |
+-----------------------------------------------------------------------------------------------------------------------------+

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

Именно для like '%%' коробочную поддержку завезли в 12 или 13 версии, но в форме регулярного выражения name ~ 'Si' в 9.6 из 2016 года уже работало, а в форме name ~~ '%Si%' вероятно работало аж в 8.3 из 2008 года.

Если устроит поиск по префиксу слов, независимо от места самого слова в строке, то есть полнотекстовый поиск to_tsquery('russian', 'Sa:*'). Тут магия в :*., сам индекс намного компактнее триграммного, можно ещё ускорить (1) сохраняя результирующий to_tsvector (2) добавив расширение на индекс RUM.

create index test3 on place_europe_spain USING GIN (to_tsvector('simple', name));
explain analyze select * from place_europe_spain where to_tsvector('simple', name) @@ to_tsquery('simple', 'S:*');
+------------------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN                                                                                                                    |
+------------------------------------------------------------------------------------------------------------------------------+
|Bitmap Heap Scan on place_europe_spain  (cost=32.62..4799.94 rows=1628 width=1535) (actual time=0.164..0.668 rows=152 loops=1)|
|  Recheck Cond: (to_tsvector('simple'::regconfig, name) @@ '''sil'':*'::tsquery)                                              |
|  Heap Blocks: exact=132                                                                                                      |
|  ->  Bitmap Index Scan on test3  (cost=0.00..32.21 rows=1628 width=0) (actual time=0.110..0.111 rows=152 loops=1)            |
|        Index Cond: (to_tsvector('simple'::regconfig, name) @@ '''sil'':*'::tsquery)                                          |
|Planning Time: 0.291 ms                                                                                                       |
|Execution Time: 0.802 ms                                                                                                      |
+------------------------------------------------------------------------------------------------------------------------------+

Нормально переваривает двухбуквенные префиксы (3-5 мс) и хоть немного, но ускоряет поиск по одной букве (10-30 мс).

Хотя мускуль 8.0 тоже индексы использует, но толку с них мало:

  • name = 'дубай'actual time=0.061..0.072

  • по префиксу name like 'дубай%'actual time=0.199..0.232

  • name like '%дубай%'actual time=205.801..228.952, в плане есть Covering index scan

  • name like '%дубай%' без индексов - actual time=19.382..277.397

>>> PostrgeSQL не очень хорошо подходит для крупных банков и телекомов. Там очень специфический набор требований.

Есть какие-то аргументы? Работал в одном проекте с более чем 100 млн пользователей - Postgres справлялся играючи.

Аргумент тут простой - Oracle ушел. Теперь его придётся менять на что-то. Использование PostgreSQL допускает какие-то частные решения. Но это не автомобиль, а только двигатель. Компаниям получить решение из одних рук гораздо проще. Они так привыкли. Русских компаний, которые могут предложить все набор технологий пока нет. Есть частные проекты.Есть сравнительно небольшие компании, которые ведут эти проекты. Я им удачи желаю, если что...

Высказываться по проектам, которых я не видел, я не могу.

Не понимаю аналогии автомобиль vs двигатель. БД - это скорее багажник, что Oracle, что Postgres.

Аналогия более чем прозрачна. Словa database engine обычно употребляют по отношению PostgreSQL. В реальной жизни помимо database engine, еще требуются самые разнообразные инструменты. Кому-то нужна система горячего копирования/восстановления, кому-то средства мониторинга и настройки производительности, кто-то желает иметь кластерную архитектуру, у кого-то время простоя является жизненно важным показателем... Никто не запрещает взять за основу database engine и выстраивать необходимые механизмы, комбинируя и дорабатывая существующие решения. Oracle Database содержит для решения подобных задач готовый набор модулей и многократно проверенный опыт. Потому работать можно быстро, решения готовы, но лицензии одни из самых дорогих в отрасли. PostgreSQL предлагает гораздо более скромный набор готовых решений. На лицензиях как раз можно сэкономить, но затраты денег и времени лягут на разработку и доработку отдельных решений. Некоторым кажется, что так дешевле. Но для разных задач этот подсчет будет разным. И всегда есть риск, что разработка новых модулей будет не вовремя и дороже чем планировали.

Ну теперь понятно, спасибо. Те самые люди, которые называют Postgres "engine", они или некомпетентны, или ангажированы, вот и несут чушь)

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

Разрабатывать ничего не нужно, "решение" уже готовое и рабочее.

Я то за свои слова отвечаю. Я это делал. Ну так раз у PostgreSQL "Бэкапы и мониторинг точно были " ... Можно ли сделать бэкап работающей базы без остановки работы в PostgreSQL? Я полагаю что нет. А это ставит крест на режим 24x7.

Вы неправильно полагаете.

Штатные утилиты pg_dump и pg_basebackupне требуют остановки работы сервера, не мешают работе клиентов, не блокируют данные. И так было всегда.

И это не исчерпывающий список вариантов сделать бэкап базы на PostgreSQL.

>pg_dump — extract a PostgreSQL database into a script file or other archive file

Это вы называете бэкапом? Вообще это называется dump.

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

pg_basebackup - это как раз классический backup. Так можно этим бэкапить при работающих транзакциях?

В связи с этими другой простой вопрос.

Если я живу в России, то кто мне продаст и за сколько, услугу по организации резервного копирования? Или научит штатного сотрудника.

Посмотрите в сторону pg_probackup. Если хотите отложенную репликацию, там посложнее, но за день-другой можно освоить.
"Продать услугу научить" могут курсы по постгре, сотни их.
Лицензии и поддержку — www.postgrespro.ru

Спасибо за содержательное сообщение.

Я извиняюсь. Я промахнулся и поставил минус вместо плюса

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

Не знаю насчет физической - но путь к логической репликации у Postgres щедро усеян граблями, причем передача и хранение пароля привилегированного юзера обычным текстом - самые маленькие из них. А когда вы научитесь эти грабли обходить и систему задеплоят в среду QA, где отдающая и принимающая схемы окажутся на одном хосте - база молча зависнет…

Мне кажется, что забыли про MongoDB рассказать как NoSQL альтернативу реляционным базам со своей нишей

Думаю, что в следующий раз будет) также тизерну Kafka;)

вы используете Кафку для ХРАНЕНИЯ данных?

ложная тревога) просто анонсировал, что будет материал про Кафку

Недавно была статья про кафку за 20 минут. В итоге, читал её неделю урывками

На СУБД Microsoft SQL оператор равенства ведет себя по-другому и возвращает TRUE, когда оба его операнда равны NULL.

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

Очень удобно когда настолько базовый оператор ведёт себя в каждой сессии по-разному /s

Сравнение, работа с датами и всякими -1 и null - то, на что тратится большая часть времени разработчика

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

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

Вот с коллейшеном засада конечно. В MS SQL по умолчанию он CI_AS, т.е. Case Insensitive — нечувствителен к регистру и нам это было удобно, а только для некоторых особых колонок в особых таблицах мы включали CS_AS (Case Sensitive). Как это покрасивее переложить на Postgre пока не придумал.

Спасибо за наводку, посмотрю поподробнее!

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

и знаменатель этот - ANSI NULL естественно, как и во всех других базах

Как, ну как можно не упомянуть самую распространённую БД, SQLite ??

Почему MySQL, а не MariaDB?

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

SQLite это удобный инструмент работы с одним файлом, своеобразный *.ini, *.cfg файл. Умолять его возможности тоже не стоит, обрабатывать миллионы записей для него непроблема.

>>Почему MySQL, а не MariaDB?

Этот вопрос тоже меня интересует, MariaDB быстрее во всём, репликациях, запросах, но видно Oracle есть тоже хочется.

Вот интересная статья https://habr.com/ru/companies/southbridge/articles/322624/ по ней MySQL вроде превосходит PostgreSQL. Для меня главным преимуществом PostgreSQL являются хранимые процедуры на SQL, pl/pgsql, javascript, (pl/v8), python, perl, lua ... на любом языке установленном на данной машине, что даёт ускорение при удалённом сервере PostgreSQL, но для php + MariaDB на одной машине это преимущество нивелируется.

SQLite файловая база данных, кто то пишет другой писать не может, блокировка доступа к файлу на уровне ОС

Во-первых, это неправда. Во-вторых, далеко не всегда мы активно пишем.

соответственно никаких сетевых соединений

А они и не особо нужны, если у нас микросервисная архитектура и весь обмен данных идёт через интерфейсы сервиса или messaging, то не-emeded БД скорее даже противопоказана.

А какие ещё актуальные СУБД Вы знаете, где есть какой-то внутренний ЯП для написания скриптов с выполнением внутри процесса сервера СУБД.

Я вот знаю из реляционных:

MS SQL Server: Transact-SQL (по мелочи) + IL (.NET) для более гибкой обработки + R для узко специализированной статистической обработки

Sybase ASE: Transact-SQL (по мелочи); не знаю есть ли тут ещё какие-то возможности ЯП для написания более продвинутых скриптов для исполнения на стороне СУБД

Oracle: PL/SQL (по мелочи - хотя чуть продвинутый чем Transact-SQL - ну тут у них свои плюсы/минусу) + Java для более гибкой обработки + JS (запускается через интерпретатор на JVM); есть вроде бы ещё базы, тоже использующие PL/SQL но навскидку назову только указанный в wiki: BM DB2; на JS насколько, я знаю ещё, может SAP HANA скрипты крутить, о инфы на эту тему почти нет, так что не уверен на 100%

PostgreSQL и иже с ними (форки): PL/pgSQL (по мелочи, по сути аналог PL/SQL - в чём-то уступает, в чём-то превосходит, но не сильно) + там целая плеяда расширений для скриптов на других ЯП от PL/Perl (родной ЯП для продвинутых скриптов на стороне сервера), до PL/Python, PL/V8, PL/Lua - в плоть до компиляции программ на чистом Си (и наверное на C++ тоже)

Так же для PostgreSQL у Googla есть расширение на её новом экспериментальном языке Logica - но это скорее альтернатива только языку запросов - тут продвинутую логику обарботки данных на нём не запилить :-( даже хранимые процедуры на нём не сделать (есть поддержка и для  Google BigQuery, SQLLite).

Есть ещё SQL/PSM стандарт хранимых процедур (модулей), по сути основанный на PL/SQL (по сути PL/pgSQL это и есть надстройка над SQL/PSM), применяемый например в MySQL

У MariaDB несколько отличный диалект, но есть опция поддержки PL/SQL

Но всё же мне больше интересны СУБД где можно писать функции и условно хранимые процедуры / триггеры на чём-то больше, чем вариации PL/SQL.

Из не реляционных вот в Tarantool можно писать подпрограммы на Lua.

А какие ещё есть продвинутые СУБД, где логику обработки можно вносить на сторону самой СУБД?

Вроде был какой-то тренд по к СУБД подключению логики на С/С++ но я не знаю где ещё кроме PostgreSQL это реализовано - наверное много где , но я просто не в курсе

В Firebird 3.0 была введена плагинная архитектура для расширения возможностей Firebird. Одним из таких плагинов является External Engine (внешние движки). Механизм UDR (User Defined Routines — определяемые пользователем подпрограммы) добавляет слой поверх интерфейса движка FirebirdExternal.

UDR могут быть написаны на любом языке программирования (необязательно
компилируемые в объектные коды), для этого необходим соответствующий External
Engine плагин. Например, существуют плагины для написания внешних модулей на Java или на любом из .NET языков.

Тем не менее, обычно рассматриваются варианты написания UDR на Delphi/FreePascal и на c++. По другим языкам инструкций не встречал, впрочем и не искал.

Для реализации бизнес-логики лично мне вполне хватает возможностей PL/SQL, что бы тянуть в проект UDF/UDR нужны ОООЧЕНЬ веские причины. Ибо все это становится платформо- и ос- зависимым, в то время как PL/SQL работает на любой версии сервера (точнее, под нужной версией сервера на любой поддерживаемой сервером платформе).

Спасибо за ответ.

Применение чего-то большего чем расширенного диалекта языка запросов обычно диктуется двумя, как ни странно, противоположными причинами (есть ещё третья - но она о другом):

  1. Желание ускорить логику обработки за счёт вынесения её в оптимизированный машинный код без необходимости интерпретации инструкций (хотя не знаю насколько сейчас медленнее идёт исполнение инструкций расширенных диалектов SQL, по сравнению с машинным кодом - может там тоже уже научились его JITить в машинный код, как это сейчас делается практически во всех ранее чисто интерпретируемых классических ЯП) - правда тут явно будут затраты на маршалинг данных из контекста СУБД в контекст библиотеки в машинных кодах - но это уже зависит от конкретной СУБД. Да - код не всегда может быть кроссплатформенным - хотя в той же PostgreeSQL вроде бы код даже на Си хранится компилируется из исходников под конкретную ОС сервера - так что это не такое уж сильное ограничение (там главное чтобы расширение СУБД для использования внешнего кода было доступно для целевой платформы).

  2. Желание перенести на сервер часть бизнес-логики - что особенно актуально если не используется трёхзвенная архитектура (WEB сервер не в счёт) - когда клиент напрямую обращается к СУБД (в WEB через WEB-сервер но он тут тонкий посредник). Писать бизнес-логику в XXI веке на диалекте SQL - это маразм. В этом случае можно и пожертвовать частью производительности и подключить более высокоуровневые ЯП - JS или .NET - зато код будет боле будет надёжным и более простым к созданию поддержке. Заодно и проще будет интегрироваться с другими системами и микросервисами. Но и в трёхзвенке это может быть востребовано - когда на сервер нужно вынести какую-то сложную обработку бизнес-логики или техническую часть - а желания заморачиваться с низкоуровневыми ЯП нет.

Третья причина возникает только в NoSQL базах - там возможности прямой системы запросов могут быть очень ограничены и за счёт отдельного ЯП реализуется более сложная обработка данных на стороне СУБД. Например в Tarantool это делается на Lua.

Можно ещё и четвёртую причину назвать для всех СУБД - это когда для какой-то логики обработки данных есть много библиотек на более классических ЯП, чем SQL - например сейчас такая тенденция наблюдается для Python и ML области - конечно сейчас чаще делают выборку из СУБД и далее обрабатывают данные на внешнем клиенте - но почему бы не делать наоборот - запускать обработку на стороне самой СУБД. Ну... тут, на самом деле всё просто - дешевле сделать несколько клиентов (условно прикладных серверов) - чем наращивать мощность сервера для СУБД. Но всё небольшую же часть логики можно было бы и на сторону СУБД выносить - сокращающую объёмы передачи данных и время на обработку - но это скорее для OLTP систем (чем для OLAP). Но тут тогда либо Си либо расширенный диалект SQL

Желание ускорить обработку логики путем переписывания с PL/SQL на иной язык, в 99% приведет к замедлению, или значительному замедлению, за счет лишних преобразований данных. Язык PL/SQL расчитан на максимально эффективную работу с данными. На том же Firebird, процедуры/функции на PL/SQL не интерпретируются при каждом вызове, работает предварительно скомпилированный байт-код.

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

UDR/UDF имеет смысл применять когда требуется функционал который отсутствует в PL/SQL, к примеру какая-нибудь сложная математика. В том же Firebird, во времена FB2.0 или даже раньше, UDF была актуальна для написания функций которых в PL/SQL не было. В более новых версиях FB значительно увеличили количество встроенных функций, и потребность в UDF практически сошла на нет. Механизм UDR значительно расширен по сравнению с UDF, но судя по общению в программистами на FB, практически не восстребован.

приведет к замедлению, или значительному замедлению, за счет лишних преобразований

Я же про это написал - тут речь скорее об сложной обработке большими порциями.

Из личной практики - перенос обработки данных из клиентского приложения в процедуру на PL/SQL на сервере в ряде случаев дает ускорение на порядки

Я это и не отрицал.

На том же Firebird, процедуры/функции на PL/SQL не интерпретируются при каждом вызове, работает предварительно скомпилированный байт-код.

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

Спасибо за это уточнение

с Pl/SQL и прочими SQL всё боле менее понятно.

А какие есть NoSQL СУБД с внутренним ЯП (кроме Tarantool c Lua)?

не знал (UDR) для меня главной фишкой Firebird были транзакции их аналога, я ни в одной СУБД не встречал

Почему-то в списке отсутствует Firebird/RedDatabase, в свете импортозамещения - это вполне актуальное решение.

Все перечисленные варианты под свободной лицензией?

да, решения распространяются свободно, но есть и платные версии

То есть базовый санкционный риск не должен реализоваться?

В части PG в России есть серьезные компетенции, сконцентрированные в компании PostgresPro, где работают несколько коммитеров ванильного PG. На данный момент они в состоянии поддерживать проекты любого масштаба.

У себя дома на мелких домашних проектах типа Home Assistant, NeхtCloud и тому подобных я перешел на PG, о чем ничуть не жалею. Несколько лет назад мне приходилось в качестве техдира поддерживать СМИшный проект на PG, как только поднял второй сервер БД и настроил нативную репликацию, поводов для беспокойства вообще не стало.

Но, конечно, желательно понимать в этом чуть больше чем docker run postgres ))

TimescaleDB тоже понравилось, удалось успешно применить в IoT для хранения и аналитики данных с сенсоров

да, TimescaleDB вообще оч интересное решение, в июле постараемся рассказать о его практическом применении подробнее

Пожалуйста, не используйте в Redis структуру List для сообщений. Это древний механизм чтения "из стека с блокировкой", не надо так (с)

В Redis уже давно есть publish / subscribe для рассылки сообщений в каналы подписчикам (сообщения не хранятся).

И уже года 4 как (с версии 5, текущая - 7) есть механизм Stream, функциональный аналог топиков Кафки. С хранением сообщений, чтением разными группами одного стрима с load balancing внутри группы, отдельным подтверждением обработки сообщения (ack), сбором полученных и не обработанных "потеряшек" и т.д. В результате получается очень быстрый и почти не требующий настроек брокер сообщений.

Кроме того, кроме самого Redis есть продукт Redis Stack от тех же авторов с кучкой очень полезных расширений (JSON storage с индексами и поиском по множеству ключей, например). Плюс админка :)

спасибо! коммент отлично дополняет материал

Sign up to leave a comment.