44

ユーザーが入力した変更を特定のテーブルに保存する必要がありますが、管理ユーザーによって表示および承認されるまで、それらの変更は表示されません。これらの変更がまだ保留状態にある間、古いバージョンのデータを表示します。承認待ちのこれらの変更を保存する最良の方法は何でしょうか?

いくつかの方法を考えましたが、どの方法が最適かわかりません。これは非常に小さな Web アプリです。1 つの方法は、他のテーブルのスキーマを模倣する PendingChanges テーブルを用意し、変更が承認されたら、実際のテーブルを情報で更新することです。もう 1 つのアプローチは、テーブルにデータの複数のバージョンを保存し、承認済みとマークされた最も高いバージョン番号を持つレコードを常にプルする、ある種のレコード バージョン管理を行うことです。これにより、余分なテーブルの数が制限されます (複数のテーブルに対してこれを行う必要があります) が、適切なレコードを確実に取得するために、一連のレコードを引き出すたびに追加の処理を行う必要があります。

これらの方法やその他の良い方法に関する個人的な経験はありますか?

更新: 明確にするために、この特定の状況では、過去のデータにはあまり興味がありません。ユーザーが行った変更をサイトに公開する前に承認する何らかの方法が必要なだけです。そのため、ユーザーは自分の「プロファイル」を編集し、管理者はその変更を確認して承認します。承認されると、それが表示される値になり、古いバージョンを保持する必要はありません。

特別な PendingChanges テーブルで XML として追跡する必要があるテーブルからの保留中の変更を格納する以下のソリューションを試した人はいますか? 各レコードには、変更が行われたテーブルを示す列、変更されるレコードの ID (新しいレコードの場合は null) を格納する列、変更が行われたときに格納する日時列、および変更されたレコードの xml を格納する列 (おそらくデータ オブジェクトをシリアル化できます)。履歴は必要ないので、変更が承認された後、実際のテーブルが更新され、PendingChange レコードが削除される可能性があります。

その方法について何か考えはありますか?

4

8 に答える 8

21

データが承認されているかどうかを示す列を含むメイン テーブルに確実に格納します。

変更が承認されると、コピーは必要ありません。未承認のデータをフィルタリングする余分な作業は、考えてみれば、データベースが行うべきことのようなものです。承認された列にインデックスを付ければ、正しいことを行うのに負担がかかりすぎることはありません。

于 2008-09-19T17:12:23.920 に答える
12

Size is your enemy. If you are dealing with lots of data and large numbers of rows, then having the historical mixed in with the current will hammer you. You'll also have problems if you join out to other data with making sure you've got the right rows.

If you need to save the historical data to show changes over time, I would go with the separate historical, table that updates the live, real data once it's approved. It's just all-around cleaner.

If you have a lot of datatypes that will have this mechanism but don't need to keep a historical record, I would suggest a common queue talbe for reviewing pending items, say stored as xml. This would allow just one table to be read by administrators and would enable you to add this functionality to any table in you system fairly easily.

于 2008-09-19T17:16:14.007 に答える
6

私は銀行のドメインで働いており、あるユーザーが行った変更は、別のユーザーが承認した後にのみ反映する必要があるというニーズがあります。使用するデザインは以下の通りです

  1. メインテーブルA
  2. 変更されたレコードを格納する別のテーブル B (最初のテーブルとまったく同じです) + 2 つの追加列 (C の FKey と変更の種類を示すコード)
  3. 承認が必要なすべてのレコードを格納する 3 番目のテーブル C
  4. 履歴を格納する 4 番目のテーブル D (おそらくこれは必要ありません)。

このアプローチをお勧めします。更新や削除を含むすべてのシナリオを非常に適切に処理します。

于 2008-09-19T18:16:32.737 に答える
4

ほとんどの上場企業に押し付けられてきた SOx コンプライアンスの動きを考えると、私はこの分野でかなりの経験を積んできました。通常、私は別のテーブルを使用しており、タイムスタンプ付きの保留中の変更には、ある種のフラグ列があります。このデータの管理担当者は、保留中の変更のリストを取得し、受け入れるかどうかを選択できます。データの一部が受け入れられると、トリガーを使用して新しいデータをテーブルに統合します。一部の人々はトリガーメソッドが好きではなく、むしろこれをストアドプロシージャにコーディングしたいと考えています。これは、かなり大規模なデータベースであっても、私にとってはうまくいきました。特に、ある変更が別の変更と直接競合し、これらの変更をどのような順序で処理するかという状況に対処する場合は、複雑さに対処するのが少し難しくなる可能性があります。要求データを保持するテーブルは、特定の状況で何が起こったかを追跡する必要がある場合に必要な、いわば「パンくず」を保持するため、決して削除することはできません。しかし、どのアプローチにおいても、競合するデータで述べたように、リスクを評価する必要があり、これらの状況でのプロセスを決定するためにビジネス ロジック レイヤーを配置する必要があります。

個人的には、同じテーブル メソッドは好きではありません。データ ストアが常に変更されている場合、テーブル内のこの余分なデータによって、テーブルのリクエストが不必要に停止する可能性があり、どのように処理するかについてより詳細な情報が必要になるためです。テーブルと実行計画にインデックスを付けています。

于 2008-09-19T17:23:41.397 に答える
2

さらに別のアイデアは、3 つのテーブルを持つことです。

  • 1 つは、元のデータを保持するメイン テーブルです。
  • 2 つ目は、提案されたデータを保持します。
  • 3 つ目は履歴データを保持します。

このアプローチにより、迅速かつ簡単にロールバックできるようになり、必要に応じて監査証跡も得られます。

于 2008-09-19T17:44:37.900 に答える
2

フラグ付きのテーブルを作成し、次のようなビューを作成します

 CREATE OR REPLACE VIEW AS 

  SELECT * FROM my_table where approved = 1

承認とクエリの間の依存関係を分離するのに役立ちます。ただし、ビューを更新する必要がある場合は、最善の方法ではない可能性があります。

レコードの移動には、パフォーマンスに関する考慮事項がいくつかある場合があります。しかし、パーティション化されたテーブルは非常に似たようなことをすることができます.

于 2008-09-19T18:38:36.677 に答える
1

これは Web アプリであるため、書き込みよりも読み取りが多く、かなり高速なものが必要であり、競合の解決 (つまり、順不同の承認) が同じ動作になると仮定します。最新の更新は、使用されている。

あなたが提案する両方の戦略は、どちらも変更セットごとに1行を保持し、競合などに対処する必要があるという点で似ています。唯一の違いは、データを1つまたは2つのテーブルに保存するかどうかです。シナリオを考えると、パフォーマンス上の理由から、2 つのテーブルがより良い解決策と思われます。データベースがサポートしている場合は、1 つのテーブルと最近承認された変更のビューでこれを解決することもできます。

于 2008-09-19T17:36:46.810 に答える
0

複数のテーブルへのスケーリングが優れているという理由だけで、2 番目の方法の方が優れたアプローチだと思います。また、「承認済み」ビットに基づいてテーブルへのインデックスを作成でき、承認済み (表示用) または未承認 (承認用) のエントリをプルするようにクエリを特殊化できるため、余分な処理は最小限に抑えられます。

于 2008-09-19T17:14:24.743 に答える