Blog about searching flow,
my thoughts, events in my life,
books I read,
testing, version controls and development in general
2013-04-27
Нетерпеливый кольцехвост
2013-04-26
2013-04-24
Бизнес-логика в базе
![]() | |
Типичный опердень
Выборка 41.5%
Фильтрация 5.8%
Обработка 13.4%
Аналитика 17.7%
Пост-обработка 21.6%
Комментарии 0%
| |
Или почему это зло
Если бизнес-логика в базе
Первая по важности - это богатые возможности СУБД: умный оптимизатор, который может работать с индексами и собирать статистику, что драматически сокращает объем считываемых данных и памяти; под рукой дешевые джойны по внешним ключам; агрегатные и аналитические функции; группировка и сортировка; фильтрация.
Второе - возможность легко и непринужденно использовать результат такого запроса в качестве источника данных.
Если бизнес-логика в приложении
Нет размазывание бизнес-логики между приложением, и базой. Что же такого на стороне приложения?
1. Не нужно вырезать и вставлять куски кода, чтобы их прогнать в изолированном окружении
2. Легкая отладка - можно остановиться в любом месте обрабоки и посмотреть на данные
3. Версионирование - кто вообще версионирует код, в базе?
4. Легковесность базы - нет логики, достаточно простого SQL, нет требований к базе, можно на коленке разворачивать схему любой версии на любой пользовательской машине. Когда база всего-лишь тупое хранилище данных, нам для работы достаточно командной строки, в идеале поля для выполнения кода с подсветкой синтаксиса. Сам билд становится переносимым, позволяя развернуть рабочее приложение на чистой машине.
5. Декларативный подход против императивно-функционального - СУБД сама выбирает оптимальный порадок выборки данных, зато во втором варианте процесс обработки можно "читать"
6. Комментарии - их нет. Ноль целых ноль десятых процента. Какой смысл их писать, если один кусочек логики размазывается по всему запросу? В случае пошаговой обработки можно пояснять что мы делаем на каждом этапе и почему.
7. Пошаговость процесса и функциональный стиль написания - позволяет писать тесты. Тестирование кода, работающего с базой - это уже джедайские практики. Я ни разу не видел тестов внутри базы, покрывающих пакеты, хотя инструменты имеются.
8. Возможность написать высокоуровневый DSL, который будет адаптирован к бизнес-домену, что позволит транслировать код в SQL с жутким мультипликатором. На эту тему у ребе metaclass можно прочитать много интересного.
Минусы хранения логики в приложении
1. ORM, которые строят сложные и, порой, неоптимальные запросы. А еще, многие из них не умею работать с курсорами, что усложнает написание кода в функциональном стиле с минимумом побочных эффектов. Претензий много.
2. Резко вырастает объем данных, которые нужно загрузить для выборки, одна из причин, по которой аппликейшен сервер держат поближе к базе данных (в сравнении с расстоянием до клиента).
Итог
Время разработчика дорого, серверные мощности дешевы. Поэтому за повышение скорости разработки и упорядочивание бизнес-логики платят скоростью работы запросов (с которым борются закидывая мощными железками), общей сложностью системы (трехзвенка вместо двухзвенки) и требованием к квалификации разработчика - круг замкнулся.
Фильтрация - Where и Having,
Обработка - различные функции, рассчеты, кейсы,
Аналитика - агрегатные и аналитические функции,
Пост-обработка - захардкоженные константы, сортировка и группировка.
P.S. Пояснения к легенде
Выборка - это Select и Join,Фильтрация - Where и Having,
Обработка - различные функции, рассчеты, кейсы,
Аналитика - агрегатные и аналитические функции,
Пост-обработка - захардкоженные константы, сортировка и группировка.
2013-04-21
Версионирование схемы БД
1 часть. Ораклява
Как-то меня перекинули на мой первый серьезный проект. Главная проблема была в том, что из проекта ушел основной разработчик, проект оказался в середине большого переписывания, а мне знания передавались неспециалистом в формате вуду-практик. Этих плясок было достаточно, чтобы поддерживать хоть какое-то подобие жизни.2013-04-20
Липосакция репозитория
| Сборка HelloWorld на Maven |
Предыстория
До того, как мы переехали на maven, мы жили в счастливом неведении: проект собирал нам eclipse, бинарные зависимости хранились рядом и коммитились в репозиторий. Двух книг оказалось достаточно, чтобы понять как низко мы пали. После этого мир изменился и уже никогда не будет прежним, а непортируемая сборка, которую нельзя запустить из консоли без IDE, будет восприниматься как нечто, о чем лучше забыть и не вспоминать.Мы успешно выпилили все старые артефакты и всё бы ничего, но наш репозиторий перевалил за гиг и клонирование занимало какое-то совсем неприличное время. Посему, между возможностью собрать любую старую версию (на тот момент мы еще не стабилизировали версии) и маленьким репозиторием, мы выбрали последний вариант. Похерив все хэши, мы удалили все бинарники сократив размер репозитория в 7 раз до 150 мегабайт. Все стало просто летать.
Хирургическое вмешательство
1 Этап. Определение кандидатов на отстрел
Такие файлы должны удовлетворять двум простым правилам:- это должен быть бинарный файл
- он должен быть удален на момент поиска
2. Этап. Составление расстрельного списка
Используем стиль для вывода списка файлов:#Для списка измененных
#changeset = "{file_mods}"
#Для списка удаленных
changeset = "{file_dels}"
file_mod = "{file_mod}\n"
file_del = "{file_del}\n"
Дальше составляем два списка командами hg log --style style_del | sort -u и hg log --style style_mod | sort -u. В первом приближении нам нужно из списка удаленных исключить все элменты которые встречаются в списке измененных. Вычесть файлы можно несколькими способами. Дальше вычитаем при помощи пайпов:
comm -2 -3 \
<(hg log --style ~/path/to/style_del | sort -u) \
<(hg log --style ~/path/to/style_mod | sort -u).
Для экспериментов можно передавать диапазон ревизий -r 0:100 чтобы оптимизировать время.
Полученный список нужно будет просмотреть глазами и составить список расширений для удаления. Список расширений можно посмотреть прогнав через | grep -oE "\.\w*$" | sort -u. В нашем случае он получился таким: deb, gz, jar, mp3, so, wav.
Прогоняем через sed, выводя только файлы, совпавшие по расширению, формируя filemap для hg convert. Итоговая строка фильтрации выглядит так:
comm -2 -3 \
<(hg log --style ~/path/to/style_del | sort -u) \
<(hg log --style ~/path/to/style_mod | sort -u) \
| sed -n 's/\(.*\)\(deb\|gz\|jar\|mp3\|so\|wav\)/exclude "&"/p' \
> filemap
3 Этап. Зачистка
Получившийся filemap скармливаем в hg convert --filemap ~/path/to/filemap ~/repo ~/repo_clean. На выходе получаем переродившийся репозиторий без шлака и мусора.
Дисклеймер
Здесь описана операция, успешно проведенная нами год назад. За это вресмя ни разу не понадобилось доступиться к удаленным файлам. На данный момент при 5к коммитах, репозиторий занимает 500Мб. При этом часть бинарных ресурсов всё еще жива и используется.
Фильтрация идет в основном средствами линуксовых команд. Хотя mercurial предоставляет прекрасный API для доступа к репозиториям, которым сам же и пользуется, на котором можно было бы написать понятную фильтрацию без подобных майндфаков: /\(.*\)\( и приседания с ключами команд, на тот момент с этим API я был незнаком, а сейчас просто воспроизвожу свои записки для сохранения в назидание потомкам.
Подписаться на:
Сообщения (Atom)


