Я не верю, конечно, ни в какую демократию (кроме оригинальной афинской 2½ тысячи лет назад, где кворум состоял из трёх с половиной образованных богатых неглупых людей, а остальные были безголосыми рабами и женщинами). Как я уже где-то говорил, существуют исторические свидетельства того, к чему привели первые проявления этой самой демократии: пару тысяч лет назад люди проголосовали распять одного там назаретянина.

Поэтому когда в качестве аргумента за ту, или иную парадигму, — я вижу какие-то индексы, голосования и прочую статистически значимую оценку vox populi, меня это раздражает. «Миллионы мух не могут ошибаться» — так себе аргумент. Поэтому мнение «коммьюнити разработчиков» — практически всегда облыжное, поверхностное, и, в целом, неверное. У каждого в руках свой молоток, а про многообразие саморезов люди en masse если и слышали, то краем уха и в качестве анекдота.

Если экстраполировать мнение большинства и принять его за аксиому, то в мире будут существовать только банковские приложения и круды с базами данных в качестве узкого места и дополнительными серверами вместо корректного горизонтального масштабирования. Тем не менее, многие даже в своей работе используют инструменты, которым никакая база не требуется, а обеспечение роста гарантируется размазыванием нагрузки по кластеру, а не приклеенными (sticky) сессиями. И я говорю не про десктоп.

Сто́ит заикнуться про недостатки ООП в высококонкурентной среде — две трети комментаторов расскажут, как я бездарен в работе с базой данных. Алё, гараж, какая база? Нет никакой базы, в данной постановке задачи. Это приятно (и очень удобно) просто полагаться на умных людей из PostgreSQL, которые вылизали и протестировали базу на объёмах, до которых ваши «Рога и Копыта» даже в опиумном сне не приблизятся. Но, ёлки-палки, даже постгрес заткнётся рано или поздно. Вы не сможете просто сохранять всё тупо в базу: в пределах 40÷100 соединений она живёт хорошо, но если к вам приплывает 10К «данных» в секунду, придётся изворачиваться без базы.

Кафка! — Скажут мне лентяи из соседнего отдела. Да, тут кафка, скорее всего, спасёт, но ведь всё равно придется написать код, который будет как-то преобразовывать сообщения из входящего потока, мы же не просто пылесос разрабатываем. Так зачем этому коду тогда кафка?

Вспоминается, как однажды я решал задачу оффлоада горячего кэша в ситуации rolling update контейнеров, и коммьюнити мне хором посоветовало: редис. То есть, у меня уже́ есть вся инфораструктура для абсорбции и обработки входящего потока, но чтобы пережить rolling update — мне на полном серьёзе предлагают втащить в проект какое-то дополнительное чудовище, которое надо будет настраивать, мониторить и вообще всячески обихаживать. Это нонсенс, что такая мысль в принципе приходит в голову людям, называющим свою профессию «разработчик». Не «пользователь», заметьте! — но «разработчик».

Лет 8 назад наша контора использовала сторонний сервис для пабсаба (рудимент первых дней стартапа). За две недели до обновления контракта, они прислали нам письмо, что стоимость сервиса выросла. Причем не на обычные 3–5%, а в десять с лишним раз. За три дня мы с коллегой полностью повторили их функциональность, и наше решение с тех пор работает в продакшене, с перезапусками только ради обновления операционки на следующий LTS.

Дело не в том, какие мы молодцы, а в том, что это было тривиально. Просто почему-то все предпочитают взять базу, редис, кафку — вместо того, чтобы прикинуть, что проще: поддерживать чужое решение, или создать своё.

База — штука полезная, спору нет. Если надо хранить данные пользователя — лучшего места не найти. Один раз в год записали, три раза в день прочитали. База идеально с этим справится.

Но мы начинаем использовать базу вместо волшебного кувшина, запихивая туда всё, буквально всё, только чтобы не следить самим за консистентностью данных. Даже если эти данные — вре́менные. Данных много (даже не много, а, выражаясь техническим языком, — дохренища). Начинаются гонки. Умные чуваки из числа авторов кода этой самой базы придумывают механизм транзакций. Транзакции решают вчерашние проблемы, но создают новые — неожиданными дедлоками в непредсказуемых местах. Появляются оптимистичные и пессимистичные локи. Каждому, кто сейчас скажет: «Нужно просто научиться работать с базой, салага!» — я отвечу: «Я-то умею. Но не хочу. Это не забота разработчика, разруливать дедлоки в непредсказуемых местах работы стороннего сервиса, которого тут вообще не должно было быть, для начала!».

Конечный автомат? — В базу! Получили сообщение от стороннего сервиса? — В базу! История изменений состояния? — В базу! База пухнет. Становится, как говорят светлые человечки, жирненькой. Увеличивается число соединений. Мы начинаем в совершенно неочевидных местах ловить исключения «таймаут при попытке получить соединение». Нас лишают премии, выдают остраку и приковывают к позорному столбу в центральной переговорке.


Попробуйте поставить мысленный эксперимент: вот у вас есть база. Что оттуда можно выбросить (перенести в исходный код приложения) — без потери общности? — Если у вас получилось меньше двух третей общего объема — думайте еще.

Умные люди придумали в свой время (довольно давно) такой способ хранения информации, как Event Log (его еще иногда называют Event Source). Должной популярности он не обрёл, потому что разработчики — твари косные, ленивые и нелюбознательные. Принципиальное отличие от классической релиционной базы данных у него такое: вы в него пишете на каждый чих, но почти никогда не читаете. Это позволяет сохранять буквально все движения, случившиеся с данными. Но есть нюанс: чтение дороговато, да к тому же нужно «воспроизвести» все шаги с момента создания объекта, а они могут быть в общем случае не только не чистыми, но и не идемпотентными. Это фиаско.

При этом, почему-то, мне не доводилось слышать об удачно осуществленных симбиозах реляционных СУБД для «статической информации» (данные пользователя, результаты платежа, и т. п.) с ивентлогами для всего остального. В идеальном случае — читать из ивентлога не придётся никогда. В неидеальном (приложение упало в процессе совершения перевода денег со счета на счет) — придется развернуть записи из ивентлога для воссоздания состояния объекта «незаконченный платёж» в памяти перезапущенного приложения. Но весь этот мусор, не имеющий даже исторической ценности, с переходами по состояниям, — в базе никому не нужен.

Ладно, если вы — банк, то нужен, конечно (в принципе, он всё еще есть для отчетности в ивентлоге, так что еще бабушка надвое сказала, имеет ли смысл тащить его в базу). Но это просто пример. Замените платёж на запись в блоге. Хороший движок сохранит все версии. Но в 99.99999% случаев потребуется только одна — последняя. Вот её и надо хранить в базе.

Я реализовал такую модель (и даже описал её тут). Библиотека (фреймворк) всё пишет в кликхаус, и экспортирует все ивенты, если кому-то надо сохранить что-то в СУБД. И знаете, что? Когда я начал думать, что же мне прям надо хранить в базе — ответ оказался простым: да ничего.

Долгоживущие процессы эрланга вычитывают состояния всех сущностей в свой стейт, обрабатывают его, и завершаются, когда сущность «обработана». Я гарантированно не потеряю ничего, при любых, самых заковыристых сбоях (наподобие сетевого сплита, или битого сектора на физическом носителе). А для первоначальной вычитки состояния в стейт процесса — я просто создал materialized view для каждой таблицы (сущности).

Так что, каждый раз, когда вы начинаете мыслить вместо категорияй данных — понятийным аппаратом «базы» (транзакции, джойны, и так далее) — я предлагаю остановиться и подумать: а точно ли тут нужна база? Да, иногда нужна. Но далеко не настолько часто, как вам кажется.

Удачного ухода с первой базы!

Комментарии (14)


  1. ky0
    25.06.2025 07:31

    "Угадай автора по первому предложению."


    1. pnmv
      25.06.2025 07:31

      "Угадай комментатора по первому комментарию."


    1. hypercrite
      25.06.2025 07:31

      Интересно что эта ниша на хабре никогда не пустует. До купраера был nmivan, тоже с великими откровениями на основе невероятно ценного опыта в 1С, до него был, забыл уже ник, тоже просветитель невежественных масс.


      1. cupraer Автор
        25.06.2025 07:31

        Вот и ноунеймы повылезали.


        1. hypercrite
          25.06.2025 07:31

          Всегда с удовольствием вас читаю, продолжайте постить!


  1. SolidSnack
    25.06.2025 07:31

    только чтобы не следить самим за консистентностью данных

    Напишите свою СУБД, концепции которые они должны поддерживать все описаны в интернете, спецификация SQL тоже открытая.

    А так, конечно, бредовая статья, мне кажется кто-то должен это написать) (EventLog приравниваете к EventSource) Вы хоть гуглом пользуетесь прежде чем статьи публиковать?)


    Пропитана ненавистью и противопоставлением себя "en masse". На это хочется сказать - любая контр культура, это часть культуры которой она себя противопоставляет ;)

    В неидеальном (приложение упало в процессе совершения перевода денег со счета на счет) — придется развернуть записи из ивентлога для воссоздания состояния объекта «незаконченный платёж» в памяти перезапущенного приложения.

    Так что, каждый раз, когда вы начинаете мыслить вместо категорияй данных — понятийным аппаратом «базы» (транзакции, джойны, и так далее)

    На этом моменте люди из финтеха как минмум недоумевают) Смотрите, в базе данных, транзакции - набор SQL инструкций, но что важнее результат этих инструкций отслеживается и при возникновении ошибки, вся транзакция откатывается. Вот, люди просто платежи через транзакции проводят, и если сеть упала, то считайте что транзакции и не было (ее вызова и самого перевода), получается и восстанавливать ничего не надо)


    1. cupraer Автор
      25.06.2025 07:31

      Я говорю: СУБД нужна далеко не всегда и далеко не для всего. Комментаторы: напишите свою СУБД.

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

      И да, весь текст выше написан на основе опыта именно в финтехе.


      1. SolidSnack
        25.06.2025 07:31

        Я вашу цитату привел что конкретно вы говорите, бизнес доверяет проверенным решениям (существцющим СУБД), а вы в статье пишете что из-за лени люди не поддерживают консистентность сами) это абсурд.

        И что, вы в финтехе свои потоки данных писали, со своей консистентностью и транзакциями?)

        Вы даже паттерны между которыми ставите знак равно не смогли нагуглить. Ещё так болезненно к критике относитесь) Что не совпадает с вашим описанием профиля)


        1. hypercrite
          25.06.2025 07:31

          Посмотрите другие статьи автора, тут смысла убеждать нет никакого. Можно только гадать: намеренный рейджбейт или незамутненное чсв


        1. cupraer Автор
          25.06.2025 07:31

          Я болезненно отношусь не к критике, а к глупости. Ивентсорс — это просто воспроизведение ивентлога, их никто давно не разделяет, среди тех, кто плотно с ними работает.

          Если бы вы спросили, как в финтехе работают с ивентлогом, с самого начала, а не начали рассказывать про всемогущие транзакции, я бы даже ответил бы.

          Но поезд ушел.


          1. SolidSnack
            25.06.2025 07:31

            Я болезненно отношусь не к критике, а к глупости

            И не можете удержать её в себе, пытаясь открыть что-то кто никто не понимает (конечно кроме вас)


            1. cupraer Автор
              25.06.2025 07:31

              Я не пытаюсь ничего открыть, всё это открыли десятилетия тому назад.

              Если вам лично не хватает умишка, это не значит, что его не хватает всем. Кто-то поймет.


              1. SolidSnack
                25.06.2025 07:31

                Вы за своим самомнением все прячетесь, но та же стена что защищает вас, видимо не даёт вам видеть


  1. Spyman
    25.06.2025 07:31

    Стиль статьи для чтения тяжеловат, я сразу и не понял о чем речь)

    Но с тезисами - что БД (особенно реляционная) необходима далеко не всегда, и надо сознательно выбирать места где её применять - полностью согласен.

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