30

We want to write some business logic rules that work on top of certain data to build reports. Not sure which is the best to store them in the database MySQL.

enter image description here

It can have a chain of the rules and then a statement for the result as shown above.

4

11 に答える 11

20

レポートを作成するために、ビジネス ロジックを任意のプログラミング言語に変換できます。また、データベース データを使用してレポートを生成します。

データベースに格納されたビジネス ロジックに対して

私は表現の力を高く評価していますが、SQL スペースがそれほど表現力に富んでいるとは思いません。最も適切なタスクには、手元にある最高のツールを使用してください。ロジックや高次の概念をいじるのは、最高レベルで行うのが最善です。したがって、ストレージと大容量データの操作は、サーバー レベルで、おそらくストアド プロシージャで行うのが最適です。

しかし、それは依存します。1 つのストレージ メカニズムと対話する複数のアプリケーションがあり、その整合性とワークフローを確実に維持したい場合は、すべてのロジックをデータベース サーバーにオフロードする必要があります。または、複数のアプリケーションで並行開発を管理する準備をしてください。

出典:ストアド プロシージャのビジネス ロジックに対する賛成/反対の引数

以下も参照してください。

  1. データベースのビジネス ロジック
  2. ストアド プロシージャのビジネス ロジック
  3. 条件付き論理式/ルールをデータベースに保存する
于 2012-07-16T07:22:45.427 に答える
15

モデル

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;
于 2012-07-15T08:26:14.823 に答える
14

次のような「ソフト コーディング」ビジネス ロジックに対する議論: http://thedailywtf.com/Articles/Soft_Coding.aspx

「私たちがソフトコーディングをしていると感じる理由は、私たちが変化を恐れているからです。通常の変化への恐怖ではなく、ビジネスルールの変更の結果として、私たちが書いたコードを変更しなければならないという恐怖です。それはかなりばかげた恐怖です。 . ソフトウェア (したがって、「ソフト」) の要点は、変更できるということです. ビジネス ルールの変更からソフトウェアを隔離する唯一の方法は、すべてのビジネス ルールを欠いている完全に汎用的なプログラムを構築することです。あらゆるルールを実装する.ああ、彼らはすでにそのツールを構築しています.それはC++と呼ばれています.そしてJava.そしてC#.そしてBasic.そして、あえて言えば、COBOL."

于 2012-07-18T14:58:48.897 に答える
10

私があなたに提供できるのは、この問題を解決する方法だけであり、答え自体ではありません.

このような複雑なデータを格納するデータベースを設計する一般的な方法は、それらをオブジェクトとしてメモリに保持する方法を設計し、それに応じてデータベースを設計することです。結局、プログラミング言語でルールを評価することになります。手順は次のとおりです。最初にクラス図

クラス図

次に、それを 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);
于 2012-07-18T09:25:05.460 に答える
6

最初に行う必要があるのは、そもそもルールをデータベースに入れる必要があるかどうかという問題だと思います。

データベースは手間のかかるソリューションであり、多くの場合、必要ありません。

データベース駆動型を含むさまざまな形式のルール エンジンを扱ってきたので、すぐにイライラして非生産的になることがわかります。私が見た大きな間違いの 1 つは、独自のアドホック ルール言語を記述しようとして、それを使用してデータベースを介して条件付きロジックを駆動することです。少なくとも、すでに証明されている言語 (Python、javascript など) を使用して、そこに埋め込んでください。

さらに良いことに、ルールが十分に複雑な場合は、個人的には Excel スプレッドシートを使用することを好みます。これを自動化 (有効日に基づいて可変ロジックを処理するためなど) に使用します。また、この製品を使用して、かなり複雑な保険評価ロジックを Web サービス経由でインターフェースされた Perl スクリプトにコンパイルします: http://decisionresearch.com/products/ rating.html

ロジックをデータベースに保存することと、たとえば Excel スプレッドシートに保存することを比較してください。

  1. データベース内のロジックは、Excel に比べてテストと開発が困難です。Excel は即座にフィードバックを提供するからです。
  2. データベースは、Excel に比べて表現力が劣ります (はるかに劣ります)。
  3. エラー状態などを目立たせるために、色分けしたり、他のあらゆる種類の視覚的な合図を Excel に追加したりできます。

もちろん、ご想像のとおり、Web サービス主導の Excel ルール エンジンがすべての状況に適合するわけではありません。そして、ここで可能な唯一の解決策ではありません。

私が得ているのは、使いやすさ/表現力/テスト容易性/パフォーマンスの観点から適切なトレードオフを行っていることを確認することです。私が働いている場所では、実行速度よりも正しく生産性を保つことが重要なので、Excel/Web サービスを使用しています。

そして、slavik262 のコメントを拡張すると、ルール エンジンで本当に達成したいことは、最終的には、可動部分を最小限に抑え、信頼性、テスト容易性、および理解可能性を高めるための抽象化と一般化です。私の経験では、データベース ルール エンジンは、単純に Java ベースのルールを作成する場合と比べて最適ではありません。それらがサンドボックス化され、適切に編成され、一般化された一貫したインターフェースの背後に隠れている限り、問題なく機能します。

私の会社では、ルールの規模と、何を採用するかについてルールが変更される頻度によって異なります。評価保険 - エクセル、それについては疑問の余地はありません。いくつかの州固有のロジック?インターフェース化された Java ルール ファイルで十分です。

于 2012-07-19T00:22:43.750 に答える
5

ルールのコンポーネントに基づいて検索を実行する必要がない場合は、ルールをデータベースの 2 つのフィールドに保存できます。あるステートメントが実行される条件と別のステートメントが実行される条件。

id, name, description, condition, statement

ルールは、JSON または同様の形式を使用して保存できます。

使用する用語をいくつか定義する必要があります。原子項、ユーザーが入力した値と比較して真/偽に評価されるシステム値、および複雑な項、論理演算子を使用して結合された項があります。

アトミックな用語では、varはシステムが提供する値 (訪問者数やユニーク訪問者数など) を表します。比較により、値に対してvarを評価する方法が決まります。は、ユーザーが生成する数値または文字列です。var と value が両方とも数値の場合、比較は "<"、"<="、"="、">="、または ">" になります。var と value が両方とも文字列の場合、比較は「等しい」、「で始まる」、「で終わる」、または「含む」のいずれかになります。原子項は次のように格納できます。

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

次の形式を使用して、接続詞、選言、および否定 (and/or/not) で構成される複雑な用語を格納できます。

// 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 }
    }}
]}

上記の例は、訪問者数が 1000 人を超えるか、一意の訪問者数が 100 以上で、かつ訪問者数が 500 人以上の場合に true とみなされます。

その後、ルールが true と評価されたときに、「ステートメント」と呼ばれるものを実行できます。

于 2012-07-19T14:34:04.517 に答える
4

したがって、私が正しく理解している場合、フロントエンドを使用して、人々がクエリに適用されるロジックを動的に作成できるようにしようとしています (どのルールが使用されているかに基づいて、実行時に where 句を動的に構築します)?

その場合、ルールで選択できる条件についてかなり具体的にする必要があります (レポート元のデータセットに存在する列に対してのみ条件付きルールを設定できるように、値 (列) を変更します)。

あなたの質問を正しく理解している場合は、条件を選択できるようにするテーブル/列をマッピングすることから始めます。これは、ルールを設計するための Web ページのコントロールになります。

ただし、データベースで選択されたルールを保存する方法を尋ねているだけの場合は、以下を含む単一のテーブルに保存することをお勧めします。

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 句に挿入し、列を動的 SQL の where 句に挿入して使用します。

混乱するかもしれませんが、あなたが求めているのはかなり複雑な解決策です。しかし最終的には、ルールを 1 か所にまとめて格納し、ループして動的に構築し、SQL を実行してレポートを生成できるようにするだけです。うまくいけば、これはあなたを正しい方向に向けます。

于 2012-07-13T20:44:02.060 に答える
2

ルールの目的は、既存のデータベーステーブル(または複数のテーブル)から計算フィールドに名前を付けることだと思います。それ以外の場合は、単なるレポートの目的で、データをExcelにダンプし、ユーザーが目的に応じてExcel関数とピボットテーブルを使用できるようにすることができます。

重要な問題は、ルールをどのように実行に移すかです。ビジネスルールを格納することだけが目的であり、ビジネスルールのレポートを作成できる場合は、SQLの単純なデータ構造で十分です。

ただし、ルールをコードに変換する場合は、コードが実行される場所を検討する必要があります。データがSQLに保存される場合、いくつかのオプションがあります。

  • 「ビジネスルール」の結果を抽出するSQLコードを作成します。
  • ビジネスルールを解析して実行するユーザー定義関数を作成します。
  • データをC++やC#などの別の環境に抽出し、そこでコードを実行します。

私はこれらの最初のものに偏見を持っています。主な理由は、ツールがSQLという1つに制限されていることです。

あなたのルールが何をしているのかわかりません。重要なのは、「ステートメント」コンポーネントが行うことです。これは、計算可能なデータの定数または式であると仮定します。その場合、ルールはcaseステートメントのように見え始めます。注意点の1つは、ステートメントでデータテーブルの複数の行を確認する必要がある場合があることです(時間の経過に伴う変更を処理するため)。

これらのルールをデータベースに保存することをお勧めします。このストレージを使用すると、SQLコーディングを使用して一連のビジネスルールからクエリを作成できます。Mysqlは動的SQLを可能にします(現在)。基礎となるテーブルとルールについてもう少し知らなければ、より多くの情報を提供することは困難です。

シナリオ分析に使うもっと複雑なシステムを設計したと言えます。シナリオ自体は、ビジネスルールと同じように、スプレッドシート、一連のテーブル、定数などに保存されていました。システムは、SQL(および一部のExcel)を使用して、シナリオのスプレッドシート表現を(巨大な)クエリに変換することで機能しました。次に、クエリを実行して、関連するレポートを生成できます。このシステムは、柔軟性、パフォーマンス、および強力であることが証明されています。

于 2012-07-20T02:20:55.837 に答える
2

これを行う簡単な方法の 1 つは、OODBMS を使用することです。そこでは、メソッドはスロットでオブジェクトにカプセル化され、データベースで実行することもできます (トリガーのように)。

SQL データベースが必要な場合は、動的プログラミング言語を使用して、おそらく他のテーブルまたは行に関連付けられたコードを格納するテーブルを用意します。

数年前、私はアルジェリア政府の税システムの入札を見ました。そこでは、ビジネス ルール (税ルール) を RDBMS の Visual Basic コードとして保存することを計画していました。

アプリケーションにインタープリターを簡単に埋め込むことができる任意の言語を選択できます (Common Lisp http://ecls.sourceforge.netまたはhttp://common-lisp.net/project/armedbear/でアプリケーションを作成する場合) 。 Java)、Lua、Javascript、Scheme など。

Common Lisp や Scheme を好む傾向があります。これらの言語を使用すると、ビジネス ルールの 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 READ または READ-FROM-STRING 演算子を使用して記号式として読み返すことができます。次に、適切な DSL を使用して、lisp EVAL 演算子を使用して評価できます。

;; with the right DSL written:
(eval (read-from-string (sql-select (expression) :where (= id 42))))
于 2012-07-18T13:41:36.423 に答える
0

ストアド プロシージャを使用する唯一の利点は、Python や Java などのさまざまなテクノロジを使用するアプリケーションからデータベースにアクセスできることです。

于 2012-07-19T16:07:49.747 に答える
0

既存のビジネス ロジックのルールと要件が文書化されていると思いますか?. これは、スキーマを設計し、最適なクライアント開発ツールを選択し、クライアント プログラムと手順を設計するための最も重要な要素です。これは質屋管理アプリケーション用に行いました。アプリケーションの機能は完全にテーブル駆動型です。システムの動作方法を変更するために、管理者が有効なパラメータを変更できるコントロール テーブルがあります。これを構造化プログラミング手法と組み合わせると、プログラミング コードの変更量が最小限に抑えられます。バンキング アプリケーションも、複雑なビジネス ルールを持つ良い例です。

于 2012-07-19T19:00:44.870 に答える