2

私は、人々が記事を作成/編集できる基本的な CRUD Web アプリを持っています。すべての編集のリビジョン履歴を保持する機能を追加したいと考えています。現在、次のような Articles テーブルがあります。

Article(id, title, content, author_id, category_id, format)

リビジョン履歴のサポートを追加するために現在のスキーマを変更するための 2 つのオプションを検討しました。基本的な考え方は、記事のすべての編集がリビジョン テーブルにレコードとして保存されるというものです。したがって、Articles and Revisions は 1 対多の関係です。

1 番目のオプション (正規化): 記事のメタデータ用に 1 つのテーブル、リビジョン用に 1 つのテーブル。重複データは保存されません。

Article(id, title, category_id)
Revision(id, content, author_id, format)

2 番目のオプション (非正規化): 2 つのテーブルはオプション 1 に似ていますが、列が重複しています。

Article(id, title, content, author_id, category_id, format)
Revision(id, article_id, content, author_id, format)

2番目のオプションを使用することを考えています。これにより、コーディングがはるかに簡単になります(複雑さが減り、コードの行が少なくなります)。「アカデミック」でも「純粋」でもないことは承知していますが、私の個人的な感覚では、追加の結合を行う必要があると、コードのメンテナンスが損なわれるということです。また、多くの結合を行う必要がないため、パフォーマンスが向上するはずです。

これは、このタスクを実行するための適切な方法ですか? おそらく、私が見落としている予期しない、または長期的な結果はありますか?

4

2 に答える 2

7

データを気にする場合は、「非正規化」の場合にコードが少なくなることはありません。 の最新の行が Revisionのコピーと常に一致するようにする必要がありますArticle。これは、並行環境では実際には簡単なことではありません。ロックは非常に慎重に行う必要があります。

(同じコピーを含めないことを選択Revisionした場合Article、これはさらに悪いことですRevision。主キーを適用するために DBMS に頼ることができなくなります!)

十分に強力な DBMS があれば、ケーキを食べて食べることもできます。たとえば、Oracle マテリアライズド ビューは、実際のデータ モデルを非正規化する必要なく、データを「事前結合」できます。

そのような DBMS がない場合でも、現実的な量のデータでパフォーマンスを測定した後にのみ、非正規化を検討してください。はい、JOINS は高価になる可能性がありますが、特定の状況では高すぎますか? 測定値だけがわかります。


ところで、次のような識別関係/自然キーの使用を検討してください。

ここに画像の説明を入力

特定のrevision_no記事の下にリビジョンを追加すると、 は単調に増加します。

PKの下にある B-Tree 構造Revisionにより、特定の記事の最新の (または任意の!) リビジョンを非常に効率的に見つけることができます。質問に表示されていない代替キーがない限り、(Oracle の下で) and をクラスターRevision化し、クラスタリング インデックスのリーディング エッジを圧縮することもできるため、繰り返しによるスペースのオーバーヘッドarticle_idは無効になります。

于 2012-04-11T19:54:31.680 に答える
5

パフォーマンスの議論はナンセンスです - あなたはより少ないJOINs を行っていますが、RDBMS は s 用に最適化されていJOINます。

ただし、必要以上に多くのデータをサーバーから引き出す可能性があり、これを最適化して取り除くことはできませ

また、一貫性の問題が発生する可能性もあります。異なるテーブルで同じアイテムのデータを複製すると、不整合が生じる可能性があります。リビジョン レコードと記事レコードのformatまたはの値が異なる場合はどうなるauthorでしょうか。どちらが正しいかどうやってわかりますか? contentinArticlesがどのリビジョンとも一致しない場合はどうなりますか?

これを正規化する必要があります。CurrentRevisionテーブルにフィールドを追加Articlesして、現在のバージョンにリンクします。2 つをリンクするArticleIDには、Revisionsテーブルに が必要です。

于 2012-04-11T19:14:30.950 に答える