Активно ли разработчики пользуются встроенными в Postgres функциями?
Читаю документацию к Postgres и удивляюсь невероятному количеству функций. Чего там только нет. Одних только вариантов оперирования датами на несколько листов. Такое ощущение, что все эти функции могут с легкостью подменить самого разного рода вычисления в коде какого-нибудь языка программирования. Мне кажется, что запомнить такое количество функция просто нереально. В связи с этим вопрос: активно ли разработчики пользуются этими функциями, подменяя ими вычисления, написанные на языке программирования (Java, Python, Ruby, PHP...) или же, все-таки, по большей части все преобразования/расчеты/вычисления пишутся/выполняются не с помощью встроенных и написанный в Postgres функций?
ну а как вы себе представляете сделать какую нибудь хитрую выборку по датам через язык программирования? выбрать все из базы и там обработать? ну если у вас 100 записей - не вопрос. А если пару миллиардов?
weranda, вот я 3 года назад делал рассыльщик почты - там в день 80 миллионов записей прилетает. И мне статистику манагеру по датам и времени как делать? Выбрать все и сидеть обрабатывать? до этого работал в CPA сети - в стате там миллиарды. Как бы вопрос где нет большого количества записей если исключить какие нибудь блоги и лендинг страницы?
Как бы вопрос где нет большого количества записей если исключить какие нибудь блоги и лендинг страницы?
Если вы про мой комментарий к вашему комментарию к вопросу, то да, интересно, что это за сайты/сервисы с таким количеством данных. В целом представляю, но это прям крупняк, которых в каждой стране одна-две сотни, наверное.
weranda, да везде. Даже если у вас магазинчик с 100 заказов по 5 товаров в день - у вас уже за 5 лет в базе миллион записей в таблице связки заказа с товаром. Если вы ведете статистику того что просматривали - то если представить что только 1% покупает то в статистике просмотров будет 100 миллионов. К вам пришел манагер и говорит хочу понять в какой день недели у вас чаще всего просматривают категорию памперсов - и вы пошли гуглить extract. Пришел манагер и сказал выбрать стату средняя разница у пользователя между просмотром и покупкой товара - и вы пошли гуглить какой нибудь datediff.
З.Ы. При этом вообщем то вопрос к чему? Вы собираетесь зубрить все эти функции? Зачем? Главное знать что может делать ваша СУБД, и понимать какую цену вы за это будете платить. Остальное можно посмотреть в документации
Дмитрий, Мне еще практически интересно понять. Вот вы, как я понял, хорошо понимаете в Postgres. Вы все функции, описанные в документации, знаете (помните на память) или только какую-то часть? Наверное, часто, все-таки, приходится обращаться к документации!?
weranda, слушайте по моему глубоком убеждению человек который сидит и высчитывает какой процент функций из какого то языка программирования он знает, а какой нет - наверное программистом не является. По-этому сказать помню ли я большую часть функций постгресса или меньшую я вам не смогу. Пусть будет меньшая часть.
Но я повторю свой посткриптум:
При этом вообщем то вопрос к чему? Вы собираетесь зубрить все эти функции? Зачем? Главное знать что может делать ваша СУБД, и понимать какую цену вы за это будете платить. Остальное можно посмотреть в документации
Смысл в развитии кругозора по вопросу. Смотрю, вижу сотни и сотни функций. Такие там есть, что кажется, что база нужна в первую очередь для научных вычислений или создавалась во многом именно для этого направления. Мне кажется, самих разработчиков спроси обо всех — не ответят. Могу ошибаться, но пока кажется именно так.
* что-то много «кажется» у меня)
Кину 5 копеек по поводу работы с датами. Да это зло. Работа с датами в современном API это
самый большой технический долг начиная с Unix, когда дата представлялась секундами с 1970 года
в виде DWORD. Я не встречал ни одного языка программирования и ни одной DBMS где изначально
была-бы какая-то очень строгая и математичная концепция работы с временем. Везде были ограничители
в основном завязанные на примитивные типы либо на строки вариативной длины. В Java например
долгое время экплуатировался тип java.util.Date который сегодня считается дыркой (мутабельность)
и неточным и его заменяют на java.time.* семейство типов. Параллельно с ним где-то в космосе
висит java.sql.Date который декларирован в интерфейсах JDBC как основа для БД. С ним-же и работают
все драйвера реляционных бд.
По поводу вычислений на application tier. В последнее время DBMS девальвировали. И в основном
используются в микросервисах как хранилище таблиц без особой логики. В этом есть свои смыслы.
Например удобнее тестировать и хранить 100% кода в языках Java/Node/C#. Это создает гомогенность
языка в проекте. В противном случае логику пришлось бы неизбежно резать на 2 слоя и хранить
половину в application и другую половину деплоить через flyway/liquibase в БД при этом еще и
не забыть тестировать 100% совместимость тех-же функций для работы дат-времени (никто
кстати невкурсе что в Oracle год может быть 9999 а java.util.Date мне удалось сгенерировать
такую Aug 17 09:12:55 EET 292 278 994. .. оптимистичненько доживем до 290 миллионов
лет хотя проблема comparison этих типов остается) Стандарты ISO помогают но они скорее
декларируют намерения сохранить нужное значение. Вот и если вы новичек - то я гарантирую
что вы словите кайф в попытке в Java разобраться в проекте какой тип дат вам брать. И еще
помножите это все на типы данных БД (их там будет 4 штуки обычно. Парочка для зональных
и парочка для локальных).
Использовать или нет функции PG? Ответ - it depends. В некоторых случаях оптимизатор не видит
индекса если ты делаешь неявный кастинг из строки в дату например. Я тут не уверен надо проверять.
Но есть старая админская поговорка. Плохой execution plan - проверь типы данных в предикатах.
Беда реально существует для Spark/Databricks и даже включена в учебный план. По крайней мере int/Long
различается на уровне Catalyst-optimizer. Вобщем если вы - лентяй то можете лупить строки вместо дат
и надеятся что SQL машина правильно интерпретирует. Если вы хотите быть точным то делайте CAST или
to_date с явным описаловом YYYY-MM и т.д.
Еще один поинт в части где хранить логику. Это я пишу просто для кругозора. Чтобы топик
не циклился вокруг Постгреса а люди видели пошире. В классических БД данные качаются
к клиенту. Тоесть делаете SELECT * из миллирад строк - и этот миллиард будет прокачан до конца
когда вы читаете резалт-сет по сети. Такова парадигма. Или курсор. Но суть таже. А в BigData данные
лежат на месте но к ним "ходит" код. Вот такой метафизический парадокс. Сами понимаете что
тут получается что встроенных функций даже как бы ... и нет. Подчеркиваю разницу.
Еще вспомнил одно наблюдение. Лет 10 назад я словил баг в коде биллинга для мобильного оператора.
Функция считала услуги за интервал в сутки. Как-то так было ... WHERE dt BETWEN dbbegin AND dend
Конструкция - типичная для БД. К сожалению закрытый интервал при tumbling window
(кувыркающееся окно) захватывал лишнюю секунду. Наивное решение возникло - вычитать
одну секунду из dend. Ошибка на какое-то время ушла. После того как логика была перенесена из
бд в application внезапно я словил новый артефакт. Дата время были с точностью до милисекунд.
Как тут быть. Вот мне еще не хватало думать об ошибках округления. Или учитывать последнюю милисекунду.
Я плюнул и решил что если закрытый интевал мне не подходит то пускай будет полу-открытый. ... WHERE dt >= dbegin AND dt < dend
Этот код работал как надо для любых точностей. Математика оказалась полезнее чем ломка
башки над типами данных.
mayton2019, как раз недавно столкнулся, разработчики умудрились парсинг даты сделать не thread-safe, отчего внезапно 2023 год в двух одновременных запросах превратился в 23000 и не смог упихаться в базу Oracle :) При этом что этому коду вероятно больше 10 лет уже, и вообще чудо, как раньше на это не напарывались при трафике 3 миллиарда запросов в месяц. Кстати, случилось это на инстансе клиента, который делает меньше 100 запросов в сутки.
Я давний сторонник производить все вычисления на стороне клиента.
Проще переползать с базы на базу, не загружаем ресурсы базы, проще параллелить, поддерживать, отлаживать.
Тоже самое относится к хранимкам и триггерам, это вообще считаю за зло в современом мире. Нет триггерам и хранимкам!