Здравствуйте, уважаемые подписчики и гости канала!
Зачем это все?
Начать стоит с того, что стоит спросить - а зачем это все, если функции уже есть в вашем любимом языке программирования и можно просто выбрать данные из БД и как-то их обработать?
Сразу скажу, что у меня есть еще одна статья на тему функций, но там про триггерные процедуры в БД, т.е. типа хуков на INSERT, UPDATE и пр. Если ваш вопрос скорее про них, то вам надо перейти по этой ссылке.
Ну, для начала, стоит отметить, что лучше всего для БД, чтобы данные обрабатывались там же, где и хранятся, а именно в БД. Кстати, примерно также думали разработчики БД Tarantool на сколько мне известно. Конечно это не касается историй в кешами уровня приложений, там вообще отдельная история.
Почему же так важно бывает обрабатывать данные именно в БД? Тут простой ответ, возможно, вас огорчит - просто для производительности. Возьмем обычное не супер энтерпраиз приложение без 1TB данных (хотя и на нем все будет норм). Не круто, когда у вас приложение сперва выбирает 100 строк кода из БД, а потом через вашу любимую ORM отправляет это обратно в БД для другой выборки. Хорошо, если БД все это сделает одним запросом так как накладных расходов просто будет сильно меньше.
А функции нужны как обычно для инкапсуляции логики, когда вам надо использовать одно и тоже во многих запросах. Например какая-нить функция, которая возвращает доступных клиентов для указанного id пользователя. Вместо того, чтобы кидать базе огромный запрос, возможно с join-ами и union-ами (как только менеджеры войдут во вкус с ACL так оно и будет), вы можете просто убрать запрос в хранимую процедуру (функцию) и в дальнейших запросах в БД использовать ее.
Функции можно делать:
- просто из SQL запроса, но на практике это редко надо
- что-то изотерическое и у меня из опыта не очень стабильно работающее типа plpythonu, plv8 . Стоит отметить, что эти расширения во всяком случае раньше считались unsafe и приводили к крашу БД в случае не очень достойной обработки исключений в коде функции. При этом plpythonu меня во многом спас в свое время. На нем даже в API ходили и потом в таблицу сразу сохраняли, но в целом это продержалось 1-2 года. Не рекомендую так делать, если есть другие варианты.
Я начал записывать курс по PostgreSQL. После прочтения статьи обязательно переходи в видео, посмотри, подпишись, влупи лайк и колокольчик. От меня - лучи добра и новые видео.
Подборка видео всех видео по PG - https://dzen.ru/suite/37b67ffa-176d-493a-b1a8-4762f79e3753
Пример использования
Пример покажу попроще с SQL. Про plpgsql стоит почитать самому тут.
Так вот например небольшая функция, которая используется для понимания можем ли мы отправлять пользователю нотификацию определенного типа.
В принципе маленькая и могла бы быть запросом, если ни одно НО - используется он в разных запросах и да, конечно, можно было бы генерить код и клеить его в запрос, которому нужно узнать можно ли пользователю что-то слать, а можно сделать вот так красиво:
БД сама прекрасно будет оптимизировать ответы от функции и там есть много много настроек. В общем я, как говориться, накидываю идеи и примеры, а вы сами думайте поможет оно вам или нет.
При этом я не предлагаю для всего писать по функции, это скорее для каких-то редких случаев и только тогда, когда функция не сильно часто меняется, иначе будет неудобно. А как именно напишу ниже.
Транзакции в хранимых процедурах
Функции всегда работают в транзакции, запущенного запроса! Однако есть варианты с блоком EXCEPTION. Подробнее можно почитать тут.
Кстати, в PostgreSQL есть много прикольных фишек и кроме json, например у меня есть статейка про триггерные функции.
Минусы
Как обычно, куда же без них )
1. Добавление, удаление, изменение функции (CREATE, ALTER) делает с блокировкой и, если функция очень часто используется в нагруженной БД то у вас будут проблемки с изменением функции.
2. Вам нужен какой-то отдельный механизм патчей, так как классические будут неудобными потому, что в git вы будете постоянно видеть новый патч со свежей функцией, а хотелось бы видеть diff.
3. Перед применением функций для продакшена обязательно хорошо ознакомьтесь с модификаторами при создании функции. Если не изучить можно получить изумительные баги с отдачей кеша предыдущего результата.
4. Не все принимают такую парадигму, поэтому я и писал, что с этим делом надо очень очень аккуратно.
Заключение
Как и любая технология - это просто инструмент и только вы можете понять на сколько он вам подходит. У меня не проекте есть всего три функции, две из которых про ACL и они используются очень очень много где и это просто очень удобно.
---
А на этом всё, спасибо за внимание!
Подписывайтесь на канал, ставьте лайки, оставляйте комментарии - это помогает продвижению в Дзене.
Кроме этого:
Подписывайтесь в Telegram: https://t.me/lets_goto_it
#postgresql #functions #pg #plpgsql #бд #функциибд