metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-10-19 10:23 pm
Entry tags:

Бизнес-логика: Структура данных vs код

[livejournal.com profile] plumqqz доставил нам очередную ссылку на ужасы обсуждения БД на хабре. Сама статья еще куда ни шло, за исключением представления constraints как мега-фичи (вроде это основа основ любой БД). В комментариях, само собой, дикий ад, трэш, угар, содомия, коровники, заборы, катаформизм хабракармы и голые бизнес-аналитекши.

Самое ужасное там - это когда структуре данных отказывают в праве считаться частью бизнес-логики, упирая на то, что "надо же абстрагироваться от хранилища".
При этом, даже если добится этого абстрагирования - то все равно структура данных будет в памяти, в виде графа объектов, будет нужен дополнительный код по интеграции этой структуры с тем, что живет в БД, и никуда мы от структуры данных не денемся. А уж про то, можно ли считать констрейнты (в т.ч. и сложные, выражаемые только в виде триггеров) частью типов данных - можно дискутировать вечно. По крайней мере, check и foreign key constraints это точно часть типа данных, в случае FK - это еще и зависимые типы, реализованные в понятном виде. В случае unique constraints - уже сложнее, но по идее, тоже зависимый тип (зависит от данных таблицы, в которой он используется).

Так вот, я считаю, что структура данных для бизнес-логики гораздо более важна, чем собственно код. Если вам скажут, что теперь операция с кодом "777029" не облагается НДС - вам всего лишь нужно добавить веточку в паттерн-матчинг. Структура программы от этого не изменится и коллегам вы билд нахрен не сломаете.
А если окажется, что для того, чтобы узнать, как обрабатывается операция, вам нужно заглянуть в настройки в СУБД - то внезапно, в гламурно-причесанной функционально-иммутабельной функции проверки условий появляется грязная монада IO, провайдеры коннектов к БД, автоматическое управление транзакциями, пул коннектов, кэши и прочая черняга и структура данных (к коей я отношу так же и сигнатуры функций) меняется весьма заметно. Альтернативный вариант - оставить функцию чистой, но добавить к ней еще параметров, передаваемых извне, проверить код коллег, записать в трекер и рассказать, что теперь без передачи в нее оккультного набора параметров функция больше не заработает.

[identity profile] theiced.livejournal.com 2012-10-20 09:47 am (UTC)(link)
ссылочную целостность может спокойно обеспечить клиентская либа же.

[identity profile] vp.livejournal.com 2012-10-20 09:50 am (UTC)(link)
поперхнулся. Ребе, что вы такое говорите? Мы об одном и том же вообще?

[identity profile] metaclass.livejournal.com 2012-10-20 10:02 am (UTC)(link)
Но мы же не хотим сами делать то, что умеет СУБД :)

[identity profile] vp.livejournal.com 2012-10-20 10:18 am (UTC)(link)
Ну вот мы подошли к главному, к расстановке точек над и. И что является говноедством :)

[identity profile] theiced.livejournal.com 2012-10-20 11:23 am (UTC)(link)
говноедством является использование кода-в-базе! ещё раз - у вас вендор лок-ин на файрбёрд - я ваше мнение по этому конкретному вопросу ставлю на уровень мнения максдз например.

[identity profile] vp.livejournal.com 2012-10-20 12:29 pm (UTC)(link)
Вендор лок будет по любому случаю на любой базе, потому что sql-92 стал настолько сферическим, что базы друг от друга отличаются по всему, и никакого бесшовного перехода так или иначе не бывает.

[identity profile] theiced.livejournal.com 2012-10-20 12:42 pm (UTC)(link)
никто руками говносикль не пишет. он убог, крив и отвратителен. что вы вообще хотите от недодсля который придумывался с целью "дать манагерам возможность делать запросы к хранилищу данных"?

[identity profile] vp.livejournal.com 2012-10-20 12:44 pm (UTC)(link)
Руками-не руками, какая разница? Таргет-платформа не понимает ваши запросы от предыдущей платформы. Потому что никакой сейчас не 92й год :)

[identity profile] theiced.livejournal.com 2012-10-20 12:53 pm (UTC)(link)
какой МОЙ запрос. запрос генерит орм-или-его-аналог. я тупо пишу что то вида: `Point.where(:created_at => Time.now.beginning_of_day .. Time.now).where(:customer_id => [1, 2, 10]).order(:name).all` и мне реально похер какая там база и какой говносрез недострандарта сикль она умеет. кампутир железный, пусть он думает.

[identity profile] theiced.livejournal.com 2012-10-20 12:58 pm (UTC)(link)
и да - в 99% случаев оно сгенерит оптимальный запрос. да, оно умеет и джоины-хуёины и всё что надо. при этом никто не запрещает при попадании в тот 1% когда запрос не совсем оптимален и когда важна скорость написать селект какой руками. за последние 6 лет я сделал такое один раз и то по причине того что не знал что тот орм умеет вложенные прелоады.

[identity profile] stdray.livejournal.com 2012-10-20 02:39 pm (UTC)(link)
Ага, потом для того, чтобы обновить поле у 100500 записей, все они ОРМом подтягиваются на клиент, потом в цикле у них изменяется значение, и , наконец, все это дело летит обратно на сервер. Потом начинает это все начинает тормозить, жрать память и тд, потом изобретается что-то вроде обновлений партиями по 500 штук и прочая ерунда.

[identity profile] vp.livejournal.com 2012-10-20 03:07 pm (UTC)(link)
А вот тут мы подошли к самому интересному моменту нашего обсуждения. 83% продуктов на рынке на фазе своей разработки имеют только одну цель: быть завершенными. Что там будет дальше в жизненном цикле - никого не волнует. А если мы о стартапе, целью которого будет продажа дальше по цепочке, то о таком вообще запрещено думать, чтобы не мутить воду.

[identity profile] stdray.livejournal.com 2012-10-20 06:10 pm (UTC)(link)
Я придерживаюсь мнения, что сначала надо сделать самым простым наивным способом, чтобы работало и можно было тестировать. У меня какие-то похожие с Айседом значения, что 98-99% задач делается ОРМом, а остальное можно и руками похардкодить. Просто он говорит, мол мощные хранимки и специфичные особенности конкретной СУБД - зло, потому что если вендер субд поехал, то все дружно попали ад. По мне так, это не аргумент ни разу. Какбы если с ума сойдут (или просто забьют на развитие и поддержку) разрабы ОРМ, то проблем будет гораздо-гораздо больше. И что теперь паниковать и воротить слой абстракции над ОРМами? Не думаю. Это ни к чему хорошему не приведет. Когда растут нагрузки придется спускаться к СУБД-специфичными фичам, когда надо делать бэкапы базы тоже чаще всего надо пользоваться СУБД-специфичными тулзами, когда надо секьерность-пользователи-права тоже все СУБД-специфичное, апдейты для базы я тоже руками пишу, хотя вроде есть какие-то там миграторы, но я опять же им не верю. Ко всему прочему, когда это дело год или два на конкретной СУБД работает, то оно оттестировао, пробелемы известны и саппорт умеет их чинить, без пробрасывания геморроя в наш отдел. А если там зверинец поддерживаемых СУБД развести, то нам, наверное, придется человека выделять. который будет рулить все енти вопросы. СУБД же все по разному работают, разные планы запросов строят, по-раному нуллы трактуют, еще с датавременем и гуидами какие-то проблемы у меня были. То есть вопрос масштаба, я считаю. Когда там code-first и надо прототип слепить, пофиг что там за постоянное хранилище, а когда пошла реальная работа с загрузкой ресурсов, то все эти абстракции прилетают бумерангом по башке.

[identity profile] theiced.livejournal.com 2012-10-20 09:22 pm (UTC)(link)
именно. поэтому получаются продукты с лок-ином на файрбёрд. абы выпустить, дальше похуй.

[identity profile] metaclass.livejournal.com 2012-10-20 03:17 pm (UTC)(link)
Вроде ормы уже научились апдейты на сервере генерить. Простые, во всяком случае, потому как общее подмножество фич разных серверов достаточно узкое.

[identity profile] stdray.livejournal.com 2012-10-20 05:35 pm (UTC)(link)
Я такого поведение не наблюдал, а вот "тысячи объектов материализуются лишь для того, чтобы по ним нагерерился update" правил буквально на днях. Я ОРМам не верю, потому любое свое предположение относительно их работы приходится тестирвоать, потому если время поджимает, я лучше руками нарисую SQL-зпапрос и заверну его в метод репозитория в модели, а еще лучше сделаю из ентого запроса такую-то хранимку, потому что у нее выше шанс реиспользования.

(no subject)

[identity profile] firebie.livejournal.com - 2012-10-20 19:19 (UTC) - Expand

(no subject)

[identity profile] stdray.livejournal.com - 2012-10-20 19:39 (UTC) - Expand

(no subject)

[identity profile] firebie.livejournal.com - 2012-10-20 19:46 (UTC) - Expand

[identity profile] theiced.livejournal.com 2012-10-20 09:21 pm (UTC)(link)
это хуёвые ормы, нормальные сгенерят правильный апдэйт.

(no subject)

[identity profile] vp.livejournal.com - 2012-10-20 21:30 (UTC) - Expand

(no subject)

[identity profile] theiced.livejournal.com - 2012-10-20 21:35 (UTC) - Expand

(no subject)

[identity profile] vp.livejournal.com - 2012-10-20 21:38 (UTC) - Expand

(no subject)

[identity profile] theiced.livejournal.com - 2012-10-20 21:41 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-20 21:49 (UTC) - Expand

(no subject)

[identity profile] vp.livejournal.com - 2012-10-21 07:38 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-21 08:08 (UTC) - Expand

(no subject)

[identity profile] theiced.livejournal.com - 2012-10-21 08:54 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-21 09:05 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-21 09:05 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-20 21:45 (UTC) - Expand

(no subject)

[identity profile] theiced.livejournal.com - 2012-10-20 21:50 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-20 22:07 (UTC) - Expand

(no subject)

[identity profile] theiced.livejournal.com - 2012-10-20 22:15 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-20 22:30 (UTC) - Expand

(no subject)

[identity profile] blackyblack.livejournal.com - 2012-10-22 06:36 (UTC) - Expand

(no subject)

[identity profile] vp.livejournal.com - 2012-10-21 07:40 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-21 08:09 (UTC) - Expand

(no subject)

[identity profile] vp.livejournal.com - 2012-10-21 08:16 (UTC) - Expand

(no subject)

[identity profile] theiced.livejournal.com - 2012-10-21 08:54 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-21 09:06 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-22 08:35 (UTC) - Expand

[identity profile] norguhtar.livejournal.com 2012-10-22 03:23 am (UTC)(link)
Если у вас такое наблюдается, не используете в этом месте ORM. ORM удобен в оперденях с тысячами CRUD.

[identity profile] metaclass.livejournal.com 2012-10-20 03:08 pm (UTC)(link)
Воще пишут, массово :)
Другое дело, что это делать нужно не так часто, благодаря всякого рода кодогенераторам и ормам.

[identity profile] 9zloy.livejournal.com 2012-10-20 01:11 pm (UTC)(link)
тут я за айседа. Нахер код в базе (Хотя я никогда не был настоящим программером и мое мнение можно не учитывать)

[identity profile] theiced.livejournal.com 2012-10-20 11:28 am (UTC)(link)
далее, современные ормы и прочая обеспечивают возможность ссылочной целостности и прочего путём написания таких же объёмов кода (а то и меньше) как и в говнотриггерах.

[identity profile] vp.livejournal.com 2012-10-20 12:31 pm (UTC)(link)
То есть мы придумаем на коленке механизм транзакций, потом придумаем механизм ссылочной целостности?

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

[identity profile] theiced.livejournal.com 2012-10-20 12:43 pm (UTC)(link)
транзакции же используются. без них никак. механизмы ссылочной целостности реализуются ормами.

[identity profile] metaclass.livejournal.com 2012-10-20 03:06 pm (UTC)(link)
Какие ORM, какие триггеры?:)
Мы за внешние ключи все еще говорим?:)

[identity profile] norguhtar.livejournal.com 2012-10-22 03:27 am (UTC)(link)
Часто проще написать один триггер, чем воротить код в ORM. К примеру обновление баланса на проведение денежной операции. Ну и по возможности фигачить их только для сохранения целостности в СУБД. Да это можно делать из ORM, но при большом количестве операций использование триггера даст хороший прирост производительности.