0

これはしばらくの間私を疑わせたものなので、ここに投稿して洞察を見つけるのは良い考えだと思いました。これはリレーショナルデータベースモデリングの問題/疑いです。

私は次の問題を抱えています:

特定の「状態」にある必要がある「質問」があり、状態のすべての変化を監査する必要があります。

私はこれに対する2つの解決策を見つけましたが、もしあれば、それらの違いを実際に見ることはできません...あなたはどう思いますか。

これが両方の図の画像です。

編集:

オプションA:テーブル「questions」にはstate_idを含めないでください。また、Question_Stateには「id」フィールドを含めないでください。間違いでごめんなさい。

EDIT2

すべての実世界の例と洞察に感謝しますが、これは学術的な問題であり、実世界に関連するものではありませんでした:)。

ダイアグラム

4

6 に答える 6

5

あなたが求めていることの要点は次のとおりだと思います:質問の状態は、時間コンポーネント(A)を持つ質問と状態の間の中間テーブルに基づいている必要がありますか、またはテーブルはより静的である必要がありますが、ログ指向ですサイドの履歴テーブル (B)。

(注: (A) の純粋なバージョンを実行したい場合は、Boofus の言うとおりです。おそらく、state_id は冗長であるため、Questions テーブルにも入れないでしょう。しかし、それは間違いなく不便です。特定の状態の質問を取得するための単純なクエリははるかに困難です。そのため、ハイブリッド バージョンがここにあります。)

一般に、状態に関する履歴情報を保持する必要があるのが本当に監査目的である場合 (つまり、アプリケーション自体によって定期的にクエリが実行されない場合) は、おそらくオプション B を使用する方がよいでしょう。もう少し単純です(実際には、状態の参照テーブルと以前の状態の「ログ」テーブルを備えた「質問」テーブルが1つだけあります)。それはあなたの意図をもう少しよく示していると思います。

ただし、アプリケーションのセマンティクスがより複雑な場合 (たとえば、「過去 24 時間以内に状態 X になったすべての質問を表示する...」などのクエリがある場合)、(A) のようなアプローチがより理にかなっている可能性があります。それは本質的に、質問の状態を時間依存の事実にすることです。これを行うと、複雑になることに注意してください。すべてのクエリが難しくなり、時間を考慮する必要があるか、質問の state_id を質問テーブルの最新の状態と同期させることを心配する必要があります。そのルートに行く場合は、おそらく「current_state」または質問の何かと呼ぶので、一種の派生情報であることは明らかです。

于 2008-12-05T17:28:17.047 に答える
1

「テンポラル データベース」について Web を調べてみるとよいでしょう。基本的に、変数が質問の状態や人の体重などをキャプチャするかどうかに関係なく、変数の変更の履歴を保存すると同じ問題が発生します。

第二に、あなたの質問はデータベースの設計に関するものであり、概念的なデータ モデリングに関するものではないと思います。私があなたのドリフトを正しく理解しているなら、あなたはどのテーブルのデザインが優れているかを尋ねています.

3 番目に、私はオプション B の方が好きですが、実際にはデータをどうするかによって異なります。

データベース設計と概念モデリングについて質問した理由は、データ分析に関連する概念データ モデリングに「エンティティとリレーションシップ」を使用する慣行をずっと前に採用したためです。論理データベースの設計について説明するときは、「テーブル、列、および行」という用語を使用します。大規模なプロジェクトでは、解析と設計を別々に保つことが非常に有益であることがわかります。そして、それは思ったほど簡単ではありません。

オプション B の図では、履歴テーブルと状態テーブルの間に矢印を追加する必要があります。この単純な例では問題ありませんが、数十のテーブルを持つデータベースにスケールアップするときに同じ慣行を維持すると、図を見るすべての人を混乱させることになります.

于 2008-12-05T21:48:57.427 に答える
0

あなたは監査済みと言います。これは、レポートの目的で履歴情報を保持したいだけであることを意味します。その場合、図Bの方が明確であることをお勧めしますが、質問と歴史、州と歴史の間の1対多の関係もマークする必要があります。

実用性に関しては、上記のような状況であれば、私自身、履歴挿入機能を質問の挿入/更新トリガーにカプセル化し、質問テーブルの量や状態の変化の数が重要になる場合は、履歴テーブルを別のデータベースに配置することを検討します。これにより、後でデータベース管理が容易になります。通常、私はトリガーに注意しています。過度に熱心に使用すると、データベースの保守が困難になる可能性があるためです(何が起こっているのかすぐにはわからないため)が、これは、それらが適切であり、使用するよりも優れた選択肢である明確なケースです。アプリケーションロジック。

ちなみに、2つの図はどちらも、質問が(PKから)各状態に一度しか入ることができないことを示しています。ほとんどの実際のアプリケーションでは間違いが発生し、状態が逆転するため、これが正しいかどうかを検討する必要があります。

于 2008-12-05T18:02:45.933 に答える
0

すべての関係を描画すると、それらは同じになります。

質問テーブルに state_id がある理由がわかりません。履歴テーブルがあるため、質問テーブルに状態を含めることは冗長であり、非同期データが残る可能性があります。

質問の現在の状態が必要な場合は、そうするように思えます

SELECT State_ID FROM Historical WHERE Question_id = ? ORDER BY Date DESC LIMIT 1

(またはSQLのフレーバーが1行だけに制限するために使用する方法)

于 2008-12-05T17:13:27.780 に答える
0

データベースと OO の間に適切な抽象化レイヤーがあると仮定すると、State テーブルをデータベースから取り出して、クラス内の列挙にすることを検討できます。必ずしも持続する必要があるものではありません。

次に、Questions テーブルの State 列と、audit テーブルを作成します。

于 2008-12-05T17:53:56.793 に答える
0

#Boofus のように、質問テーブルに state_id フィールドを持つことの利点を理解できませんでした。

私は、私たち自身のアプリケーションでそのような「状態」の概念をかなり扱ってきました。完全な状態履歴を追跡する必要がある最も複雑な状況や、オブジェクトが複数の状態を持つ可能性がある状況では、次のモデルを使用しています。

代替テキスト

複数の状態の状況では、end_date の値が null かどうかを確認することが考えられます (別の考えとして、テーブルにブール フィールド isActiveState を設定することもできます)。この「複数状態」構成の利点を過小評価しないでください。例:

質問は

  • 閉じて解決

また

  • 閉じられ、解決されていません。

これは、次の 2 つの異なる状態に対応する可能性があります。

  • 「クローズして解決済み」の状態

また

  • 「クローズ済みで未解決」の状態

しかし、最善の解決策は両方を持つことだと思います

  • 「開閉」状態

  • 「解決済み/未解決」状態

そして、質問が複数の状態を持つことを許可する

于 2008-12-07T23:54:25.440 に答える