Дмитрий Кутейников

Дмитрий Кутейников 

Программист, технарь и самую малость - графоман

55subscribers

180posts

goals1
7 of 100 paid subscribers
Для начала. Возможно, в какой-нибудь параллельной вселенной, я смогу заработать писательством на жизнь, и уж тогда...

Про честный SQL и вычисления для бизнес-аналитики

Есть чудесная поговорка: "не только ботинок по ноге, но и нога по ботинку", и другая, тоже в тему: "если у вас в руках молоток - все проблемы выглядят как гвозди".
SQL появился очень давно - когда инженеры ещё не привыкли, что в мире информационных технологий всё меняется быстрее, чем успеваешь кофе попить, а потому спроектировали его тщательно, вдумчиво и строго. Есть таблица, есть разнообразные нормальные формы (из институтского курса помню, что их никак не менее шести, но в реальных задачах обычно безальтернативным выбором является третья), есть строгие правила объединения данных (всякие RIGHT/LEFT/INNER/FULL/прочие JOIN), строгие правила конвертации (включая кодировку для строк), строгие правила фильтрации (всякие WHERE [xxx].[yyy].[zzz] = 'Q' со всякой булевой алгеброй в условиях)...
Суть в том, что сам SQL спроектирован под работу с табличными данными: у таблицы есть сколько-то столбцов разных типов, в таблице есть некоторое произвольное количество строк и мы некоторым образом (по каким-то условиям) выбираем (и иногда по каким-то правилам группируем) подмножество строк/столбцов этой таблицы. Чтобы было интереснее - есть те самые JOIN и другие страшные операторы (я уже порядочно позабыл, что нам в институте рассказывали, ибо, слава Богу, не DBA, а классический программист), всякие хранимые процедуры и VIEW - но всё равно это сводится к "получить некоторое множество строк некоторого множества столбцов". На самом деле, это гораздо сложнее, чем выглядит, и гораздо мощнее, чем можно было бы ожидать от такой простой формулировки - в частности поэтому классические СУБД живут и здравствуют и совершенно не собираются никуда уходить несмотря на огромное количество концептуально новых подходов к хранению и обработке данных - всякие "No-SQL" (учитывая, что SQL - это Structured Query Language, язык структурированных запросов, "No-SQL" - это обман в названии, там тоже есть язык запросов и он тоже структурированный).
Описанная концепция SQL позволила его очень качественно формализовать и разработать массу разных решений (в математическом смысле) для решения разных прикладных задач. Если брать бизнес-аналитику - например, какой-нибудь средний чек - то задача формализуется как "подсчитать количество уникальных чеков и их общую сумму и поделить второе на первое". Под это же адаптируется структура хранения данных, когда один чек записывается как несколько строк таблицы - по одной на каждый товар в чеке (что-то вроде кортежа {"идентификатор чека", "артикул товара", "количество товара"} - и потом из справочника товаров через упоминавшийся выше JOIN можно подтянуть цену единицы товара, а в ещё одну таблицу потом записать {"идентификатор чека", "дата-время покупки", "идентификатор кассового аппарата", "способ оплаты", "код скидки"} или как-то так, и ещё всякие дополнительные данные, размазанные по СУБД - магазин, например).
Главное же я уже написал в самом начале, про ботинок и молоток. За многие десятилетия разработчики программ, работающих с данными, неописуемо глубоко привыкли к SQL - к его возможностям и ограничениям, а вслед за ними - и пользователи этих программ. Привыкли даже не к тому, что есть запросы простые и сложные, и поэтому их надо сообразно оптимизировать и костылить всякие индексы, а к тому, что запросы вообще есть. В смысле, "запросить подмножество строк по неким критериям" (так-то "запрос" как термин имеет много применений, но здесь речь именно про SQL). То самое "но и нога по ботинку" - люди привыкли к ограничениям SQL и уже сами формулируют свои желания в такой форме, чтобы их было проще переложить на SQL. Когда люди только начинают анализировать свои данные, они как правило честно говорят, что хотят получить, но приходит матёрый DBA и говорит, мол, так и так, это посчитать сложно и долго, но можно вот эдак извернуться и получить почти то же самое, только в профиль, и опытные аналитики уже не пытаются запросить то, что они хотят на самом деле, а берут то самое "почти то же самое, только в профиль" и старательно щурят глаз, пытаясь увидеть искомое. Со своей стороны разработчики ("молоток") все задачи пользователей уже тоже воспринимают через призму возможного (нормальный инженерный подход, между прочим). Однако, очевидно, что не всё можно посчитать в терминах таблиц - в некоторых случаях, внезапно, возникает комбинаторный взрыв, например, или случаются другие неприятные истории.
Для анализа данных, который не хочет дружить с SQL, придумали OLAP. Концептуально у нас есть Н-мерное пространство (по числу столбцов данных) и каждая строка SQL-таблицы превращается в точку в этом Н-мерном пространстве, координатами которой являются значения соответствующих столбцов на этой строчке, и таким образом вся таблица превращается в множество точек этого Н-мерного пространства. На первый взгляд променяли шило на мыло, но на самом деле выигрыш есть: от плоских линейных таблиц мы переходим к матрицам (сильно разреженным, к слову) и можем использовать ДРУГОЙ математический аппарат - который, возможно, не так хорош там, где уже хорош SQL, зато лучше там, где SQL не справляется. К слову, где-то здесь рядом пробегают те самые уже упоминавшиеся No-SQL СУБД (я с ними дела не имел и представление о них имею весьма поверхностное). Основная проблема OLAP - сильно разреженные очень многомерные матрицы дико громоздки в хранении и очень тяжелы в обработке. Есть разные способы это всё оптимизировать и ускорить, но задача это весьма нетривиальная.
Изучая вопрос OLAP я наткнулся на некий OLAP-движок, который очень хвалили, который работал поверх sqlite в памяти и позволял обрабатывать, если мне не изменяет память, что-то около 60 тысяч строк (Н-мерных точек). От души посмеялся. "Полиматика" выполняла аналогичные операции у меня на ноутбуке (далеко не самом топовом на тот момент) в виртуальной машине (ибо под линукс) на 50 миллионах строк за единицы-десятки секунд - это был "малый тестовый набор данных", те самые 60 тысяч строк были отладочным объёмом: запустить тест и получить результат примерно мгновенно. На "взрослых" серверах, как я уже упоминал раньше, "Полиматика" вполне уверенно крутила 400-500 миллионов строк и довольно решительно замахивалась на 700-800 милиионов (правда, на таких объёмах время обработки сложных реальных запросов уже нередко вылезало за пару минут).
"Rapeed", как, в частности, развитие идей "Полиматики", исходно проектировался именно под бизнес-аналитику. К сожалению, я не могу рассказать, как именно мы добились своей фантастической скорости работы, но могу обрисовать направление нашего движения: мы решали конкретные задачи конкретных сценариев. Тот самый средний чек, упоминавшийся выше. Или связь многие-ко-многим, часто нужная для анализа кто что и у кого покупает в сложных цепочках поставок. Сведение остатков с продажами и планами закупок/продаж. Совершенно конкретные прикладные задачи, с совершенно понятной математикой (даже арифметикой, евпочя), и многие - весьма "поперёк" логики классического SQL. И очень тяжёлые в логике OLAP (хотя и лучше, чем в SQL).
Пару лет назад или около того Meta* (категорически осуждаю) пыталась разработать свой движок распределённого OLAP с прицелом на ответ менее, чем за секунду (даже, кажется 100мс). Самое забавное - они его сделали и выкинули (в смысле, в помойку, а не на рынок). Причина предельно простая: они позвали математиков (причём хороших, я читал эту статью), а надо было звать инженеров. Да, они получили ответ по миллиарду строк менее, чем за 0.1 секунды на десятке серверов, но он никому не сдался за такие деньги. Rapeed даёт ответ за единицы-десятки секунд, но при этом считает этот ответ на трёх серверах о 80 Гб оперативки каждый по полутора миллиардам строк данных - и это я говорю не про что-то простое (вроде подсчёта количества уникальных чеков), а про весьма затейливые вещи: когда в таблице сверху год и под годом квартал, а слева - иерархия категорий товаров от самого верха до самых артикулов и в каждой клеточке точно посчитано искомое, при этом снизу итоги по тем годам/кварталам, справа - по иерархии и товарам и всё это можно раскрывать и схлопывать за те самые единицы-десятки секунд (причём это только в самый первый раз - повторные раскрытия/закрытия обрабатываются за доли секунды), и на эту же таблицу наложены данные какого-нибудь плана - правда, разумеется, видны они только на том уровне детализации, на котором план написан (ну и иерархически выше, разумеется). Если интересны именно практические прикладные примеры - это лучше посмотреть ролики реальной работы системы, их есть в интернете и они без монтажа, ибо система работает достаточно быстро.
Я про прикладное применение особо рассказать не могу - я программист, я пишу код.
* Компания Meta Platforms Inc. признана экстремистской организацией и запрещена на территории Российской Федерации.
Subscription levels3

Поддержать голодного программиста!

$0.4 per month
Спасибо за моральную поддержку! Она для меня ОЧЕНЬ важна!

Поддержите молодого (нет) графомана

$1.32 per month
ВСЁ И СРАЗУ!
Ничего ждать не придётся, весь платный контент будет выкладываться именно на этом уровне и через неделю падать ниже.

Две шавермы

$5.3 per month
Всё ровно то же самое, что и на предыдущем уровне, ибо я так и не смог придумать, что бы такое осмысленное добавить.
Специально для тех, кто хочет поддержать более решительно.
Go up