2

最初は意図的に曖昧なままにしておきます。私は議論を求めており、難しい答えを探しているよりも重要な問題は何かを探しています。

ポートフォリオ管理のようなアプリを設計中です。今まで持っていたデザインは

  • 問題: 解決する必要がある問題
  • 解決策: 1 つまたは複数の問題に対する提案された解決策
  • 関係: 2 つの問題、2 つの解決策、または問題と解決策の間の関係。さらに次のように分類されます。
    • 親子 - ある種の分類 / ツリー階層
    • 重複 - 2 つの解決策または 2 つの問題が実際に同じ概念に対処している度合い
    • アドレス - 問題が解決策に対処する程度

私の質問は、これらの物事の時間的性質についてです。問題が発生し、消えていきます。ソリューションには予想される解決日がありますが、それは開発中に変更される可能性があります。関係の程度は、問題や解決策が進化するにつれて、時間の経過とともに変化する可能性があります。

では、問題は、ポートフォリオの現在と過去の両方の視点を得ることができるように、これらのもののバージョン管理に最適な設計は何ですか?

後で:@Eric Beardの答えはアップする価値がありますが、おそらくこれをより具体的な質問にする必要があります。

私は 3 つのデータベース設計を検討しました。それぞれの欠点を示すのに十分です。私の質問は次のとおりです。どれを選ぶか、またはもっと良いものを考えられますか?

1: 問題 (および個別に解決策) は、バージョン管理において自己参照的です。

table problems
  int id | string name | text description | datetime created_at | int previous_version_id

  foreign key previous_version_id -> problems.id

新しいバージョンが必要になるたびに、その長いdescription列を含む行全体を複製する必要があるため、これは問題です。

2: 新しい関係タイプを作成します: バージョン。

table problems
  int id | string name | text description | datetime created_at

これにより、リレーションシップが問題テーブルとソリューション テーブルからリレーションシップ テーブルに移動するだけです。同じ重複の問題ですが、私はすでに抽象的な関係の概念を持っているので、おそらく少し「きれい」です。

3: より Subversion に似た構造を使用します。問題と解決策のすべての属性を別のテーブルに移動し、それらをバージョン管理します。

table problems
  int id

table attributes
  int id | int thing_id | string thing_type | string name | string value | datetime created_at | int previous_version_id

  foreign key (thing_id, thing_type) -> problems.id or solutions.id
  foreign key previous_version_id -> attributes.id

これは、問題または解決策の現在のバージョンをロードするには、属性のすべてのバージョンを取得し、それらを日付順に並べ替えてから、最新のものを使用する必要があることを意味します。それはひどいことではないかもしれません。私にとって本当に悪いと思われるのは、データベースでこれらの属性をタイプチェックできないことです。そのvalue列はフリーテキストでなければなりません。name列を、列を持つ別のattribute_namesテーブルへの参照にすることはできますが、それはテーブルの正しい型を強制typeしません。attributes

後でまだ:複数テーブルの外部キーに関する@Eric Beardのコメントへの応答:

悲しいかな、私が説明したことは単純です。物事には 2 つのタイプ (問題と解決策) しかありません。私は実際に約 9 つか 10 の異なる種類のモノを持っているので、あなたの戦略の下に 9 列から 10 列の外部キーがあるでしょう。単一テーブルの継承を使用したかったのですが、Things には共通点がほとんどないため、それらを 1 つのテーブルに結合するのは非常に無駄です。

4

5 に答える 5

1

@ガイウス

foreign key (thing_id, thing_type) -> problems.id or solutions.id

これらの種類の「多方向」外部キーには注意してください。私の経験では、結合条件がどのテーブルに結合するかを判断する前にタイプをチェックする必要がある場合、クエリのパフォーマンスが大幅に低下することが示されています。エレガントではないようですが、null許容です

problem_id and solution_id 

はるかにうまく機能します。

もちろん、最新バージョンのレコードを取得するためにチェックを追加する必要がある場合、MVCC設計ではクエリのパフォーマンスも低下します。トレードオフは、更新との競合について心配する必要がないことです。

于 2008-08-15T13:22:01.477 に答える
1

うーん、このサイトのように聞こえます...

データベース設計に関する限り、SVN のようなバージョン管理システムでは、実際に更新を行うことはなく、変更があったときに (バージョン番号を付けて) 挿入するだけで済みます。これは、MVCC、Multi-Value Concurrency Control と呼ばれます。ウィキは、これのもう 1 つの良い例です。

于 2008-08-14T20:57:36.573 に答える
1

これについてどう思いますか:

テーブルの問題
int id | 文字列名 | テキストの説明 | datetime created_at

テーブル problem_revisions
int リビジョン | 整数 ID | 文字列名 | テキストの説明 | datetime created_at
外部キー ID -> problems.id

更新の前に、リビジョン テーブルに追加の挿入を実行する必要があります。この追加の挿入は高速ですが、これはあなたが支払わなければならないものです

  1. 現在のバージョンへの効率的なアクセス - いつものように問題を選択
  2. 直感的でモデル化したい現実に近いスキーマ
  3. スキーマ内のテーブル間の結合は効率的です
  4. ビジネス トランザクションごとにリビジョン番号を使用すると、SVN がファイルに対して行うように、テーブル レコードに対してバージョン管理を行うことができます。
于 2008-10-18T08:55:54.107 に答える
0

あると思います

オプション4:ハイブリッド

共通のThing属性を単一継承テーブルに移動してから、custom_attributesテーブルを追加します。これにより、外部キーが単純になり、重複が減り、柔軟性が得られます。追加属性の型安全性の問題は解決されません。また、Thingが属性を持つには2つの方法があるため、少し複雑になります。

descriptionただし、その他の大きなフィールドがThingsテーブルに残っている場合でも、重複スペースの問題は解決されません。

table things
  int id | int type | string name | text description | datetime created_at | other common fields...
  foreign key type -> thing_types.id

table custom_attributes
  int id | int thing_id | string name | string value
  foreign key thing_id -> things.id
于 2008-08-15T14:19:17.320 に答える
0

モデルに関する一般的な質問に簡単に答えられるようなデータ構造を選択することをお勧めします。ほとんどの場合、あなたは現在のポジションに興味を持っている可能性が最も高いです。場合によっては、特定の問題や解決策の履歴を掘り下げたいことがあります。

現在の位置を表す問題、解決策、および関係のテーブルが必要です。problem_history、、solution_historyなどのテーブルもあります。VersionNumberこれらは問題の子テーブルになりますが、との余分な列も含まれますEffectiveDate。キーは ( ProblemId, VersionNumber) になります。

問題を更新すると、古い値がテーブルに書き込まれproblem_historyます。problem_historyしたがって、特定の日付で有効なレコードを選択できるため、特定時点のクエリが可能です。

以前にこれを行ったところで、UNION へのビューも作成しましたproblemproblem_historyこれは、さまざまなクエリで役立つ場合があるためです。

オプション 1 では、すべての履歴データが現在のデータと混ざり合っているため、現在の状況を照会することが困難になります。

オプション 3 は、単純なクエリであるべきものに対して多くの行にアクセスすることになるため、クエリのパフォーマンスが低下し、コーディングが困難になります。

于 2008-10-31T09:50:35.683 に答える