0

MS SQL Server 2005 を使用しています。

Wiki のようなシステムに最適なスキーマは何ですか? ユーザーが提出物を編集/修正し、システムがこれらの提出物を追跡する場所。

単純な wiki ベースのシステムを実行しているとしましょう。各リビジョンに加えて、各リビジョンのビューと最新のアクティビティを追跡します。他の画面では、システムは「最新の提出物」と「最も閲覧されたもの」を一覧表示し、さらにタイトルで検索します。

私の現在のスキーマ (そして私はそれが悪いことを知っています) は単一のテーブルを使用しています。「最新の提出物」を確認する必要がある場合は、「LatestActivity」で並べ替え、「DocumentTitle」でグループ化し、最初の N レコードを取得します。多くのグループ化 (特に nvarchar でのグループ化) は悪いニュースだと思います。最も閲覧されたものをリストするために、私も同じことを行います: ビューで並べ替え、名前でグループ化し、最初の N レコードを取得します。ほとんどの場合、「WHERE DocumentName LIKE '%QUERY-HERE%'」も実行します。

私の現在のスキーマは「バージョン 1」です。以下を参照してください: 代替テキスト http://www.anaimi.com/junk/schemaquestion.png

これは受け入れられないと思います。だから私は別の/よりパフォーマンスの高いデザインを考え出そうとしています. バージョン 2 はどのように聞こえますか? バージョン 2 では、数値である WikiHeadId でグループ化する利点があります。数値でグループ化する方が nvarchar よりも優れていると想定しています。

または、グループ化を行わないバージョン 3 の極端なケースですが、値の重複、コード内でのこれらの値の維持など、いくつかの欠点があります。

または、そのようなシステムのためのより良い/既知のスキーマはありますか?

ありがとう。

(ServerFault から移動 - IT の問題というよりは開発の問題だと思います)

4

2 に答える 2

2

まず (そして好奇心から) 現在のスキーマは現在のバージョンが何であるかをどのように示していますか? 同じ DocumentTitle を持つ「WikiDocument」エントリが複数ありますか?

バージョンレベルで「LastActivity」が必要な理由についても明確ではありません。「LastActivity」が「バージョン」の概念にどのように適合するかわかりません。ほとんどのウィキでは、「バージョン」は一度だけ書き込みます。バージョンを変更すると、新しいバージョンが作成されるため、バージョンの最後に更新された型の値の概念は無意味です-それは実際には単に「datecreated」です。

本当に、あなたのデザインの「自然な」スキーマは #2 です。個人的には、古い DB の公理「問題が発生するまで正規化し、機能するまで非正規化する」のファンです。#2は、よりクリーンで優れた設計(単純で重複がない)であり、バージョン3に非正規化する緊急の理由がない場合は、気にしません.

最終的には、次のようになります。「よりパフォーマンスの高い」設計について心配しているのは、パフォーマンスの問題を観察したからですか、それとも仮説的に問題がある可能性があるからですか? #2 のパフォーマンスが良くないという本当の理由はありません。グループ化は、SQL Server では必ずしも悪いニュースではありません。実際、クエリに適切なカバー インデックスがあれば、インデックス内の特定のレベルに移動してグループ化された値を見つけてから使用できるため、非常にうまく機能します。使用するインデックスの残りの列を MIN/MAX/何でも。NVARCHAR によるグループ化は特に悪いことではありません。問題が見られない場合でも、心配する必要はありませんが、(非バイナリ) 照合は少し複雑になる可能性がありますが、バージョン 2 では、 GROUP BY は WikiHeadId でできますよね?

現在のバージョンで多くの操作を行う場合 (おそらくそうすると思います)、現在のバージョンを示す FK をヘッド テーブルからボディ テーブルに追加することで、作業が楽になるかもしれません。ヒット数が最も多い現在のバージョンを表示したい場合は、現在の #2 で次のようになります。

SELECT TOP ...
FROM WikiHead
INNER JOIN 
  (SELECT WikiHeadId, MAX(WikiBodyVersion) /* or LastUpdated? */ AS Latest 
   FROM WikiBody GROUP BY WikiHeadId) AS LatestVersions
INNER JOIN WikiBody ON 
  (Latest.WikiHeadId = WikiBody.WikiHeadId)
  AND (WikiBody.WikiBodyVersion = LatestVersions.Latest)
ORDER BY 
  Views DESC

または代わりに

...
INNER JOIN WikiBody ON 
  (WikiHead.WikiHeadId = WikiBody.WikiHeadId)
  AND (WikiBody.WikiBodyVersion = 
    (SELECT MAX(WikiBodyVersion) FROM WikiBody WHERE WikiBody.WikiHeadId = WikiHead.WikiHeadId)
...

どちらも厄介です。WikiHead が現在のバージョンへのポインターを保持している場合、それは単に

...    
INNER JOIN WikiBody ON 
  (WikiHead.WikiHeadId = WikiBody.WikiHeadId)
  AND (WikiHead.Latest = WikiBody.WikiBodyVersion)
...

パフォーマンスのためではなく、あなたの人生を楽にするという理由だけで、これは有用な非正規化かもしれません。

于 2009-07-15T00:25:47.127 に答える
0

これをチェックしてください。

これは、ウィキペディアが基づいている mediawikiのデータベース スキーマです。

それはかなりよく文書化されているようで、あなたにとって興味深い読み物になるでしょう.

このページから.

于 2009-07-13T15:57:15.897 に答える