programing

데이터베이스에 비즈니스 로직 저장

css3 2023. 10. 12. 23:25

데이터베이스에 비즈니스 로직 저장

보고서를 작성하기 위해 특정 데이터 위에 작동하는 비즈니스 논리 규칙을 작성하고자 합니다.데이터베이스 MySQL에 저장하기에 가장 좋은 방법이 무엇인지 확실하지 않습니다.

enter image description here

위와 같이 규칙의 체인과 결과에 대한 문장을 가질 수 있습니다.

보고서 작성을 위해 비즈니스 로직을 프로그래밍 언어로 변환할 수 있습니다.그리고 데이터베이스 데이터를 보고서 생성에 사용합니다.

데이터베이스에 저장된 비즈니스 로직에 반대합니다.

저는 표현력을 높게 평가하는데, SQL 공간이 그렇게 표현력이 있다고 생각하지 않습니다.가장 적절한 작업을 위해 현재 보유하고 있는 최상의 도구를 사용합니다.논리와 고차 개념을 다루는 것이 가장 좋은 방법입니다.따라서 저장 및 대량 데이터 조작은 서버 수준에서, 아마도 저장 프로시저에서 수행되는 것이 가장 좋습니다.

그렇지만 상황에 따라 다르죠.여러 애플리케이션이 하나의 스토리지 메커니즘과 상호 작용하고 있는데, 애플리케이션이 무결성 및 워크플로우를 유지하도록 하려면 모든 로직을 데이터베이스 서버로 오프로드해야 합니다.또는 여러 애플리케이션에서 동시 개발을 관리할 수 있도록 준비해야 합니다.

출처: 저장 프로시저에서 Business Logic에 대한 찬성/반대 주장

참고 항목:

  1. 데이터베이스의 비즈니스 로직
  2. 저장 프로시저의 비즈니스 로직
  3. 조건부 논리식/규칙을 데이터베이스에 저장

Model

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++라고 합니다.자바도.그리고 C#.그리고 베이직.그리고 감히 말씀드리지만, 코볼."

제가 드릴 수 있는 것은 당신이 이 문제를 해결해야 하는 방법이지, 답 자체가 아닙니다.

이와 같이 복잡한 데이터를 저장하기 위해 데이터베이스를 설계하는 일반적인 방법은 데이터를 객체로 메모리에 보관하는 방식으로 설계한 후 그에 따라 데이터베이스를 설계하려고 시도하는 것입니다.당신은 결국 프로그래밍 언어로 규칙을 평가하게 될 것입니다.절차는 다음과 같습니다.우선 수업도.

Class diagram

그럼 이제 ERD로 전환해야 할 때입니다.

enter image description here

개체를 저장/재로드할 데이터베이스 구조가 있으면 각 개체가 자신을 로드/저장하도록 클래스를 만들기만 하면 됩니다.

[업데이트]

를 들어 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);

먼저 해야 할 일은 우선 데이터베이스에 규칙을 넣어야 하는지 여부에 대한 질문이라고 생각합니다.

데이터베이스는 까다로운 솔루션이므로 필요하지 않은 경우가 많습니다.

데이터베이스 구동 방식을 포함한 다양한 형태의 규칙 엔진을 다루었으므로 매우 실망스럽고 생산적이지 않을 수 있습니다.제가 본 가장 큰 실수 중 하나는 특별한 규칙 언어를 작성하려고 시도하는 것입니다. 그리고 이를 사용하여 데이터베이스를 통해 조건부 논리를 실행하는 것입니다.최소한 이미 입증된 언어(파이썬, 자바스크립트 등)를 사용하여 그 안에 포함시키십시오.

더 좋은 점은 규칙이 충분히 복잡하다면 개인적으로 엑셀 스프레드시트를 사용하는 것을 선호합니다.우리는 이것을 자동화(유효일을 기준으로 가변 로직을 처리하는 등)에 사용하고, 이 제품 http://decisionresearch.com/products/rating.html 을 사용하여 웹 서비스를 통해 인터페이스되는 Perl 스크립트에 다소 복잡한 보험 등급 로직을 컴파일합니다.

데이터베이스에 로직을 저장하는 것과 Excel 스프레드시트를 비교하면 다음과 같습니다.

  1. 엑셀은 즉각적인 피드백을 제공하기 때문에 데이터베이스의 로직은 엑셀에 비해 테스트하고 개발하기가 어렵습니다.
  2. 데이터베이스는 엑셀에 비해 표현력이 떨어집니다.
  3. 컬러코드를 만들어 엑셀에 다른 모든 시각적 단서들을 추가하여 에러 상태 등을 눈에 띄게 만들 수 있습니다.

물론, 여러분이 상상할 수 있듯이, 웹 서비스 기반의 엑셀 규칙 엔진이 모든 상황에 적합하지는 않을 것입니다.그리고 이것이 유일하게 가능한 해결책은 아닙니다.

하지만 사용성/표현성/테스트 가능성/성능 측면에서 올바른 절충점을 제시하고 있다는 점이 중요합니다.제가 일하는 곳에서는 빨리 실행하는 것보다 올바르고 생산적인 것이 더 중요하기 때문에 엑셀/웹 서비스를 이용합니다.

slavik262의 의견을 좀 더 자세히 소개하자면, 궁극적으로 규칙 엔진으로 달성하고자 하는 것은 추상화와 일반화로 움직이는 부품을 최소화하고 신뢰성, 테스트성, 이해성을 향상시키는 것입니다.제 경험상 데이터베이스 규칙 엔진은 단순히 자바 기반 규칙을 만드는 것과 비교해도 최적이 아닌 경우가 많습니다.샌드박스가 적절하게 구성되고, 일반화된 일관된 인터페이스 뒤에 숨어 있는 한, 이들은 잘 작동합니다.

우리 회사에서는 규칙의 규모와 규칙이 얼마나 자주 바뀌는지에 따라 달라집니다.등급 보험 - 엑셀, 의심할 여지가 없습니다.어떤 주별 논리인가요?인터페이싱 된 Java 규칙 파일이면 충분합니다.

규칙의 구성요소에 따라 검색을 수행할 필요가 없는 경우, 데이터베이스의 두 필드에 규칙을 저장할 수 있습니다.한 문에서 실행되는 조건과 다른 문에서 실행되는 조건입니다.

id, name, description, condition, statement

JSON 또는 유사한 형식을 사용하여 규칙을 저장할 수 있습니다.

제가 사용할 용어를 정의해야 합니다.원자 항, 참/거짓으로 평가하는 사용자가 입력한 값과 비교되는 시스템 값, 논리 연산자를 사용하여 결합된 복잡한 항 등이 있습니다.

원자 용어에서 var는 시스템이 제공할 값(예: 방문자 수 또는 고유 방문자 수)을 의미합니다.비교를 통해 에 대한 변수 평가 방법이 결정됩니다.은 사용자가 생성하는 숫자 또는 문자열입니다.변수와 값이 모두 숫자인 경우 비교는 "<", "<=", "=", ">=" 또는 ">"일 수 있습니다.변수와 값이 모두 문자열인 경우 비교는 "동일", "시작", "끝" 또는 "포함"일 수 있습니다.원자 항은 다음과 같이 저장할 수 있습니다.

{ var: varName, comp: comparison, value: numberOrString }

다음 형식을 사용하여 접속사, 접속사, 부정사(및/또는 없음)로 구성된 복잡한 용어를 저장할 수 있습니다.

// Conjunction
{ op: "and", terms: [ term, ..., term ] }

// Disjunction
{ op: "or", terms: [ term, ..., term ] }

// Negation
{ op: "not", term: term }

그런 다음 이러한 방법을 사용하여 참/거짓으로 평가하는 문장을 만들 수 있습니다.예는 다음과 같습니다.

{ op: "and", terms: [
    {op "or", terms: [
        { field: "numVisitors", comp: ">", value: 1000 },
        { field: "numUniqueVisitors", comp: ">=" 100 }
    ]},
    { op: "not", term: {
        { field: "numVisitors", comp: "<", value: 500 }
    }}
]}

위의 예는 방문자 수가 1000명 이상이거나 고유 방문자 수가 100명 이상이고 방문자 수가 500명 이상인 경우에 해당합니다.

그런 다음 규칙이 true로 평가될 때 "문"이라고 하는 것을 실행할 수 있습니다.

그렇다면 제가 이해하는 바와 같이, 사람들이 쿼리에 적용할 논리를 동적으로 생성할 수 있도록 프론트 엔드를 사용하려고 하십니까? (실행 시간에 어떤 규칙이 사용되고 있는지에 따라 섹션이 동적으로 구축됨)?

이 경우에는 규칙에서 선택할 수 있는 조건을 상당히 구체적으로 지정해야 합니다(보고 대상 데이터 세트에 존재하는 열에 대한 조건부 규칙만 가질 수 있도록 어떤 값(열)의 변경).

질문을 정확하게 이해하고 있다면 우선 어떤 테이블/열에 대해 조건을 선택할 수 있는지부터 생각해 보겠습니다.웹 페이지에서 규칙을 설계하기 위한 제어 기능이 됩니다.

그러나 데이터베이스에서 규칙을 선택한 후 저장하는 방법을 묻는 경우에는 다음을 포함하는 단일 테이블에 저장하는 것이 좋습니다.

ID  |  RuleSetName         |  Table     |  Column      |  Comparison  |  Value   |  Percentage  |  Notes  |  CreatedDate  |  Created By
1   |  'VisitorAnalytics'  |  Visitors  |  SUM(Views)  |  >           |  null    |  10          |  n/a    |  1/1/2012     |  JohnDoe

그런 다음 이러한 레코드가 생성되면 동적 sql에 대한 from 절에 테이블을 삽입하고 where 절에 열을 삽입하여 레코드를 사용합니다.

혼란스럽게 들릴지도 모르지만, 당신이 요구하는 것은 상당히 복잡한 해결책입니다.그러나 궁극적으로는 규칙을 한 곳에 함께 저장하여 동적으로 구축한 다음 SQL을 실행하여 보고서를 생성할 수 있습니다.이것이 당신이 옳은 방향을 가리키기를 바랍니다.

이를 위한 하나의 쉬운 방법은 OODBMS를 사용하는 것입니다. 거기서, 메소드들은 객체들에 슬롯들로 캡슐화되며, 심지어 트리거들과 같이 데이터베이스에서 실행될 수도 있습니다.

SQL 데이터베이스를 고집한다면 동적 프로그래밍 언어를 사용하고 코드를 저장할 테이블(다른 테이블 또는 행과 연결)을 갖는 것이 가능합니다.

몇 년 전에 저는 알제리 정부의 세금 시스템에 대한 입찰을 보았고, 그들은 비즈니스 규칙(세칙)을 RDBMS에 비주얼 베이직 코드로 저장하려고 계획했습니다.

어플리케이션에 인터프리터를 쉽게 내장할 수 있는 언어를 선택할 수 있습니다(Common Lisp http://ecls.sourceforge.net ; 또는 자바로 어플리케이션을 작성하는 경우 http://common-lisp.net/project/armedbear/ ). Lua, 자바스크립트, 스킴 등.

이 언어를 사용하면 비즈니스 규칙에 대한 DSL을 쉽게 작성할 수 있기 때문에 Common Lisp 또는 Scheme을 선호하는 경향이 있습니다.

주어진 예는 다음과 같은 기호 표현으로 쓸 수 있습니다.

(rule :name "RuleName"
      :description "Some description"
      :body (if (and (< (change-in total-visitor)   (percent 10))
                     (> (change-in unique-visitors) (percent 2)))
                (do-something)))

이러한 기호식은 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 READ 또는 READ-FROM-STRING 연산자를 사용하여 기호식으로 다시 읽을 수 있습니다. 그런 다음 올바른 DSL을 사용하여 lisp EVEL 연산자를 사용하여 평가할 수 있습니다.

;; with the right DSL written:
(eval (read-from-string (sql-select (expression) :where (= id 42))))

규칙의 목적은 기존 데이터베이스 테이블(또는 테이블)에서 계산된 필드의 이름을 지정하는 것입니다.그렇지 않으면 단순한 보고 목적으로 엑셀에 데이터를 집어넣고 사용자가 엑셀 기능과 피벗 테이블을 사용하도록 할 수 있습니다.

핵심적인 질문은 어떻게 규칙을 행동으로 옮길 것인가 하는 것입니다.비즈니스 규칙을 저장하기 위한 목적이 비즈니스 규칙 보고서를 생성할 수 있다면 SQL의 간단한 데이터 구조로도 충분합니다.

그러나 규칙을 코드로 전환하려면 코드 실행 위치를 고려해야 합니다.데이터를 SQL에 저장할 경우 다음과 같은 몇 가지 옵션이 있습니다.

  • "비즈니스 규칙"의 결과를 추출할 SQL 코드를 만듭니다.
  • 비즈니스 규칙을 구문 분석하고 실행할 사용자 정의 함수를 만듭니다.
  • 데이터를 C++나 C#과 같은 다른 환경으로 추출하고 코드를 실행합니다.

저는 이 중 첫 번째 것에 대해 편견을 갖고 있습니다.주된 이유는 툴을 SQL이라는 하나로 제한하기 때문입니다.

저는 당신의 규칙이 무엇을 하고 있는지 잘 모르겠습니다. 관건은 "문" 구성요소가 무엇을 하는지 입니다.계산할 수 있는 데이터에 대한 상수 또는 식이라고 가정하겠습니다.그런 경우에는 규칙이 사례 진술처럼 보이기 시작합니다.한 가지 주의해야 할 점은 문장에 데이터 테이블에서 하나 이상의 행을 살펴봐야 시간에 따른 변경 사항을 처리할 수 있다는 것입니다.

이 규칙들을 데이터베이스에 저장하는 것이 좋습니다.이 스토리지를 사용하면 SQL 코딩을 사용하여 일련의 비즈니스 규칙에서 쿼리를 구성할 수 있습니다.Mysql은 동적 SQL(현재)을 허용합니다.기본적인 표와 규칙에 대해 조금도 알지 못하면 더 많은 정보를 제공하기가 어렵습니다.

시나리오 분석에 사용되는 훨씬 더 복잡한 시스템을 설계했다고 할 수 있습니다.시나리오 자체는 비즈니스 규칙과 마찬가지로 일련의 테이블, 상수 등에 스프레드시트에 저장됩니다.이 시스템은 SQL (및 일부 Excel)을 사용하여 시나리오의 스프레드시트 표현을 (거대한) 쿼리로 변환하여 작동했습니다.그런 다음 쿼리를 실행하여 연관된 보고서를 생성할 수 있습니다.이 시스템은 유연하고 성능이 뛰어나며 강력한 것으로 입증되었습니다.

저장 프로시저를 사용할 때 얻을 수 있는 유일한 이점은 Python 및 Java와 같은 다양한 기술을 사용하는 애플리케이션에서 데이터베이스에 액세스할 수 있는 가능성입니다.

기존의 비즈니스 논리 규칙과 요구사항을 문서화한 것으로 생각됩니다.이것이 스키마를 설계하고, 최상의 클라이언트 개발 도구를 선택하고, 클라이언트 프로그램과 절차를 설계하는 데 가장 중요한 요소입니다.저는 전당포 관리 애플리케이션을 위해 이 작업을 했습니다.응용프로그램의 기능은 완전히 테이블 중심입니다.관리자가 시스템 작동 방식을 수정하기 위해 유효한 매개 변수를 변경할 수 있는 제어 테이블이 있습니다.구조화된 프로그래밍 기술과 결합하면 프로그래밍 코드 수정량을 최소화할 수 있습니다.은행 애플리케이션도 복잡한 비즈니스 규칙을 가지고 있는 좋은 예입니다.

언급URL : https://stackoverflow.com/questions/11407062/storing-business-logic-in-database