web-dev-qa-db-ja.com

どうすればメーカーチェッカーの原則を実装できますか?

私は、会社のリポジトリでさまざまなクラスのメーカーチェッカー原則を実装する方法を検討しています。基本的にルールは次のとおりです。

  • エンティティとは、ウェブサイトに表示されるオブジェクトです(ブログの投稿など)。
  • 適切な権限/ロールを持つエンティティの作成者がいる(例:ROLE_POST_CREATOR)(元の質問コンテキスト、作成者)
  • 適切な権限/ロール(例:ROLE_POST_APPROVER)を持ち、投稿の作成者(元の質問コンテキストではチェッカー)とは異なるエンティティの承認者がいます
  • 投稿には2つのステータス(DRAFTEDおよびAPPROVED)があり、APPROVEDステータスの投稿のみがWebサイトに表示されます

ここまでは順調ですね。ここが複雑になるところです:

  • 投稿をWebサイトで表示することを承認するだけでなく、Webサイトからの削除(削除)、またはWebサイトでの更新を承認する必要があります。つまり、投稿を更新しても、現在表示されている投稿に影響が及ぶことはなく、承認後にのみ新しいバージョンが表示されるはずです。削除についても同様です(投稿の削除は投稿を削除するためのリクエストに過ぎず、承認後にのみ実際に削除されます)

これのモデリング(Javaで言う)は非常に簡単です。

class SampleClass {
    ...

    private User maker;

    private User checker;

    private Status status;
}

ただし、データベース(特に更新)に永続化することはできません。ここに私が思いつくことができるいくつかのアイデアがあります:

  • すべてのエンティティに対して、2つのテーブル、たとえばSAMPLE_CLASSSAMPLE_CLASS_REQUESTSを設定できます。基本的に、更新されたフィールドを除いて、SAMPLE_CLASSからSAMPLE_CLASS_REQUESTSまでのすべてのフィールドを複製します。 _REQUESTSが承認されたら、そのテーブルから削除し、更新されたバージョンをSAMPLE_CLASSに移動します。

これは非常に実行可能なオプションですが、チェッカーユーザーに表示するSampleClassRequestなどの新しいエンティティを作成する必要があります。これは非常に実現可能なオプションですが、すべてのエンティティに新しいテーブルを作成してメーカーチェッカーを実装することは、100を超える数のテーブル環境ではかなりのオーバーヘッドになります。

  • 更新するSAMPLE_CLASSテーブルにSampleClassの新しいフィールドを作成できます。このシナリオでは、SampleClassRequestを生成する必要がありますが、エンティティごとに新しいテーブルを生成するオーバーヘッドを回避できます。ただし、これは非常に悪いデータベースアーキテクチャのように見えます。

どのように実装しますか?基本的に、デザイン、動作、アーキテクチャを模倣できるサンプルライブラリ、またはこの機能をすでに備えた(Java)ライブラリ、または少なくともガイダンス/サンプル手法を探しています。データベース管理者が作成したサンプルデータベース設計も役立ちます。

2
Hasan Can Saral

状態変更要求テーブルでこれをモデル化します。オブジェクトと変更の種類(公開、削除、コンテンツの置換)を参照します。リクエストが承認されると、状態変更が実行されます。

複数の状態変更要求が処理中の場合は、特別な考慮が必要になります。

1
Martin K

解決すべき2つの問題があります。a)最新の承認済みおよび最新の送信済み状態を追跡すること、およびb)その動作を多数のエンティティに適用することです。

まずはa)に行きましょう。タイムスライスを使用することをお勧めします。これは、たとえば、同じ表のブログ投稿。各バージョンは、valid-from列とvalid-until列を取得します。現在公開されているバージョンには、過去のvalid-fromとnullのvalid-until(または_9999-12-31 23:59:59_など)があります。新しいバージョンが承認されたら、前のバージョンのvalid-untilをNOW()に設定し、承認されたバージョンが有効になるようにします。クエリは正直である必要があります。一部のSQL方言には、このための非常に便利なセマンティクスがあります(T-SQLテンポラルテーブル、_valid_until_がnullにできない場合はBETWEEN)。

何百ものエンティティがこのように動作するようになりました:

すべてのエンティティが非常に類似している場合は、おそらく単一のテーブルの継承でうまくいくでしょう。エンティティが大きく変化する場合、特に一貫性が必要なリレーションシップがある場合は、必要なすべての列をすべてのテーブルで複製することをお勧めします。これはデータベース側では多くのことですが、Hibernateの_@MappedSuperclass_を使用すると、Javaでの複製はまったくありません。

2
cmenke