Здравствуйте, Gattaka, Вы писали:
G>Коллеги, G>Так ли плохо реализовывать бизнес логику в высокопроизводительных хранимых процедурах?
"Высокопроизводительные хранимые процедуры" это оксюморон.
Типичное приложение — это CRUD. В простом приложении CRUD это 100% всей работы с базой, в сложном — не менее 60% по моим подсчетам.
Высокопроизводительное чтение данных строится на простом принципе — делаем максимально точный предикат (без всяких t.Field = @p or @p is null) для выборки и минимальную проекцию.
Это значит что тебе нужно будет или 100500 процедур для чтения данных, или клеить строки в SQL.
Естественно никто в здравом уме так не делает и использует запросы общего вида, с неоптимальными проекциями и предикатами, получая быстродействие заведомо хуже того, что могло бы быть.
Что касается изменения данных, то картина тоже не в пользу процедур. В случае изменения\добавления\удаления одной строки никакой разницы с запросами из приложения нет.
Зато если надо сразу несколько строк добавить\обновить\удалить, то ORMы просто формируют батч и отправляют на сервер, а для процедуры нужно данные сериализовать в какой-нибудь xml\json или на крайняк в табличный параметр. Потом распарсить параметр в процедуре и только после этого выполнить операции. Естественно подход с процедурами также заведомо неоптимален.
Реальная высокая производительность в процедурах достигается не в OLTP сценариях, а в OLAP, когда нужно гонять массивы данных, желательно без перекачки их в приложение.
G>Либо сейчас модно использовать кодогенераторы типа ОРМ, которые генерируют ужасные sql запросы? Учитывая, что код на sql как правило более локаничный и лучше читается.
Код на SQL который более лаконичный и лучше читается не имеет никакого отношения к высокой производительности.
HBM>>машины админить не надо, всё на автомате. HBM>>горизонтальное масштабирование всегда дешевле вертикального. G>Объясняю на пальцах. У одного из компьютеров посыпался диск, у второго винда начала обновление. Что тогда?
в случае с одним сервером таких проблем быть не может?
а если он один вышел из строя, что тогда?
шанс что ляжет весь кластер минимален.
да, и по секрету, винда на серваках сама обновления не начинает
Здравствуйте, Gattaka, Вы писали:
G>Здравствуйте, Sinix, Вы писали: S>>Про фэн-шуй не будем, это и без меня расскажут. С практической точки зрения — ну можно, да. При наличии определённых условий, разумеется.
G>Я бы про ОРМ высказался "ну можно, да..." Когда вы проверили генерируемый запрос, что этой ОРМ и этой версией ОРМ он более ни менее нормально генерируется. И если не так критично вытаскивание из базы избыточного объема данных чтобы заполнить поля сущности, которые не используются.
А что мешает сделать проекцию в ORM? Все известные мне ORM поддерживают проекции и динамическое конструирование запросов. Только по религиозным соображениям не все этим пользуются.
Здравствуйте, HeBpuMHeCkaTuHa, Вы писали:
HBM>>>оптимизировать sql нужно тогда, когда есть проблемы с перфомансом. 90% операций приложения это таки CRUD, а с ним любая ORM отлично справляется. G>>Ерунда. Нужно сразу писать оптимальный код. Преждевременная пессимизация приводит к проектам, которые и за полгода не отрефакторишь. HBM>преждевременная оптимизация не меньшее зло. код должен быть нормальным, но нет смысла гнаться за +1% перфоманса.
Это неверно.
Когда Дейкстра писал про преждевременную оптимизацию он имел ввиду мелкие хаки на уровне отдельных команд процессора, которые дают незначительный прирост быстродействия, но значительно ухудшают читаемость.
Частично это же касается выбора алгоримтма, типа лучше сначала запилить линейный поиск, чем ловить баги в двоичном поиске с интерполяцией.
Но когда мы говорим о высокоуровневой оптимизации — на уровне структур данных, взаимодействия компонентов, базы данных, то оптимизировать нужно с самого начала, иначе потом цена исправления растет экспоненциально.
Оптимизация SQL касается как раз такого вида оптимизации.
У меня есть прекрасный пример. В 2008 году, когда только появился linq, я делал сайт и один человек из моей команды занимался построением навигации.
Нужно было сделать нетривиальный запрос, который сделает выборку.
Это человек следуя подходу "потом оптимизируем" написал вместо сложного запроса пару foreach циклов. Мало того, что получил select n+1, так еще и код представления ориентировался на объекты модели, каждый из которых требовал поднятия по несколько КБ текста. В итоге навигация строилась полсекунды.
Я ему сказал, что надо переписать это дело в запрос и сделать проекцию, но он сказал, что это фигня и лучше мы применим кэш. И прикрутил кэш для объектов модели.
Потом мы на сайте прогрузили реальные данные клиента и получилось на построение навигации 8 секунд. Даже отлаживать стало неудобно, даже кеш не помогал, ибо разработчик запускал с нуля приложение чуть ли не каждую минуту.
В итоге надо было переделать запросы, сделать DTO, переделать код представления, переделать механизм кеширования. По сути переписать ВСЕ, что делал этот программист.
Вот такая цена неоптимальных запросов.
Еще хуже оказывается ситуация неоптимальной структуры БД, тогда нужно не просто запросы переписать, а еще и данные перелить и не дай бог приложение у заказчика работает.
Здравствуйте, HeBpuMHeCkaTuHa, Вы писали:
HBM>горизонтальное масштабирование всегда дешевле вертикального.
На практике вертикальное дешевле.
И даже банальные расчеты это показывают. Предположим что цена железа растет линейно мощности.
Чтобы масштабировать сервер горизонтально вам надо его продублировать. То есть купить такой же набор дисков, такой же процессор, такую же мать, столько же памяти. То есть понести двойные затраты.
Чтобы масштабировать вертикально не надо все покупать в двойном размере, потому что упирается система во что-то одно. Например диск или процессор, изредка в память. Поэтому вертикальное масштабирование обходится дешевле.
Кроме того при горизонтальном масштабировании растут издержки на запуск системного ПО. ОС всегда кушает часть ресурсов и чем больше у вас компов, тем больше кушает ОС.
На практике же цена на железо растет медленнее, чем линейно. 16ГБ оп стоят дешевле, чем 2 по 8, диск на ТБ стоит дешевле двух на 500 ГБ. Процессор в 2 раза быстрее не в два раза дороже медленного.
Конечно такая зависимость сохраняется не всегда, если мы возьмем масштабы гугла или ФБ, то там вертикальное масштаирование или физически невозможно или стоит сильно больше горизонтального. Но это гугл и ФБ, таких масштабов в жизни мало кто сможет увидеть. А для обычных приложений вертикальное масштабирование выгоднее.
Почитай про stackoverflow, при их нагрузках они масштабируются вертикально в основном.
HBM>>горизонтальное масштабирование всегда дешевле вертикального.
G>На практике вертикальное дешевле. G>И даже банальные расчеты это показывают. Предположим что цена железа растет линейно мощности. G>Чтобы масштабировать сервер горизонтально вам надо его продублировать. То есть купить такой же набор дисков, такой же процессор, такую же мать, столько же памяти. То есть понести двойные затраты. G>Чтобы масштабировать вертикально не надо все покупать в двойном размере, потому что упирается система во что-то одно. Например диск или процессор, изредка в память. Поэтому вертикальное масштабирование обходится дешевле.
тут мы упремся либо в ограничения по железу, либо в софтину, которая просто не сможет загрузить всю железку и будет продолжать тормозить
G>Кроме того при горизонтальном масштабировании растут издержки на запуск системного ПО. ОС всегда кушает часть ресурсов и чем больше у вас компов, тем больше кушает ОС.
ось можно всегда подтюнить, и она будет кушать почти незначительную часть ресурсов. я бы вообще это не брал в расчет.
G>На практике же цена на железо растет медленнее, чем линейно. 16ГБ оп стоят дешевле, чем 2 по 8, диск на ТБ стоит дешевле двух на 500 ГБ. Процессор в 2 раза быстрее не в два раза дороже медленного. G>Конечно такая зависимость сохраняется не всегда, если мы возьмем масштабы гугла или ФБ, то там вертикальное масштаирование или физически невозможно или стоит сильно больше горизонтального. Но это гугл и ФБ, таких масштабов в жизни мало кто сможет увидеть. А для обычных приложений вертикальное масштабирование выгоднее.
мы же тут не конкретный пример рассматриваем, а мечтаем, так сказать
G>Почитай про stackoverflow, при их нагрузках они масштабируются вертикально в основном.
SO в отличии от других просто пытаются максимально выжать из железа. это круто.
но тем не менее их архитектура изначально расчитана на горизонтальное масштабирование.
Здравствуйте, Gattaka, Вы писали:
HBM>>кто мешает вытащить только те данные, которые нужно и не тащить лишних? G>ОРМ мешает. У меня, допустим замеплина таблица на сущность, а из этой сущности нужно пару столбцов для отчета. ОРМ всю сущность вытащит и дальше вы будете работать с теми полями что вам нужно.
Что у тебя за ORM?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gandjustas, Вы писали:
G>Типичное приложение — это CRUD. В простом приложении CRUD это 100% всей работы с базой, в сложном — не менее 60% по моим подсчетам.
Даже CRUD для ORM не такое простое дело, например в том же NHibernte при этом нужно открывать именно его транзакции обязательно. Иначе текут коннекшены, он их в таком случае не освобождает.
G>Высокопроизводительное чтение данных строится на простом принципе — делаем максимально точный предикат (без всяких t.Field = @p or @p is null) для выборки и минимальную проекцию. G>Это значит что тебе нужно будет или 100500 процедур для чтения данных, или клеить строки в SQL. G>Естественно никто в здравом уме так не делает и использует запросы общего вида, с неоптимальными проекциями и предикатами, получая быстродействие заведомо хуже того, что могло бы быть.
G>Что касается изменения данных, то картина тоже не в пользу процедур. В случае изменения\добавления\удаления одной строки никакой разницы с запросами из приложения нет. G>Зато если надо сразу несколько строк добавить\обновить\удалить, то ORMы просто формируют батч и отправляют на сервер, а для процедуры нужно данные сериализовать в какой-нибудь xml\json или на крайняк в табличный параметр. Потом распарсить параметр в процедуре и только после этого выполнить операции. Естественно подход с процедурами также заведомо неоптимален.
Погодите. Наиболее типичный пример у меня в базе лежит 10 ГБ записей в табличке, мне нужно найти в этой куче удовлетворящие моему критерию умножить поле на два и вставить записи в две другие таблички. Решение с хранимой процедурой очевидно. Решение с ORM — нужно вытащить данные из БД, матерелиазовать их в сущности, сделать бизнес логику и поехали опять в базу на вставку. Вот за счет таких переливаний ORM и проигрывает, причем сильно. Но зато бизнес логика не в хранимках и "красиво"
G>Код на SQL который более лаконичный и лучше читается не имеет никакого отношения к высокой производительности.
Ну это был второй аргумент: 1. производительность, 2. локаничность и выразительность. Все таки SQL очень мощный он позволяет вам запросить что вам нужно, а не как извлеч данные.
Здравствуйте, Sinix, Вы писали:
S>Тут от языка / фреймворков / требований проекта / СУБД в бэкенде зависит. S> Если язык не умеет в linq, фреймворк (подставить косяк по вкусу), проект позволяет тратить время на сопровождение скриптов при каждом рефакторинге, а оптимизатор СУБД захлёбывается на простейших запросах (не будем говорить кто, но постгре в этом смысле ещё ничего), то да — наличие / отсутствие ORM меньшая из проблем.
Если вы на начальной стадии подошли грамотно к проектированию системы структура табличек — редко меняется. Если часто, то что-то не то в консерватории... Чтобы оптимизатор не захлёбывался используйте SQL Server у него очень хороший оптимизатор, говорю на собственном опыте. Вот эти ребята подтвердят: https://www.youtube.com/watch?v=AW87RzZJ0Z0
G>>А в целом от ОРМ гораздо больше проблем, чем выгоды.
S>Ну блин. ORM не сами по себе работает, он должен в стеке использоваться. Т.е. плюс локальные транзакции, плюс change tracking плюс сериализация изменений по сети, + обработка в одной транзакции данных, которые объявлены в разных сборках (т.е. общего репо как такового, нет) + умный коммит + автомиграция / авторазвёртывание и тыды и тыпы.
Change tracking — зло. Вы должны сами отслеживать изменения, а не завязываться на конкретную ORM.
S>Это как бумажные чертежи vs проектирование в цифре — основной выигрыш получается, когда используется вся цепочка, вплоть до инструментального контроля. Иначе получается "дядя Вася с киянкой цифру не понимает — отстой ваша цифра".
Ничего подобного! Это скорее как проф. фотокамера против мыльницы. Мыльница позволяет вам не заморачиваться о выдержке, iso, диафрагмы. Зато теперь вы тоже можете делать фотки прямо как фотограф. Аналогично с ORM зачем читать про SQL и базы данных, если можно работать с обычными и привычными классами, само как-то замепится и выполнится. Вот только на практике этого не бывает и крайними оказываются СУБД в этой истории.
Здравствуйте, gandjustas, Вы писали:
HBM>>>>оптимизировать sql нужно тогда, когда есть проблемы с перфомансом. 90% операций приложения это таки CRUD, а с ним любая ORM отлично справляется. G>>>Ерунда. Нужно сразу писать оптимальный код. Преждевременная пессимизация приводит к проектам, которые и за полгода не отрефакторишь. HBM>>преждевременная оптимизация не меньшее зло. код должен быть нормальным, но нет смысла гнаться за +1% перфоманса.
G>Это неверно.
G>Когда Дейкстра писал про преждевременную оптимизацию он имел ввиду мелкие хаки на уровне отдельных команд процессора, которые дают незначительный прирост быстродействия, но значительно ухудшают читаемость. G>Частично это же касается выбора алгоримтма, типа лучше сначала запилить линейный поиск, чем ловить баги в двоичном поиске с интерполяцией.
G>Но когда мы говорим о высокоуровневой оптимизации — на уровне структур данных, взаимодействия компонентов, базы данных, то оптимизировать нужно с самого начала, иначе потом цена исправления растет экспоненциально. G>Оптимизация SQL касается как раз такого вида оптимизации.
<... пример реализации через жопу скипнут...>
G>Еще хуже оказывается ситуация неоптимальной структуры БД, тогда нужно не просто запросы переписать, а еще и данные перелить и не дай бог приложение у заказчика работает.
то что ты описываешь не совсем верно. Из того что я видел, пример преждевременной оптимизации на высоком уровне обычно такой:
Дизайним что-то крупное. И в процессе раскопок потенциальных проблем видны несколько бутылочных горлышек. Какое именно будет главным зависит от поведения пользователей, а его никто не знает(вот так построены бизнес процессы в компании что никто точно не знает как будут использовать фичу/компоненту/продукт, и даже как используют текущие фичи. Т.е. нормальных предположений сделать нельзя.). Тут встает "архитектор" и выдает: "Модель нагрузки будет вот такой <описание фантазий>". Поэтому мы всю архитектуру, заточим под скорость на такой модели. Причем под этими фантазиями нет никаких фактов, просто человеку так показалось. В случае если он не угадает, такую "заоптимизированную" систему переделать под другую модель нагрузки намного сложнее чем нейтральную. И соответственно нормальное решение, в ситуации когда мы не знаем точно что будет горлышком, сделать нейтральную модель и знать как мы будем отслеживать горлышки, что будет делать сапорт в этот момент, как будем менять поведение системы, когда любая комбинация из них сработает...
Опять же зло предварительной оптимизации не должно оправдываться решением через жопу. Если сразу видно, что решение не держит расчетную нагрузку — в топку его.
Здравствуйте, Gattaka, Вы писали:
IT>>Что у тебя за ORM? G>Ну я знаю про вашу ОРМ... У меня NHibernate и Entity Framework был. Но сама идея парочна.
Ты выбрал два худших представителя тяжёлых ORM и делаешь выводы об идее. Первый, кстати, уже давно протухший трупик. Второй впитал в себя все худшие идеи первого.
Если нам не помогут, то мы тоже никого не пощадим.
G>Если вы на начальной стадии подошли грамотно к проектированию системы структура табличек — редко меняется. Если часто, то что-то не то в консерватории... Чтобы оптимизатор не захлёбывался используйте SQL Server у него очень хороший оптимизатор, говорю на собственном опыте. Вот эти ребята подтвердят: https://www.youtube.com/watch?v=AW87RzZJ0Z0
А вот это классическая ошибка программиста, от которых всех аналитиков приходится отучать в первую очередь (от них и наслушался). Aka "я здесь один" или "работает на малом — будет работать и на большом".
Ну вот представьте себе средних размеров биз-отдел под любую erp: команда из 10 человек (собственно разработчики — половина, из них с опытом — человека три в лучшем случае), число сущностей в модели данных — эдак с полторы тысячи (это ещё немного), команда должна дорабатывать продукт под новых клиентов и под изменения законодательства (очередной нежданчик минимум пару раз в квартал), а не тратить своё время на "поправил — всё поломалось".
Вот на таких маштабах все благоглупости типа "всё можно сделать вручную", "скрипты легко поддерживать" или "всё можно запроектировать заранее" выветривается через неделю максимум.
G>Чтобы оптимизатор не захлёбывался используйте SQL Server у него очень хороший оптимизатор, говорю на собственном опыте.
О, тож распространённое заблужление aka "бесплатного sql express достаточно"/"все клиенты готовы покупать взрослый MS SQL". Таки нет, как минимум поддержка postgre нужна. А там, увы, страх и боль, причём со всем стеком, от средств администрирования и до косяков в провайдере ADO.Net. Впрочем, нормальный orm тут спасает, да.
G>Change tracking — зло. Вы должны сами отслеживать изменения, а не завязываться на конкретную ORM.
Бугагашенька.
Когда типовой бизнес-сценарий — документик в 40 листов A4 и в нём только биз-логика, без деталей реализации, последнее, что тебе захочется делать — раздувать код в n раз только чтобы отслеживать все исправления вручную. Напоминаю, код ещё должен быть написан так, чтобы правился влёт после очередной корректировки ТЗ совместно с заказчиком. Т.е. чем ближе он будет к исходному тексту — тем лучше.
Если что, цена ошибки "упс, строчка потерялась" в лучшем случае — бесплатный фикс (считай, нагрел родную контору эдак на 5 мифических человекодней) в худшем — потеря клиентов (про прелести работы с госслужбами таки не будем).
G> Аналогично с ORM зачем читать про SQL и базы данных
Вы точно с ORM работали? Фэнтази какая-то, чесслово. Человек, неспособный самостоятельно воспроизвести/диагностировать/починить проблему, в разработчиках живёт недолго. И знание SQL / умение копаться в существующем коде тут — самые базовые навыки.
Здравствуйте, Gattaka, Вы писали:
G>Даже CRUD для ORM не такое простое дело, например в том же NHibernte при этом нужно открывать именно его транзакции обязательно. Иначе текут коннекшены, он их в таком случае не освобождает.
Это такая шутка? CRUD в исполнении linq2db
G>Погодите. Наиболее типичный пример у меня в базе лежит 10 ГБ записей в табличке, мне нужно найти в этой куче удовлетворящие моему критерию умножить поле на два и вставить записи в две другие таблички. Решение с хранимой процедурой очевидно. Решение с ORM — нужно вытащить данные из БД, матерелиазовать их в сущности, сделать бизнес логику и поехали опять в базу на вставку. Вот за счет таких переливаний ORM и проигрывает, причем сильно. Но зато бизнес логика не в хранимках и "красиво"
Тот же linq2db поддерживает не только DML, но и DDL, а это, например, работа с временными таблицами, что в свою очередь означает, что на LINQ можно написать код, которые перелапатит пол базы и при этом не поднимет на клиента ни одной записи.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Sinix, Вы писали:
S>Когда типовой бизнес-сценарий — документик в 40 листов A4 и в нём только биз-логика, без деталей реализации, последнее, что тебе захочется делать — раздувать код в n раз только чтобы отслеживать все исправления вручную. Напоминаю, код ещё должен быть написан так, чтобы правился влёт после очередной корректировки ТЗ совместно с заказчиком. Т.е. чем ближе он будет к исходному тексту — тем лучше.
S>Если что, цена ошибки "упс, строчка потерялась" в лучшем случае — бесплатный фикс (считай, нагрел родную контору эдак на 5 мифических человекодней) в худшем — потеря клиентов (про прелести работы с госслужбами таки не будем).
А на клиенте эти изменения как отслеживаются? Я про INotifyPropertyChanged ну там валидация всякая, подсветка красным невалидных полей?
Здравствуйте, Gattaka, Вы писали:
G>Так ли плохо реализовывать бизнес логику в высокопроизводительных хранимых процедурах?
Мне однажды пришлось поддерживать такой проект.
Я не припомню чтобы за всю мою карьеру мне попадался другой проект, который было бы настолько же сложно поддерживать.
Субъективное, конечно. Но я был не одинок в таких оценках того проекта.
Основная сложность поддержки того проекта была именно в хранимых процедурах, дело усугублялось тем, что процедуры писались профессиональным SQL-разработчиком, а поддерживалось это потом C# full-stack разработчиками, которым было непросто читать многостраничные cross-DB запросы с кучей JOIN'ов, CROSS-APPLY, MERGE и прочими прелестями.
Здравствуйте, HeBpuMHeCkaTuHa, Вы писали:
HBM>>>горизонтальное масштабирование всегда дешевле вертикального.
G>>На практике вертикальное дешевле. G>>И даже банальные расчеты это показывают. Предположим что цена железа растет линейно мощности. G>>Чтобы масштабировать сервер горизонтально вам надо его продублировать. То есть купить такой же набор дисков, такой же процессор, такую же мать, столько же памяти. То есть понести двойные затраты. G>>Чтобы масштабировать вертикально не надо все покупать в двойном размере, потому что упирается система во что-то одно. Например диск или процессор, изредка в память. Поэтому вертикальное масштабирование обходится дешевле.
HBM>тут мы упремся либо в ограничения по железу, либо в софтину, которая просто не сможет загрузить всю железку и будет продолжать тормозить
Если упремся в то, что наращивать ресурсы одного сервера нельзя или слишком дорого, тогда и можно рассмотреть горизонтальное масштабирование. Не раньше.
Если упираемся в софт, то надо переделывать софт или брать другой.
G>>Кроме того при горизонтальном масштабировании растут издержки на запуск системного ПО. ОС всегда кушает часть ресурсов и чем больше у вас компов, тем больше кушает ОС. HBM>ось можно всегда подтюнить, и она будет кушать почти незначительную часть ресурсов. я бы вообще это не брал в расчет.
Дело не только в оси. У любого экземпляра приложения есть фиксированные накладные расходы.
G>>На практике же цена на железо растет медленнее, чем линейно. 16ГБ оп стоят дешевле, чем 2 по 8, диск на ТБ стоит дешевле двух на 500 ГБ. Процессор в 2 раза быстрее не в два раза дороже медленного. G>>Конечно такая зависимость сохраняется не всегда, если мы возьмем масштабы гугла или ФБ, то там вертикальное масштаирование или физически невозможно или стоит сильно больше горизонтального. Но это гугл и ФБ, таких масштабов в жизни мало кто сможет увидеть. А для обычных приложений вертикальное масштабирование выгоднее.
HBM>мы же тут не конкретный пример рассматриваем, а мечтаем, так сказать
Надо не мечтать, а считать.
G>>Почитай про stackoverflow, при их нагрузках они масштабируются вертикально в основном.
HBM>SO в отличии от других просто пытаются максимально выжать из железа. это круто. HBM>но тем не менее их архитектура изначально расчитана на горизонтальное масштабирование.
Прости, в каком месте? Они изначально сделали ASP.NET веб-приложение с базой на SQL Server. Первое очевидно масштабируется горизонтально, второе очевидно нет. Такую же архитектуру имеют чуть менее, чем все веб-приложения.
Здравствуйте, Gattaka, Вы писали:
G>Здравствуйте, gandjustas, Вы писали:
G>>Типичное приложение — это CRUD. В простом приложении CRUD это 100% всей работы с базой, в сложном — не менее 60% по моим подсчетам. G>Даже CRUD для ORM не такое простое дело, например в том же NHibernte при этом нужно открывать именно его транзакции обязательно. Иначе текут коннекшены, он их в таком случае не освобождает.
Выкини NHibernate, возьми EF или linq2db, там нет таких проблем.
G>Погодите. Наиболее типичный пример у меня в базе лежит 10 ГБ записей в табличке, мне нужно найти в этой куче удовлетворящие моему критерию умножить поле на два и вставить записи в две другие таблички. Решение с хранимой процедурой очевидно.
Это реальный сценарий? Можешь описать его в терминах пользователя?
Или ты нафантазировал и считаешь, что ради такого стоит весь crud в хранимках делать?
В реальности у тебя будет сценарий такой:
1) Выбор строк по критерию и отображение на экране
2) Вызов этой самой бизнес-логики указанных пользователем строк.
Тут логика в приложении на два порядка лучше отработает.
G>Решение с ORM — нужно вытащить данные из БД, матерелиазовать их в сущности, сделать бизнес логику и поехали опять в базу на вставку. Вот за счет таких переливаний ORM и проигрывает, причем сильно. Но зато бизнес логика не в хранимках и "красиво"
Только в жизни подобный сценарий встречается в OLAP-системах, где вообще нет "приложения".
G>>Код на SQL который более лаконичный и лучше читается не имеет никакого отношения к высокой производительности. G>Ну это был второй аргумент: 1. производительность, 2. локаничность и выразительность. Все таки SQL очень мощный он позволяет вам запросить что вам нужно, а не как извлеч данные.
Ок, напиши запрос, удовлетворяющий следующим условиям:
1) Если пользователь админ, то ему показать все записи
2) Если пользователь не админ, то
— показать ему записи, где пользователь = автор
— или автор записи входит в группу друзей текущего пользователя
— и записи не должны быть скрыты
3) Записи должны быть отфильтрованы по категории, которую выбрал пользователь (id категории — параметр запроса, может быть пусто)
При этом запрос должен быть максимально лаконичным и быстрым.
Здравствуйте, Gattaka, Вы писали:
G>А на клиенте эти изменения как отслеживаются? Я про INotifyPropertyChanged ну там валидация всякая, подсветка красным невалидных полей?
Ну у кода здорового человека оно работает из коробки. У нас для этого используется самописный стек, причём он уже существовал к моменту, когда я пришёл в команду.
Проблема в том, что традиционный биндинг уже не особо актуален из-за моды на веб / rest api. И я очень и очень сомневаюсь, что что-то подобное выйдет в опенсорс, целевой аудитории ноль.
Здравствуйте, gandjustas, Вы писали:
G>Выкини NHibernate, возьми EF или linq2db, там нет таких проблем.
Вы будете смеятся, но мы до этого выкинули EF. Был болезненный переход на NH... У EF тоже куча недостатков, например он не позволяется получить вам чистые доменные объекты. То есть в классах доменных сущностей у вас присутсвуют ссылки на типы из EF, а это не правильно. Я, например, должен свободно использовать доменную сущность на клиенте не потащив туда ORM... Да и запросы у EF просто жесткач некоторые, NH в этом плане получше, хотя тоже косячит.
G>>Погодите. Наиболее типичный пример у меня в базе лежит 10 ГБ записей в табличке, мне нужно найти в этой куче удовлетворящие моему критерию умножить поле на два и вставить записи в две другие таблички. Решение с хранимой процедурой очевидно. G>Это реальный сценарий? Можешь описать его в терминах пользователя? G>Или ты нафантазировал и считаешь, что ради такого стоит весь crud в хранимках делать?
Не верите. Окей, вот вам реальный бизнес сценарий. Есть компьютерная сеть в которой есть сетевые узлы и пользователи. Они имеют связи между собой, мы это все храним в базе и даем возможность через наше приложение админить.
Таблицы User(Id, Name, Property), Network_Node(Id, Name, Property), User_User(User1Id, User2Id), Network_Node(Node1Id, Node2Id), UserOnNode(NodeId, UserId)
В нашей базе 70000 узлов по одному пользователю на узле (для простоты). Пользователи связаны все со всеми. Для некоторый (приблизительно половины) узлов был проставлен признак Prorepry — теперь нужно добавить для таких узлов на которых есть зарегестрированные связанные пользователи . Особенно посчитайте размер таблицы User_User, это приятный момент
G>>>Код на SQL который более лаконичный и лучше читается не имеет никакого отношения к высокой производительности. G>>Ну это был второй аргумент: 1. производительность, 2. локаничность и выразительность. Все таки SQL очень мощный он позволяет вам запросить что вам нужно, а не как извлеч данные. G>Ок, напиши запрос, удовлетворяющий следующим условиям: G>1) Если пользователь админ, то ему показать все записи G>2) Если пользователь не админ, то G> — показать ему записи, где пользователь = автор G> — или автор записи входит в группу друзей текущего пользователя G> — и записи не должны быть скрыты G>3) Записи должны быть отфильтрованы по категории, которую выбрал пользователь (id категории — параметр запроса, может быть пусто)
G>При этом запрос должен быть максимально лаконичным и быстрым.
Я считаю — прекрасно, практически на естественном языке
select r.id, r.name
from rows as r
where r.IsHidden = false and
(exists(select * from Administrators a where a.User = r.User) or
exist(select * from UserFriends uf where uf.User = r.User and r.Friend = @currentUser ))