Хранение бизнес-логики в базе данных
мы хотим написать некоторые правила бизнес-логики, которые работают на определенных данных для построения отчетов. Не уверен, что лучше хранить их в базе данных MySQL.
Он может иметь цепочку правил, а затем оператор для результата, как показано выше.
11 ответов
для построения отчетов вы можете конвертировать бизнес-логику на любом языке программирования. И использовать базы данных для создания отчетов.
против бизнес-логики хранится в базе данных
Я придаю большое значение силе выражения, и я не нахожу Пространство SQL должно быть таким выразительным. Используйте лучшие инструменты, которые у вас есть силы для наиболее подходящих задач. Игра с логикой и выше порядок понятий лучше всего делать на самом высоком уровне уровень. Следовательно, хранение и массовое манипулирование данными лучше всего делать на уровне сервера, вероятно, в хранимых процедурах.
но это зависит. Если у вас есть несколько приложений, взаимодействующих с одной механизм хранения, и вы хотите убедиться, что он сохраняет свою целостность и рабочий процесс, тогда вы должны разгрузить всю логику в сервер базы данных. Или, будьте готовы управлять параллельной разработкой в несколько приложений.
источник: аргументы за/против бизнес-логики в хранимых процедурах
Читайте также:
CREATE TABLE businessRule (
id INT NOT NULL ,
name VARCHAR(32) NOT NULL ,
description VARCHAR(255) NULL ,
statement VARCHAR(255) NOT NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB;
CREATE TABLE leftOperand (
id INT NOT NULL ,
value VARCHAR(255) NOT NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB;
CREATE TABLE ruleItem (
id INT NOT NULL ,
businessRuleId INT NOT NULL ,
operator ENUM('if','and','or','not') NOT NULL ,
loperand INT NOT NULL ,
comparator ENUM('<','=','>') NOT NULL ,
roperand VARCHAR(255) NOT NULL ,
roperand_ispercentage TINYINT(1) NOT NULL ,
PRIMARY KEY (id) ,
INDEX businessRule_FK (businessRuleId ASC) ,
INDEX leftOperand_FK (loperand ASC) ,
CONSTRAINT businessRule_FK
FOREIGN KEY (businessRuleId )
REFERENCES mydb.businessRule (id )
ON DELETE CASCADE
ON UPDATE RESTRICT,
CONSTRAINT leftOperand_FK
FOREIGN KEY (loperand )
REFERENCES mydb.leftOperand (id )
ON DELETE RESTRICT
ON UPDATE RESTRICT)
ENGINE = InnoDB;
аргумент против" мягкого кодирования " бизнес-логики, как это:http://thedailywtf.com/Articles/Soft_Coding.aspx
"причина, по которой мы находим себе мягкое кодирование, заключается в том, что мы боимся изменений. Не обычный страх перемен, а страх, что код, который мы пишем, придется изменить в результате изменения бизнес-правил. Это довольно глупый страх. Весь смысл программного обеспечения (следовательно, "мягкого") заключается в том, что оно может изменить то, что оно изменит. Единственный способ изолировать программное обеспечение от изменений бизнес-правил-это создать полностью универсальную программу, которая лишена всех бизнес-правил, но может реализовать любое правило. О, и они уже построили этот инструмент. Это называется C++. И Java. И C#. И Основной. И, осмелюсь сказать, КОБОЛ."
общий способ проектирования базы данных для хранения сложных данных, как это, чтобы спроектировать, как вы бы сохранить их в памяти в качестве объектов, а затем попытаться спроектировать базу данных соответственно. В конце концов, вы будете оценивать правила на языке программирования. Процедура будет следующей: сначала диаграмма классов
тогда пришло время преобразовать его в ERD:
Как только у вас есть структура базы данных для хранения/перезагрузки объекта в/Из, вы можете просто создать свои классы, чтобы каждый объект отвечал за загрузку/хранение себя.
[обновление]
например, если вы хотите сохранить заявлением a + b * -c
в базу данных, оно может быть переведено как следующие вставки:
-- c
INSERT INTO statement (statement_id) VALUES (1);
INSERT INTO operand (statement_id, type) VALUES (1, 'double');
-- - (minus)
INSERT INTO statement (statement_id) VALUES (2);
INSERT INTO operator (statement_id, type) VALUES (2, 'minus');
-- -c
INSERT INTO binary (operator_statement_id, operand_statement_id) VALUES (2, 1);
-- b
INSERT INTO statement (statement_id) VALUES (3);
INSERT INTO operand (statement_id, type) VALUES (3, 'double');
-- * (multiply)
INSERT INTO statement (statement_id) VALUES (4);
INSERT INTO operator (statement_id, type) VALUES (4, 'multiply');
-- b * -c
INSERT INTO unary (operator_statement_id, operand_statement_id1, operand_statement_id2) VALUES (4, 3, 2);
-- a
INSERT INTO statement (statement_id) VALUES (5);
INSERT INTO operand (statement_id, type) VALUES (5, 'double');
-- + (plus)
INSERT INTO statement (statement_id) VALUES (6);
INSERT INTO operator (statement_id, type) VALUES (6, 'sum');
-- a + b * -c
INSERT INTO unary (operator_statement_id, operand_statement_id1, operand_statement_id2) VALUES (6, 5, 4);
Итак, если я правильно понимаю, вы хотите использовать передний конец, чтобы позволить людям динамически создавать логику, которая будет применяться к запросам (динамически построенные предложения where во время выполнения, на основе которых используются правила)?
Если это так, вам нужно будет довольно точно указать, какие условия они могут выбрать в своих правилах (изменить в каком значении (столбце), чтобы они могли иметь только условные правила для столбцов, которые существуют в наборе данных, который вы сообщаете от.)
Если я правильно понимаю ваш вопрос, я бы начал с отображения, какие таблицы / столбцы вы хотите, чтобы они могли выбирать условия. Это будут ваши элементы управления для веб-страницы для разработки правил.
однако, если вы просто спрашиваете, как хранить правила, как только они выбраны в базе данных, я бы предложил сохранить его в одной таблице, которая содержит:
ID | RuleSetName | Table | Column | Comparison | Value | Percentage | Notes | CreatedDate | Created By
1 | 'VisitorAnalytics' | Visitors | SUM(Views) | > | null | 10 | n/a | 1/1/2012 | JohnDoe
затем, как только эти записи будут созданы, вы будете использовать их вставка таблиц в предложение from, столбцов в предложение where для динамического sql.
Я знаю, что это может показаться запутанным, но то, что вы спрашиваете, является довольно сложным решением. Но в конечном итоге вы просто хотите сохранить правила вместе в одном месте, где вы можете выполнить цикл для динамической сборки, а затем выполнить SQL для создания отчета. Надеюсь, это укажет вам правильное направление.
Я думаю, что сначала нужно сделать вопрос, следует ли вам вводить правила в базу данных для начала.
базы данных-это тяжелое решение, и часто просто не нужны.
имея дело с движками правил в различных формах, в том числе с базой данных, я могу сказать, что это может стать очень неприятным и непродуктивным, очень быстро. Одна из больших ошибок, которые я видел, - это попытка написать свои собственные правила ad-hoc язык и использование этого для управления условной логикой через базу данных. По крайней мере, используйте уже проверенный язык (Python, javscript и т. д.) и встраивайте его туда.
еще лучше - если правила достаточно сложные, я лично предпочитаю использовать электронные таблицы Excel. Мы используем это для автоматизации (для обработки переменной логики на основе даты вступления в силу и т. д.), а также компилируем довольно сложную логику рейтинга страхования для сценариев Perl, взаимодействующих через веб-сервис, используя это продукт: http://decisionresearch.com/products/rating.html.
контраст хранения логики в базе данных по сравнению, скажем, с электронной таблицей Excel:
- логика в базе данных сложнее тестировать и разрабатывать по сравнению с Excel, потому что Excel обеспечивает мгновенную обратную связь.
- база данных менее (гораздо менее) выразительна по сравнению с Excel.
- вы можете цветовой код и добавить все виды других визуальных сигналов в Excel, чтобы сделать ошибку условия и т. д. действительно выделяются.
теперь, конечно, как вы можете себе представить, движок правил Excel, управляемый веб-службой, не будет соответствовать каждой ситуации. И это не единственное возможное решение.
Я имею в виду, что убедитесь, что вы делаете правильный компромисс с точки зрения удобства/выразительности/тестируемости/производительности. Там, где я работаю, быть правым и продуктивным важнее, чем быть быстрым в исполнении, поэтому мы идем с В Excel/web-сервиса.
и, чтобы расширить комментарий slavik262,чего вы действительно хотите достичь с помощью движков правил, в конечном счете, это абстракция и обобщение, чтобы свести к минимуму движущиеся части и повысить надежность, тестируемость и понятность. движок правил базы данных, по моему опыту, является неоптимальным по сравнению с даже просто созданием, скажем, правил на основе Java. До тех пор, пока они изолированы и организованы должным образом, и скрываются за обобщенным и последовательный интерфейс, тогда они работают просто отлично.
в моей компании это зависит от масштаба правил и того, как часто они меняются относительно того, с чем мы идем. Рейтинг страхования-Excel, никаких вопросов по этому поводу. Какая-то государственная логика? Интерфейсные файлы правил Java достаточно просто отлично.
Я предполагаю, что цель правил-назвать вычисляемые поля из существующей таблицы базы данных (или таблиц). В противном случае, для простых целей отчетности, вы можете сбросить данные в Excel и позволить пользователям использовать функции Excel и сводные таблицы для своих целей.
ключевой вопрос заключается в том, как вы собираетесь преобразовать правила в действие. Если целью является только хранение бизнес-правил, чтобы можно было создать отчет бизнес-правил, то простая структура данных в SQL хватать.
однако, если вы хотите превратить правила в код, вам нужно рассмотреть, где будет выполняться код. Когда данные хранятся в SQL, у вас есть несколько вариантов:
- создайте код SQL, который будет извлекать результаты "бизнес-правила".
- создайте пользовательскую функцию, которая будет анализировать и выполнять бизнес-правила.
- извлеките данные в другую среду, такую как C++ или C#, и запустите код там.
У меня есть предубеждение к первому из них. Основная причина заключается в том, что он ограничивает инструменты одним: SQL.
Я не уверен, что ваши правила делают; ключ-это то, что делает компонент "оператор". Предположим, что это константа или выражение для данных, которые можно вычислить. В этом случае ваши правила начинают выглядеть как заявление по делу. Одно предостережение заключается в том, что оператор может потребовать просмотра более одной строки в таблице данных (для обрабатывать изменения с течением времени).
моя рекомендация-хранить эти правила в базе данных. Это хранилище позволит вам построить запрос из последовательности бизнес-правил, используя кодировку SQL. Mysql позволяет динамический SQL (в настоящее время). Не зная немного больше о базовой таблице и правилах, трудно дать больше информации.
Я могу сказать, что я разработал гораздо более сложную систему, используемую для анализа сценариев. Сами сценарии хранились в электронные таблицы, таблицы, константы и так далее-очень похоже на ваши бизнес-правила. Система работала с использованием SQL (и некоторых Excel) для преобразования представления электронной таблицы сценария в (гигантский) запрос. Затем он может запустить запрос для создания связанных отчетов. Эта система оказалась гибкой, эффективной и мощной.
Если вам не нужно выполнять поиск на основе компонентов правил, вы можете сохранить правило в двух полях базы данных. Условие, при котором оператор выполняется в одном и оператор, который выполняется в другом.
id, name, description, condition, statement
ваши правила могут быть сохранены с помощью JSON или аналогичного формата.
мне нужно будет определить некоторую терминологию, которую я буду использовать. Есть атомная термины, системные значения по сравнению со значениями, введенными пользователь, который оценивает значение true / false и сложные термины, термины, объединенные с использованием логических операторов.
на атомная срок, var обозначает значение, которое система предоставит (например, количество посетителей или количество уникальных посетителей). сравнения определить как var должен быть оценен в отношении стоимостью. The стоимостью - это число или строка, которую создает пользователь. Когда var и значение оба числа, сравнения могут быть "=", или">". Когда var и value являются строками, сравнения могут быть "равными", "начинается с", "заканчивается"или " содержит". Атомарные термины могут храниться следующим образом:
{ var: varName, comp: comparison, value: numberOrString }
вы можете хранить сложные термины, состоящие из конъюнкции, дизъюнкции и отрицания (и/или/не), используя следующие форматы.
// Conjunction
{ op: "and", terms: [ term, ..., term ] }
// Disjunction
{ op: "or", terms: [ term, ..., term ] }
// Negation
{ op: "not", term: term }
затем вы можете создавать операторы, которые оцениваются в true / false с помощью этих методов. - пример выглядит следующим образом:
{ op: "and", terms: [
{op "or", terms: [
{ field: "numVisitors", comp: ">", value: 1000 },
{ field: "numUniqueVisitors", comp: ">=" 100 }
]},
{ op: "not", term: {
{ field: "numVisitors", comp: "<", value: 500 }
}}
]}
приведенный выше пример приравнивается к true, когда число посетителей больше 1000 или число уникальных посетителей больше или равно 100, а число посетителей не менее 500.
затем вы можете выполнить то, что вы называете "оператором", когда правило оценивается как true.
один простой способ сделать это-использовать OODBMS. Там методы инкапсулируются с помощью слотов в объекты, и они даже могут быть выполнены в базе данных (например, триггеры).
Теперь, если вы настаиваете на базе данных SQL, вы можете использовать динамический язык программирования и иметь таблицу для хранения кода, возможно, связанную с другими таблицами или строками.
несколько лет назад я видел тендер на налоговую систему алжирского правительства, в котором они планировали хранить бизнес правила (налоговые правила), как код Visual Basic в СУБД.
вы можете выбрать любой язык, для которого вы можете легко встроить интерпретатор в свое приложение (Common Lisp http://ecls.sourceforge.net; или http://common-lisp.net/project/armedbear/ Если вы пишете свое приложение на Java), Lua, Javascript, Scheme и т. д.
это, как правило, в пользу общего Lisp или схемы, так как с этими языками вы можете легко написать DSL для бизнеса правила.
приведенный пример может быть записан как символическое выражение, такое как:
(rule :name "RuleName"
:description "Some description"
:body (if (and (< (change-in total-visitor) (percent 10))
(> (change-in unique-visitors) (percent 2)))
(do-something)))
в lisp такое символьное выражение может быть распечатано с помощью операторов PRINT или PRINT-to-STRING, чтобы вы могли вставить это выражение в базу данных SQL:
insert into rules (id,expression) values (42,"(rule :name \"RuleName\"
:description \"Some description\"
:body (if (and (< (change-in total-visitor) (percent 10))
(> (change-in unique-visitors) (percent 2)))
(do-something)))");
и вы можете получить его обратно из SQL, прочитать его как символическое выражение с операторами чтения lisp или чтения из строки, а затем, с правильным DSL, вы можете оценить его с помощью lisp Оператор EVAL:
;; with the right DSL written:
(eval (read-from-string (sql-select (expression) :where (= id 42))))
единственное возможное преимущество использования хранимых процедур является возможность доступа к базе данных из приложений, использующих различные технологии, такие как Python и Java.
Я полагаю, что у вас уже есть существующие правила и требования бизнес-логики?.. Это самый важный фактор для разработки схемы, выбора лучших инструментов разработки клиентов и разработки клиентских программ и процедур. Я сделал это для моего приложения управления ломбардом. Функциональность приложения полностью управляется таблицей. Он имеет контрольные таблицы, в которых администратор может изменить допустимые параметры, чтобы изменить способ работы системы. Когда в сочетании со структурированными методами программирования это минимизирует количество модификаций программного кода. Банковские приложения также являются хорошим примером, которые имеют сложные бизнес-правила.