5

私はまもなく、(仕様から)StackOverflowを少し思い出させるプロジェクトの作業を開始します。基本的に、ユーザーが制御するコンテンツを持つWebアプリです。

私が頭の中で輪になって回っている機能の1つは、バージョン管理です。ここStackOverflowでは、各質問と回答に複数のリビジョンを含めることができます。これは、オブジェクトのタイプ(この場合はそのテキスト)が1つしかない場合に実装するのは非常に簡単です。

だから、私の単純なページについては、私は設定されています。

問題は、バージョン管理下にある必要のあるいくつかのオブジェクトに関係があると考えるときに発生します。具体的な例を示すために、ランダムな類似ドメインを選択します。

本/著者情報を追跡するためにWikiのようなサイトを実装していたとしましょう。このサイトの主な焦点は、「作成者」ページを作成および更新することです。これは、テキストとしては非常に単純です(上記のとおり)。ただし、著者と本の間に1対多の関連付けを追加しましょう(つまり、人が多くの本を作成できることは明らかであるため、本は別個のオブジェクトになります)。各本には、著者ページからその本に関する情報ページへのリンクがあります。

ユーザーにとって、著者を説明するテキストベースの「要約」と、その著者と彼らの作品との間のリンクとの間にほとんど違いはありません。したがって、著者ページ、書籍ページ、および著者と書籍の関連付けに「改訂」/編集機能を実装する必要があります。つまり、ユーザーは、著者ページ、書籍ページ、および2つの間の関連付けを編集、履歴の表示、およびロールバックできる必要があります。

その関係が多対多になると、これはさらに複雑になり、複数の著者が本に寄稿したとリストされる可能性があります。

私はいくつかの解決策を考えていますが、どれも私が望むほどきれいではありません(そして少なくともいくつかの繰り返しのコード/冗長データストレージを含みます)、そして私はここの至る所で共通点を見ますが、私は感じます特にデータベースレベルでは、実際にそれを最適に抽出することはできませんでした。与えられた答えにバイアスをかけたくないので、すぐに答えるつもりはありません。

では、このシステムをデータベースレベルでどのように設計しますか?ここでテーブルの仕様を探しています。すぐにわからない場合は、テーブルの仕様とその使用方法の説明を探しています。関連する可能性のある回答については、ASP.NETと、Linq-to-SQL(LTSの多対多に慣れている)またはEntityFrameworkのいずれかを使用します。

編集:明確にするために、私は基本的なDB設計、正規化、多対多のマッピングテーブルなどを理解しています。私はこの特定の状況に対するクリーンなソリューションを探しています。

編集2:システムには単なる本よりもはるかに多くのサブオブジェクトがある可能性があるため、一般化可能なソリューションを探しています。作者は他の作者、雑誌、イベントなどと関係があるかもしれません。一人一人に歴史を実装していくと、たくさんの仕事を繰り返しているような気がします。

4

3 に答える 3

5

これは、データウェアハウジングでよくある問題です。彼らは「ゆっくりと変化する次元」を使用します。

ただし、「バージョン管理された」データを試してみる場合は、いくつかのルールが必要です。

  1. 最初に定義されたとおりに著者と本の関係を記録する必要があります。これは公式の著者と本の関係です。これは、データウェアハウスの人々が「ファクトのないファクトテーブル」と呼んでいるものです。それはキーのペアです。

  2. 本は本の著者の事実の次元です。本は変わる可能性があります。ゆっくりと変化する次元アルゴリズムは数多くあります。最新のものだけを保持し、履歴テーブルを現在のものとは別にすることができます。現在と履歴を区別するためのフラグを使用して、履歴と現在を1つのテーブルに保持します。

  3. 著者は、本の著者の事実の次元です。作者は変更できます。繰り返しますが、多数のSCDアルゴリズムがあります。選択肢を読んでください。詳細については、ラルフキンボールのデータウェアハウスツールキットを参照してください。

関係(著者と本)は事実であり、バージョンは必要ないことに注意してください。それは事実です。「変化」しません。これはtrueであるか、データベースに誤って配置されています。その場合は、削除する必要があります。ファクトにはバージョン番号は必要ありません。

より洗練されたスタースキーマでは、ファクトに対策があります。価格、販売量、コスト、利益など。これらもファクトテーブルに記録されます。これらの情報は時間とともに変化する可能性があります。したがって、ほとんどの場合、各ファクトの時間ディメンションがあります。

したがって、時間は本の著者の事実の次元です。この事実が変更される可能性がある場合は、該当する期間が事実の一部として記録されます。

時間ディメンションは、バージョン番号とまったく同じではありません。少し簡単です。それは、ある時点で、事実が真実であったと述べています。ファクトが変更された場合は、タイムスタンプが異なる新しいファクトを追加します。

特定の時点で、関連するファクトと関連するディメンション値を見つけることができます。

于 2009-08-17T02:32:18.610 に答える
1

各テーブルにテーブルがあります。つまり、著者と本です。

テーブル間には通常の外部キー関係(それが何であれ)があります。

各テーブルには、履歴テーブル、つまりAuthorHistoryとBookHistoryもあります。これらの履歴テーブルには、古い/廃止されたバージョンのレコードが含まれています(たとえば、削除および/または編集された各作成者レコード)。履歴テーブルとの間の外部キー関係はありません。


編集:

一部の機能は各テーブルで類似しています。たとえば、どのテーブルに関係なく、レコードを更新するということは、レコードの古いコピーを対応する履歴テーブルに保存することを意味します。この機能は、データベーストリガー(各テーブルのトリガーの更新と削除)を使用して実装します。私が使用しているデータベースエンジンはトリガーをサポートしているため、アプリケーションに対して透過的になります。これらのトリガー内のコードは、テーブルごとに類似しています(テーブルの名前とフィールド名のリストのみが、テーブルごとに異なります)。


多対多の状況はどうですか?著者を本にマッピングするレコードが実際にはない可能性があるため、これはより困難ですが、以前はレコードがあり、それを履歴アイテムとして表示する必要があります。

編集#2:

多対多の状況の履歴はまだ実装していませんが、なぜ同じにならないのかわかりません。つまり、次のようになります。

  • 多対多の関係は、BookAuthorテーブルが存在することによって実装されます。各テーブルのレコードは、BookIdとAuthorIdだけです。
  • 履歴関係は、対応するBookAuthorHistoryテーブルにあります。
于 2009-08-16T22:18:38.683 に答える
1

CouchDBの理想的なユースケースのように聞こえます。このドキュメント指向データベースを使用すると、無料でリビジョンを取得できます(データベースを個別に構成しない限り、各ドキュメントは自動的にリビジョンされます)。

ドキュメント間にm:nの関係を持つことも可能です。ただし、CouchDBへの移行は非常に大きなステップであり、ASP.NETからどれだけアクセスできるかわかりません。しかし、いくつかの入門チュートリアルを読んでも害はありません。

于 2009-08-17T11:17:39.470 に答える