Здравствуйте, <Аноним>, Вы писали:
А>Не могу выбрать: А> 1 делать логику на уровне БД хранимками PL/SQL А> 1 вынести логику из базы
А>какие за и против по поводу обоих вариантов?
А нет ни "за", ни "против". Надо смотреть по ситуации. И всегда оставлять логику СУБД — самой СУБД, а логику приложения — приложению. Универсального совета, я думаю, не существует. Так что, ты хоть примерно опиши предметную область задачи, саму задачу... Вот тогда и можно будет что-то советовать.
С годами я делаюсь все менее терпимым к людям неумным и неумеющим работать свое дело очень хорошо. (с) М. Веллер
Здравствуйте, Аноним, Вы писали:
А>Не могу выбрать: А> 1 делать логику на уровне БД хранимками PL/SQL А> 1 вынести логику из базы
А>какие за и против по поводу обоих вариантов?
Я всегда придерживаюсь следующего правила:
1. Логика реализуется на уровне БД.
2. Только когда сложно или невозможно реализовать логику на уровне
БД, вынести логику из базы.
Первый вариант имеет следующие преимущества:
— В хранимых процедурах напрямую использовать SQL, уровень которого выше, чем
у процедурного языка программирования
— Многие бизнес-правила на уровне БД реализуются декларативно
средствами БД (такими, например, как CHECK CONSTRAINT или
FOREIGN KEY) или при помощи триггеров
— Код находится ближе к данным, что облегает отладку, тестирование и
сопровождение программы
Этот же вариант имеет и недостатки:
— Скорость работы хранимых процедур может быть недостаточной
— Логика может быть сложной настолько, что ее становится трудно
реализовать при помощи хранимых процедур (хотя PL-SQL,
в общем-то, достаточно можный язык)
Какой подход лучше использовать, зависит от конкретного проекта.
Здравствуйте, Аноним, Вы писали:
А>Не могу выбрать: А> 1 делать логику на уровне БД хранимками PL/SQL А> 1 вынести логику из базы А>какие за и против по поводу обоих вариантов?
Слабому Серверу Толстый клиент и наоборот.
В то же время, если логика будет вся в БД, то создавать свои приложения можно будет по средствам различных средств разработки, а не писать заново логику одну и ту же во всех приложениях. К примеру ВинФормс и Веб приложения могут использовать одни и те же функции и процедуры с сервера. Так же контроль прав намного проще и безопаснее на уровне сервера организовывать.
Хотя для какой-то разовой работы можно и всю логику из БД в приложение вынести. Разрабатывать такое попроще, если язык БД знаете хуже чем приложения.
Здравствуйте, Flying Dutchman, Вы писали:
FD>Первый вариант имеет следующие преимущества: FD>- Многие бизнес-правила на уровне БД реализуются декларативно FD> средствами БД (такими, например, как CHECK CONSTRAINT или FD> FOREIGN KEY) или при помощи триггеров
Вот из этой цитаты я понял, что ты не совсем четко представляешь, что именно должно кодироваться в программе, а что именно в SQL.
Здравствуйте, Mika Soukhov, Вы писали:
MS>Здравствуйте, Flying Dutchman, Вы писали:
FD>>Первый вариант имеет следующие преимущества: FD>>- Многие бизнес-правила на уровне БД реализуются декларативно FD>> средствами БД (такими, например, как CHECK CONSTRAINT или FD>> FOREIGN KEY) или при помощи триггеров
MS>Вот из этой цитаты я понял, что ты не совсем четко представляешь, что именно должно кодироваться в программе, а что именно в SQL.
И что же, по-твоему, должно кодироваться в программе, а что в SQL ?
Здравствуйте, Flying Dutchman, Вы писали:
MS>>Вот из этой цитаты я понял, что ты не совсем четко представляешь, что именно должно кодироваться в программе, а что именно в SQL. FD>И что же, по-твоему, должно кодироваться в программе, а что в SQL ?
В SQL — работа с данными. Логику в хранимых процедурах поддерживать сложно и неудобно. Там должно быть только то, что не имеет смысла делать в прикладном коде: создание данных для отчетов, еще может быть проверка политик безопасности и т.п.
Средства поддержки целостности БД еще прекрасно работают в качестве "последнего рубежа" в борьбе с ошибками. То есть, в хорошей программе нарушения констрейнтов — ошибочная ситуация, которой не должно быть (хотя могут быть какие-то частные случаи). Но уж если ошибка случилась — то БД хоть не даст испортить данные.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Flying Dutchman, Вы писали:
MS>>>Вот из этой цитаты я понял, что ты не совсем четко представляешь, что именно должно кодироваться в программе, а что именно в SQL. FD>>И что же, по-твоему, должно кодироваться в программе, а что в SQL ? C>В SQL — работа с данными. Логику в хранимых процедурах поддерживать сложно и неудобно.
Почему же "сложно и неудобно" ? По опыту своих проектов могу сказать, что
большую часть логики удобно реализовать в хранимых процедурах,
тем более что логика
Даже на таком, в общем-то, примитивном языке, как Transact-SQL.
Не говоря уже о PL-SQL, который представляет собой полноценный (почти) язык
программирования.
Другое дело, что работа с данными должна быть по возможности отделена от логики, т.е. должна
быть реализована в других хранимых процедурах.
С>Там должно быть только то, что не имеет смысла делать в прикладном коде: создание данных для отчетов, еще может быть проверка политик безопасности и т.п.
Я бы сказал по-другому — в прикладном коде должно быть только то, что сложно или не имеет смысла
реализовать в хранимых процедурах.
Здравствуйте, Flying Dutchman, Вы писали:
FD>Здравствуйте, Mika Soukhov, Вы писали:
MS>>Здравствуйте, Flying Dutchman, Вы писали:
FD>>>Первый вариант имеет следующие преимущества: FD>>>- Многие бизнес-правила на уровне БД реализуются декларативно FD>>> средствами БД (такими, например, как CHECK CONSTRAINT или FD>>> FOREIGN KEY) или при помощи триггеров
MS>>Вот из этой цитаты я понял, что ты не совсем четко представляешь, что именно должно кодироваться в программе, а что именно в SQL.
FD>И что же, по-твоему, должно кодироваться в программе, а что в SQL ?
Бизнес-правила — это: послать уведомление о подтверждении заказа; сделать скидку X если сумма превысила Y; удалить товар, если заказ не подтвердился в течении времени Z. Foreign Key, Primary Key, Constraints — это системный уровень. К бизнесу он никакого отношения не имеет (если, конечно, у вас бизнес не построен на создании СУБД).
Собственно, из твоего сообщения, я считаю правильным только вот это:
— Логика может быть сложной настолько, что ее становится трудно
реализовать при помощи хранимых процедур (хотя PL-SQL,
в общем-то, достаточно можный язык)
Все остальное или неверно, или спорно (aka зависит от задача).
Здравствуйте, Аноним, Вы писали:
А>Не могу выбрать: А> 1 делать логику на уровне БД хранимками PL/SQL
В этом случае можно задействовать всю мощь Oracle (pl/sql) и соответственно повысить производительность и скорость обработки запросов.
А> 1 вынести логику из базы
Если планируете разрабатывть не зависимую от СУБД систему. Т.е. СУБД только для хранения данных.
Flying Dutchman wrote: > C>В SQL — работа с данными. Логику в хранимых процедурах поддерживать > сложно и неудобно. > Почему же "сложно и неудобно" ? По опыту своих проектов могу сказать, что > большую часть логики удобно реализовать в хранимых процедурах, > тем более что логика
По моему опыту, перенос сложной логики в БД — путь к монструозным проектам.
> Даже на таком, в общем-то, примитивном языке, как Transact-SQL. > Не говоря уже о PL-SQL, который представляет собой полноценный (почти) язык > программирования.
Ага. И при использовании такого подхода — получить мучения с системами
контроля версий, совместной работой и т.п.
Я уж не говорю про крайнюю убогость языка по сравнению даже с обычным C#.
> Другое дело, что работа с данными должна быть по возможности отделена от > логики, т.е. должна > быть реализована в других хранимых процедурах.
А это вообще приводит к бреду.
> С>Там должно быть только то, что не имеет смысла делать в прикладном > коде: создание данных для отчетов, еще может быть проверка политик > безопасности и т.п. > Я бы сказал по-другому — в прикладном коде должно быть только то, что > сложно или не имеет смысла реализовать в хранимых процедурах.
То бишь, почти все.
Здравствуйте, Cyberax, Вы писали:
C>В SQL — работа с данными. Логику в хранимых процедурах поддерживать сложно и неудобно...
Гм... Логика — это ни есть работа с данными? Например, увеличение остатка после оприходования товара?
C>Средства поддержки целостности БД еще прекрасно работают в качестве "последнего рубежа" в борьбе с ошибками. То есть, в хорошей программе нарушения констрейнтов — ошибочная ситуация, которой не должно быть (хотя могут быть какие-то частные случаи). Но уж если ошибка случилась — то БД хоть не даст испортить данные.
Безусловно. И теперь, следуя Вашей мысли, проверять на предмет "ошибки" тоже стоит не на стороне бд, например, на нарушение того или иного ограничения на логику обработки данных?
Здравствуйте, Cyberax, Вы писали:
C>По моему опыту, перенос сложной логики в БД — путь к монструозным проектам.
Т.е. реализация бизнес-логики в "другом месте" не приведет к монструозности? Аргументы?
C>Ага. И при использовании такого подхода — получить мучения с системами C>контроля версий, совместной работой и т.п.
Гм... И какие проблемы с контролем версий и совместной работой при разработке логики на сервере, например, на T-SQL?
C>Я уж не говорю про крайнюю убогость языка по сравнению даже с обычным C#.
По меньшей мере странно обрабатывать данные в реляционным хранилище языком, не предназначенном для этого.
Здравствуйте, pkarklin, Вы писали:
C>>В SQL — работа с данными. Логику в хранимых процедурах поддерживать сложно и неудобно... P>Гм... Логика — это ни есть работа с данными? Например, увеличение остатка после оприходования товара?
Ага, именно. Такие действия надо как можно дальше из БД выносить.
Потому как потом захочется еще при изменении, например, посылать письма или обновлять Excel-отчет в Sharepoint-сервере. Я видел монстров на TSQL, где формировался CSV и HTML в хранимых процедурах, куда шло обращение из ISAPI-фильтров.
C>>Средства поддержки целостности БД еще прекрасно работают в качестве "последнего рубежа" в борьбе с ошибками. То есть, в хорошей программе нарушения констрейнтов — ошибочная ситуация, которой не должно быть (хотя могут быть какие-то частные случаи). Но уж если ошибка случилась — то БД хоть не даст испортить данные. P>Безусловно. И теперь, следуя Вашей мысли, проверять на предмет "ошибки" тоже стоит не на стороне бд, например, на нарушение того или иного ограничения на логику обработки данных?
Именно. Как пример — в форме ввода disable'ить кнопку 'OK' пока не введут все нужные поля.
Проверки и констрейнты в БД нужно использовать, причем чем больше — тем лучше. Но только как дополнительную защитную фичу. Естественно, при правильном подходе констрейнты и проверки можно декларативно задавать в одном месте.
Здравствуйте, Cyberax, Вы писали:
P>>Гм... Логика — это ни есть работа с данными? Например, увеличение остатка после оприходования товара? C>Ага, именно. Такие действия надо как можно дальше из БД выносить.
Гм... Выносить вкуда? На апп.сервер? Который в конце концов сгенерит инструкцию типа
UPDATE
AccountSaldo
SET
Saldo = Saldo + @SomeValue
WHERE
AccountID = @SomeID AND
Period = @SomePeriod
Зачем мне еще что-то где-то на чем-то еще программировать, если в конечном результате я все равно проапдэйчу поле в одной записи? Зачем мне для этого апп.сервер, написанный на C?
C>Потому как потом захочется еще при изменении, например, посылать письма или обновлять Excel-отчет в Sharepoint-сервере. Я видел монстров на TSQL, где формировался CSV и HTML в хранимых процедурах, куда шло обращение из ISAPI-фильтров.
Нивапрос. Если СУБД предоставляет мне такие возможности (sp_send_dbmail, или linked servers, или DTS), то зачем мне еще где-то городить дополнительные городушки, которые еще будут неизвестно как работать?
P>>Безусловно. И теперь, следуя Вашей мысли, проверять на предмет "ошибки" тоже стоит не на стороне бд, например, на нарушение того или иного ограничения на логику обработки данных? C>Именно. Как пример — в форме ввода disable'ить кнопку 'OK' пока не введут все нужные поля.
Вот как раз "визуализация" ограничений в клиентском приложении есть дополнительная (но не обязательная) функциональность к:
1. соответствующим проверкам в коде бизнес-логики:
IF @ReceiverAccount IS NULL EXEC dbo.Abort 'Не указан счет получателя!'
0. И декларативным ограничениям. NOT NULL для поля
Здравствуйте, pkarklin, Вы писали:
C>>По моему опыту, перенос сложной логики в БД — путь к монструозным проектам. P>Т.е. реализация бизнес-логики в "другом месте" не приведет к монструозности? Аргументы?
Нормальные языки имеют нааамного больше средств для борьбы со сложностью, чем языки хранимых процедур (возможность юнит-тестирования, ООП всякое и т.п.)
C>>Ага. И при использовании такого подхода — получить мучения с системами C>>контроля версий, совместной работой и т.п. P>Гм... И какие проблемы с контролем версий и совместной работой при разработке логики на сервере, например, на T-SQL?
Покажи мне как нормально положить хранимые процедуры в SVN? Кроме того, очень часто девелоперам приходится работать на одном сервере (так как поставить себе на личные компьютеры полную базу данных часто нереально). В случае, когда логика от базы отделена — часто можно использовать центральную базу, к которой будут цепляться серверы на личных компьютерах.
C>>Я уж не говорю про крайнюю убогость языка по сравнению даже с обычным C#. P>По меньшей мере странно обрабатывать данные в реляционным хранилище языком, не предназначенном для этого.
По меньшей мере странно использовать хранилище для обработки данных.
Здравствуйте, Cyberax, Вы писали:
C>Flying Dutchman wrote: >> C>В SQL — работа с данными. Логику в хранимых процедурах поддерживать >> сложно и неудобно. >> Почему же "сложно и неудобно" ? По опыту своих проектов могу сказать, что >> большую часть логики удобно реализовать в хранимых процедурах, >> тем более что логика C>По моему опыту, перенос сложной логики в БД — путь к монструозным проектам.
По моему опыту — наоборот. Чтобы не быть голословным, приведу примеры
некоторых проектов, в которых я принимал участие.
1. Банковская система.
Реализована на Oracle, > 150 таблиц
Вся логика реализована в хранимых процедурах на PL/SQL (кроме экспорта данных
в другую систему), включая генерацию отчетов (это оказалось удобнее,
чем использовать Oracle Reports).
2. Система для хранения конструкторской информации и заказов для
фабрики по производству кранов. Реализована на SQL Server 2000, около 60
таблиц. Вся логика реализована на Transact SQL (несколько тысяч строк).
3. ERP-система для компаний, предоставляющих персонал внаем. Функции отдела кадров,
учеты проектов, расчета зарплаты и др. Реализована на SQL Server 2000, > 300 таблиц,
сотни хранимых процедур. Большая часть (почти вся) логики реализована на
Transact SQL, в частности, расчет зарплаты — полностью. На С# была организована
генерация отчетов в XML-формате, да и то я только потому, что я не знал тогда всех возможностей
Transact SQL. Сейчас я сделал бы это в хранимых процедурах.
4. Система автоматизации документооборота для полиции. SQL Server 2000, около 60 таблиц.
Около 80% логики (а может, и больше) в хранимых процедурах. Довольно сложная система
workflow и прав доступа. Были проблемы с некоторыми ХП из-за
низкой производительности. Некоторые ХП были очень большими и сложными, но на C#
это было бы еще больше и сложнее.
С другой стороны, знакомый участвовал в проекте автоматизации нефтеперегонного завода.
Все было также реализовано на Transact SQL, но у них были проблемы и со сложностью,
и с производительностью. Было много работы с массивами, которые моделировались
при помощи таблиц и обрабатывались при помощи курсоров, что приводило к большому замедлению.
Общий вывод — для большинства проектов лучше реализовавать логику в базе данных.
Для меньшей части проектов — в клиентском приложении.
>> Даже на таком, в общем-то, примитивном языке, как Transact-SQL. >> Не говоря уже о PL-SQL, который представляет собой полноценный (почти) язык >> программирования. C>Ага. И при использовании такого подхода — получить мучения с системами C>контроля версий, совместной работой и т.п.
И какие же проблемы могут быть с системами контроля версий ? Если поступать
правильно, то есть хранить хранимые процедуры в файле, а файл в системе
контроля версий, то никаких проблем не будет. Если же создавать и редактировать
хранимые процедуры прямо на сервере — то да, будут проблемы.
C>Я уж не говорю про крайнюю убогость языка по сравнению даже с обычным C#.
Ну, не убогость, а ограниченность для процедурных задач. Но этот недостаток
с лихвой компенсируется удобством использования SQL для работы с данными.
И то эта ограниченность свойственна, например, Transact SQL, а PL-SQL
уже полнофункциональный язык программирования.
>> Другое дело, что работа с данными должна быть по возможности отделена от >> логики, т.е. должна >> быть реализована в других хранимых процедурах. C>А это вообще приводит к бреду.
К чему приводит ??? Описанная практика это вообще best practice в
мире Oracle (за подробностями отсылаю к статьям Люкаса Йеллема The best of both worlds. Cross-breeding Java and PL/SQL и
Стива Ферстайна Cleaning Up PL/SQL Practices).
>> Я бы сказал по-другому — в прикладном коде должно быть только то, что >> сложно или не имеет смысла реализовать в хранимых процедурах. C>То бишь, почти все.
Ну, в общем-то, да. Работая в Oracle, вполне можно этого добиться для многих проектов.
Да и у SQL Server 2005 есть много возможностей. Можно, например, писать хранимые процедуры на C#.
Здравствуйте, pkarklin, Вы писали:
P>>>Гм... Логика — это ни есть работа с данными? Например, увеличение остатка после оприходования товара? C>>Ага, именно. Такие действия надо как можно дальше из БД выносить. P>Гм... Выносить вкуда? На апп.сервер? Который в конце концов сгенерит инструкцию типа
Именно.
P>Зачем мне еще что-то где-то на чем-то еще программировать, если в конечном результате я все равно проапдэйчу поле в одной записи? Зачем мне для этого апп.сервер, написанный на C?
А если потребуется перед измененим сальдо сначала направить счета на подтверждение к координинатору?
C>>Потому как потом захочется еще при изменении, например, посылать письма или обновлять Excel-отчет в Sharepoint-сервере. Я видел монстров на TSQL, где формировался CSV и HTML в хранимых процедурах, куда шло обращение из ISAPI-фильтров. P>Нивапрос. Если СУБД предоставляет мне такие возможности (sp_send_dbmail, или linked servers, или DTS), то зачем мне еще где-то городить дополнительные городушки, которые еще будут неизвестно как работать?
А письмо как формировать будем? Конкатенацией строк? А я могу мой любимый Velocity использовать в качестве темплейтного движка? А может MVEL? А как насчет использования LDAP для взятия почтового адреса пользователя?
Ты будешь лепить интерфейсы к базе?
P>>>Безусловно. И теперь, следуя Вашей мысли, проверять на предмет "ошибки" тоже стоит не на стороне бд, например, на нарушение того или иного ограничения на логику обработки данных? C>>Именно. Как пример — в форме ввода disable'ить кнопку 'OK' пока не введут все нужные поля. P>Вот как раз "визуализация" ограничений в клиентском приложении есть дополнительная (но не обязательная) функциональность к:
Нет. Эта функциональность для _нормальных_ приложений обязательна. Люди очень плохо реагируют на ошибки типа "Constraint filed_cannot_be_null violation. Transaction rolled back".
P>
P>IF @ReceiverAccount IS NULL EXEC dbo.Abort 'Не указан счет получателя!'
P>
P>0. И декларативным ограничениям. NOT NULL для поля
А у меня это все описано вот примерно так:
class Something
{
@Validate(notNull=true, messageKey="account.cant.be.null")
void setAccount(Account account);
}
"account.cant.be.null" — это локализуемый ресурс, будет определен примерно так: "ru.account.cant.be.null=Не указан счет получателя для ${that.name}!".
Да, и при этом система байндинга автоматически будет подкрашивать поле красным цветом при ошибке, дизэйблить кнопку 'OK' и т.п.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, pkarklin, Вы писали:
C>>>По моему опыту, перенос сложной логики в БД — путь к монструозным проектам. P>>Т.е. реализация бизнес-логики в "другом месте" не приведет к монструозности? Аргументы? C>Нормальные языки имеют нааамного больше средств для борьбы со сложностью, чем языки хранимых процедур (возможность юнит-тестирования, ООП всякое и т.п.)
Зато языки хранимых процедур обладают большими возможностями для работы с реляционными данными.
Это преимущество перевешивает их недостатки (например, отсутствие ООП).
Юнит-тестирование для баз данных существует. Для Oracle есть пакет utPLSQL, для
тестирования хранимых процедур SQL Server я использую NUnit и пишу тестовые программы на C#.
P>>Гм... И какие проблемы с контролем версий и совместной работой при разработке логики на сервере, например, на T-SQL? C>Покажи мне как нормально положить хранимые процедуры в SVN? Кроме того, очень часто девелоперам приходится работать на одном сервере (так как поставить себе на личные компьютеры полную базу данных часто нереально). В случае, когда логика от базы отделена — часто можно использовать центральную базу, к которой будут цепляться серверы на личных компьютерах.
Можно хранить хранимые процедуры в текстовом файле, а текстовый файл в SVN.
C>>>Я уж не говорю про крайнюю убогость языка по сравнению даже с обычным C#. P>>По меньшей мере странно обрабатывать данные в реляционным хранилище языком, не предназначенном для этого. C>По меньшей мере странно использовать хранилище для обработки данных.
База данных — это не просто хранилище данных, а хранилище данных + хранилище бизнес-правил + устройство обработки данных.