Сайт Романа ПарпалакаБлог20190806

Не храните бизнес-логику в базе данных

6 августа 2019 года, 11:46

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

Я расскажу, почему в промышленном программировании так делать не надо.

Масштабирование производительности. У приложений и базы данных различные возможности масштабирования при росте нагрузки на систему. Обычные приложения на современных фреймворках легко запустить в несколько копий на разных серверах. А вот базу данных «запустить» на нескольких серверах не так просто. Чтобы снизить нагрузку на чтение, применяют репликацию master-slave. Снизить нагрузку на запись сложнее. Но, возможно, к этим методам и не придется прибегать, если просто не создавать лишнюю нагрузку на базу данных и держать бизнес-логику в приложении.

Масштабирование разработки. Когда вы разрабатываете систему сами, вы используете любые инструменты на свое усмотрение. Когда вы нанимаете разработчиков, лучше применять стандартные общепринятые инструменты. И баги с боевой системы проще воспроизводить локально, когда бизнес-логика располагается только в коде.

Автоматизация разработки. БД как хранилище данных — стандартная практика. Для упрощения разработки в такой парадигме есть развитые инструменты — библиотеки ORM, которые умеют, в частности, автоматически генерировать скрипты миграции структуры БД. Изменение бизнес-логики в коде облегчается средствами среды разработки: автодополнением, автоматическим рефакторингом. Пользовательские функции в БД придется изменять полностью вручную.

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

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

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

Я помню, как на прошлой работе в CityAds в проекте была одна InnoDB-табличка на несколько сотен записей. Она пополнялась из триггера при изменении записей в другой таблице. Но иногда вставки по непонятным причинам не происходило.

Я долго не мог докопаться до настоящей причины, пока не сделал добавление записей из кода приложения, а не из триггера. Оказалось, что вставка иногда не срабатывает из-за ошибки типа unique constraint violation на автоинкрементном первичном ключе. Стандартный механизм исключений и логирование помогли отследить эту ошибку.

Админы подтвердили, что это известная проблема в MySQL 5.6, но быстро перевести production на 5.7 они не могли. Пришлось переключить тип таблицы с InnoDB на MyISAM. Проблема исчезла.

Не храните бизнес-логику в базе данных.

Поделиться

Дизайн указателей в московском метро — 2 Ctrl Радиационное загрязнение больницы в Северодвинске

Читайте также

Как покрыть тестами устаревший код?
Многим разработчикам приходилось поддерживать и дорабатывать устаревшие приложения, в которых никогда не было автотестов. С помощью приемочных тестов библиотеки Codeception можно покрыть веб-приложение на любом фреймворке и даже на любых языках.
2023

Оставьте свой комментарий


Формулы на латехе: $$f(x) = x^2-\sqrt{x}$$ превратится в $$f(x) = x^2-\sqrt{x}$$.
Выделение текста: [i]курсивом[/i] или [b]жирным[/b].
Цитату оформляйте так: [q = имя автора]цитата[/q] или [q]еще цитата[/q].
Других команд или HTML-тегов здесь нет.

Записи