私は珍しいデータベース構造について考え、誰かが以前にそれを使用しているのを見たことがあるのではないかと思いました。基本的に2つのデータベースを使用しています。
- 最初のデータベースは、現在有効なデータのみを保持します
- 2番目のデータベースは、最初のデータベースで入力、更新、または削除されたすべての履歴を保持します
シナリオ
私は、発生するすべてをログに記録する必要があり、データが頻繁に変更されるプロジェクトに取り組んでいます。
例(実際のものではない)
サッカーリーグのデータベース設計を行う必要があります。このリーグには選手とチームがあります。プレイヤーはしばしばチームを切り替えます。
- 最初の要件:データベースは、次の試合をプレイするために必要な情報を保持する必要があります。これは、すべてのプレーヤー、チーム、および各プレーヤーが現在所属しているチームのリストを意味します。
- 2番目の要件:データベースは、統計の生成に使用する履歴値を保持する必要があります。これは、チームに所属していたすべてのプレーヤーのリスト、またはプレーヤーが参加していたすべてのチームのリストを意味します。
問題
これらの2つの要件は、互いに正反対です。同じデータベースですべてを実行しようとしましたが、意味がありません。最初の要件は「次の試合のプレー」のみを対象とし、2番目の要件は「統計の生成」のみを対象とします。
同じデータベースですべてを行うために、明らかなソフト削除を使用して情報を削除/更新する一種の「挿入のみ」のデータベースを使用しました...
最初は簡単な作業のように見えましたが、プレーヤー、チーム、および各プレーヤーの現在のチームのリストを保持することは、突然、かなり難しくなります。次の一致を再生するために必要なアプリケーションロジックはすでに十分に複雑ですが、データベースは非常に役に立たない設計になり、アプリケーションは次の一致を再生するためにすべてのクエリに「削除済み」チェックを追加する必要があります。
「チームのすべてのプレーヤーが私に来てください」と叫ぶコーチになりたいですか?それから2000人のプレーヤーがあなたのところに来ます。その時点で、おそらく、「このチームで削除されていないすべてのプレイヤーが私のところにやって来ます」と叫ぶでしょう(この愚かなデザインについては誓います)。
私の結論
なぜすべてを同じデータベースに入れる必要があるのか不思議に思いました。多くの列(time_created、who_created_it、time_deleted、who_deleted_it)を追加しない限り、ソフト削除はすべてをログに記録するのに不十分なだけでなく、すべてを複雑にします。データベースの設計が複雑になり、アプリケーションの設計も複雑になります。
また、これら2つの要件は、分割できない1つのアプリケーションの一部として受け取りますが、これは2つの完全に異なるアプリケーションであると考え続けています。なぜ一緒にすべてをしようとしているのですか?
そのとき、データベースを2つに分割することを考えました。次の試合をプレイするためにのみ使用され、現在有効な情報のみが含まれる運用データベースと、作成、削除、および誰が行ったかについて、これまで存在していたすべての情報を保持する履歴データベース。
目標は、2番目のデータベース(履歴)にできるだけ多くの情報を保持しながら、最初のデータベース(運用)とアプリケーションをできるだけシンプルに保つことです。
ご質問
- 以前にそのデザインを見たことがありますか?名前はありますか?
- 私が見逃している明らかな落とし穴はありますか?
編集2015-03-16
現在のアーキテクチャ
基本的に、アーキテクチャ全体を2ステップのプロセスと考えることができます。
ステップ1 :
- アプリケーションが実行中で、ユーザーがいくつかのアクションを実行しています
- イベントが発生するたびに、イベントテーブルに自動的に記録されます(監査ソリューション)。
- 次に、運用データベースの正しい行が更新されます
ステップ2 :
- ジョブがイベントテーブルの最新の挿入を読み取り、この新しいデータを履歴データベースに挿入します。
- ユーザーは履歴データベースを照会して、必要な情報を取得します。
イベントテーブルから、いつでも情報を再構築できます。問題は、このイベントテーブルが簡単にクエリできないことです。これは、履歴データベースが機能する場所です。必要なものを正確に取得しやすい方法でデータを提示する。
すべてを同じテーブルに入れるときの追加の問題
各クエリで「削除されている」チェックの複雑さが増すことについては、すでに懸念を表明しています。しかし、別の問題があります:整合性。
外部キーと制約を多用して、データベースのデータがいつでも有効であることを確認しています。
例を見てみましょう:
制約:チームごとにゴールキーパーは1人だけです。
チームごとにゴールキーパーが1人だけかどうかをチェックする一意のインデックスを追加するのは簡単です。しかし、ゴールキーパーを変更するとどうなりますか。以前の1つについての情報を保持する必要がありますが、同じチームに2つのゴールキーパーがいます。1つはアクティブで、もう1つは非アクティブであり、制約と矛盾します。
確かに制約にチェックを追加するのは簡単ですが、管理および検討する必要があるもう1つのことです。