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] 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-зпапрос и заверну его в метод репозитория в модели, а еще лучше сделаю из ентого запроса такую-то хранимку, потому что у нее выше шанс реиспользования.

[identity profile] firebie.livejournal.com 2012-10-20 07:19 pm (UTC)(link)
Обновление на сервере:

db.Employee
.Where(e => e.Title == "Spectre")
.Set(e => e.Title, "Commander")
.Update();

[identity profile] stdray.livejournal.com 2012-10-20 07:39 pm (UTC)(link)
Люди написали один единственный ОРМ-фреймворк, ага.

[identity profile] firebie.livejournal.com 2012-10-20 07:46 pm (UTC)(link)
В тех, в которых такое невозможно - да, ручной запрос.
Если уж говорить за ОРМ - то правильные являются тонкой надстройкой над базой и не занимаются самодеятельностью по созданию и загрузке данных.

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

[identity profile] vp.livejournal.com 2012-10-20 09:30 pm (UTC)(link)
Как выглядит такой апдейт? можешь привести пример?

[identity profile] theiced.livejournal.com 2012-10-20 09:35 pm (UTC)(link)
Foo.where(:bar => 'bee').update_all(:huj => 'хуй')

[identity profile] vp.livejournal.com 2012-10-20 09:38 pm (UTC)(link)
Я не про апдейт, я про апдейт схемы базы.
У вас была версия 1.1, вы апдейтите изделие на 1.8
Как ваш чудо орм автоматически обновит ту базу, на которой работает?
в 1.8 у вас удалили половину полей, который были в 1.1 и создали другую половину.

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

[identity profile] metaclass.livejournal.com 2012-10-20 09:49 pm (UTC)(link)
Я делаю sql cкриптами.
А схема и прочее для ормов генерируется из модели, т.к. полное описание предметки в виде модели слишком сложное, чтобы его запихивать в любой частный язык программирования (за исключением разного рода лиспов, разве что)

[identity profile] vp.livejournal.com 2012-10-21 07:38 am (UTC)(link)
Ну дык для того, чтобы сделать апдейт схемы, необходимо эту схему представлять. И необходимо понимать, на каком состоянии у тебя находится обновляемая система к твоей текущей версии, до которой ты собираешься ее догнать.
Как ты это делаешь без понимания того, как устроена база? (мы только что постулировали, что только так и нужно и нам пофиг что там)

(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

[identity profile] metaclass.livejournal.com 2012-10-20 09:45 pm (UTC)(link)
Что ты несешь, мы же обсуждаем апдейты данных, а не метаданных.

Для метаданных есть миграции в рубевой activerecord, а поскольку в базе логику и вообще хоть что-то осмысленное делать у них не принято, то функций типа "добавить/удалить таблицу" и "добавить/удалить поле" более чем достаточно :)

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

[identity profile] theiced.livejournal.com 2012-10-20 09:50 pm (UTC)(link)
вот, до вас доходит же потиху. именно - ВЫКИНУТЬ К ХУЯМ всю это ненадёжную поебень.

(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)
Воще пишут, массово :)
Другое дело, что это делать нужно не так часто, благодаря всякого рода кодогенераторам и ормам.