イデオロギーと金融システム開発の問題。 パート2

前回、私は金融システムの構造を計画する際に通常忘れられる、承認とアクセス権の計画に関連する小さなことについて話をしようとしました。



今回は問題についてお話ししたかったのですが、金融システムの設計の後の段階で問題を解消することは最も費用がかかり、時間がかかります。



例を考えてみましょう。

システムのデータベースにいくつかのテーブルがあるとします。 それらの1つは、法人のディレクトリです。 開発者/アナリストとして、ある種のドキュメントを操作するための機能を設計する必要があります。 たとえば、支払い注文を作成および編集する機能を開発する必要があるとします。 1つの支払い注文に次のフィールドが必要であるとします:



1.一意の番号

2.作成日時

3.支払いの日時

4.支払いが行われた法人(取引相手)

5.量

6.支払い方法



すぐに、一意のドキュメント番号をデータベーステーブルのエントリのIDに関連付ける価値はほとんどないことに注意してください。 ここに問題があります。ユーザーは間違いを犯すことができます。 ユーザーのロジックは非常に独特な場合があります。たとえば、時々、誤って作成されたドキュメントを削除して新しい方法で作成する方が簡単な場合があります(これは特に「混乱」を恐れる新入社員に当てはまります)。 このようなアクションの後、システム内のドキュメント番号間に多くの空の「穴」ができます。 それは些細なことのように思えますが、「関心のある」人による検証はこれに秘密の意図を見つけるでしょう。 (実際の例が必要な場合は、グーグル「Prime-TASSがモスクワ市役所を訴えた」。彼らの全証拠ベース-文書番号は整理されていたが、公開されているのはそのうちのいくつかだけである)。 私たちの意見では、新しく作成されたドキュメントに番号を割り当てることをお勧めします=このタイプのドキュメントのシステムでの最大一意の番号+ 1。

しかし、例に戻りましょう。 フィールド番号4-法人に注意してください。 法人のディレクトリができたらすぐに、このフィールドのこのディレクトリのエントリへのリンクを記録するのは明らかです。

次に、考えられるいくつかの状況を想像してください。

1)2009年に支払い注文が作成されました。 支払いはベッドによって行われました。 2010年1月、同社はChairs LLCに社名変更されました。 2010年末に支払い注文フォームを開くと、2009年には物理的に存在しなかった会社に支払いが行われたことがわかります。

2)2010年3月にLLC「ベッド」とCJSC「ソファス」の合併が発生したとします。結果はOJSC「ソファスとベッド」でした。 ユーザーは何ができますか? また、OJSCのLLC LLCの名前を「ソファ」と「ソファ」に変更できます。また、「ソファベッド」のZAOの名前を「ソファ」に変更できます。 最も興味深いのは、最初のレポートから始まります。異なる法人間のすべての支払い(実際には3つ、データベースでは4つ)が混同され、支払いを行った人だけがそれらを区別できました(残念ながら、人員削減の対象になり、すでに数か月でした)あなたの会社では働かないでください)。





もちろん、すべてのアクションは履歴によって復元できます。 会計スタッフではなく、あなただけがこれに従事します(まあ、彼らはあなたのシステムの内部をいじくり回しません、結局、彼らはまだ整理する必要がある大量の紙片を持っています;そして、最終的に、誰がシステムを設計しましたか?それはあなたの問題を意味します。会計士は通常、システムを扱うのではなく、支払う仕事を持っています)。



そして、これはすべて根本的に間違っています:

a)あなたは、あなたがまったく実行する資格のない行動に対して責任を負います。

b)原則として、解決できない状況があります。

c)これはシステムの明らかな間違いであり、発生は予測できませんでした。



だから、私が話したいことに行きました。



ドキュメントに関連するエンティティを設計します。




いくつかの要件を提示します。

1.すべてのドキュメントデータは、変更に対する耐性が必要です。 これは、ユーザーが支払い注文の受取人を変更したい場合、これを行うことができないことを意味しませんが、これは、法人のディレクトリ内の受取人の名前を変更すると、古い名前が支払い注文に反映されることを意味します。

2.ドキュメントは、ビジネスプロセスで説明されているロジックに耐える必要があります。 説明した例では、これは、名前が異なるすべての法人のすべての支払注文の金額を合計する必要がある場合、これを行う技術的能力があることを意味します。



私の経験が許す限り(モスクワ市庁舎システムからの挨拶)、ほとんどの人が最初の段落を覚えていると言えますが、段落2を覚えている人はほとんどいません。 つまり これは通常、次のように実装されます。ドキュメントのすべてのフィールド(通常、ドキュメントの印刷形式に該当するすべてのフィールド)は、データベーステーブルのテキストテーブルに格納されます。 この例では、これは会社への参照に加えて、この会社の名前もテーブルに保存されることを意味します。

もちろん、これはいくつかの問題を排除しますが、すべてではありません。 そして一般的に、これはイデオロギー的に間違っています。リンクはある名前の会社に保存され、別の名前が支払いオーダーに表示されます(会社の名前が変更された場合)。



この問題の解決方法


次の2つのオプションを検討しました。



1.法人のディレクトリには、すべての変更が保存されます。 つまり ディレクトリ内のデータを更新するとき、変更履歴を記録するだけでなく、変更される行を物理的に更新しません-単に非アクティブとしてマークします。 これにより、フラグ「現在のレコード」を持つ新しい行が作成されます。 この場合、親レコードへのリンクが新しく記録された行に作成されます。 この行の前のバージョンに。 また、文字列の新しいバージョンを作成するとき、その作成時間は修正されます。

したがって、ドキュメントの作成日(支払い注文の例)がわかれば、その時点で取引相手のどのデータが関連していたかを常に知ることができます。

さらに、レコードバージョンはテーブル内で異なるIDを持っているため、それらによって要約(グループ化/分類/共有)するのは楽しいことです。



2.法人のディレクトリは2つのテーブルで構成されています。

最初のフィールドには、このエンティティを特徴付けるフィールドのみが含まれ、メインと呼ばれます。 通常、これらは特定のエンティティの不変フィールドです(企業の例では、TINとPPCのペアが表示される可能性が高い)。 そのようなフィールドがゼロになる可能性が高いことに注意してください。 唯一の不変のフィールドはテーブル内のIDであり、これは絶対に正常です。

2番目のフィールドには、このエンティティのすべてのフィールドと、親テーブルのレコードへのリンクと新しいレコードが作成された時刻が含まれます。

したがって、この法人を参​​照するすべてのドキュメントは1つのリンク(メインテーブルのエントリへ)を保存しますが、このドキュメントに関連するバージョンは、ドキュメントが作成された時刻とディレクトリの下位テーブルのエントリの「変更時刻」列によって簡単に復元されます。



その結果、2番目のオプションが選択されました。 理由は次のとおりです。

1.親項目への一般的な参照は、最初のオプションのすべての利点を残します(すべての記録オプションを一時的な変更に簡単に分割して個別に作業できます)が、親レコードのすべてのバージョンで作業しても問題はありません。

2. MS SQL:最初のケースでは、次の変更が前のものを参照するため(つまり、NULL <-ver1 <-ver2 <-ver3 <-... <-verN)

a)変更の履歴全体を表示するには、i番目のノードから左および右へのチェーンをバイパスする必要がありますが、これにはデータベースレベルでいくらかの費用が必要になります。 そして、これはレコードの変更に関する情報のみを返すアトミック関数です。

b)バージョンごとにクラスタリングを使用することは機能しません(2番目の場合、親テーブルのレコードへのリンクにインデックスをハングアップすることは非常に便利です)。 したがって、私たちは(データベースの観点から)非常に安価であり、レコードのすべての変更に関する情報をすばやく受け取ることができます。

3. 2番目のオプションでは、データベースレベルで、メインテーブルに含まれるデータの変更を禁止することは非常に簡単です。 したがって、それらを変更する試みが失敗した場合、ユーザーは少なくとも自分の問題を解決する正しい方法について考えます(極端な場合、プログラムに同伴する人に連絡してください)。



これで2番目の部分には十分だと思います。

すべての質問にお答えいたします。



All Articles