高性能のwikiスキーマ
-
12-09-2019 - |
質問
私はMS SQL Server 2005を使用しています。
wikiのようなシステムのための最高のスキーマは何ですか?ユーザーは、提出を改訂/編集し、システムがこれらの提出を追跡します。
ここで、私たちは、単純なウィキベースのシステムをやっているとしましょう。各リビジョンプラスビューおよび各リビジョンの最新の活動を追跡します。他の画面では、システムは、「最新の提出」をリストアップし、「人気の動画」、プラスタイトルで検索します。
私の現在のスキーマは、単一のテーブルを使用している(と私はその悪いを知っています)。私は「LatestActivity」でソートI「を最新の提出」を参照してくださいする必要がある場合、グループは「DocumentTitle」で、最初のNレコードを取ります。私はグループの多くは(特にnvarchar型にグループ分け)悪いニュースであると仮定します。名前のビュー、グループによる並べ替え、最初のNレコードを取る:ほとんどの私も同じことを行う閲覧リストについては。ほとんどの時間、私もやってます "WHERE DOCUMENTNAME LIKE '%のQUERY-HERE%'"。
私の現在のスキーマは「バージョン1」で、以下を参照してください: altテキストhttp://www.anaimi.com/junk/schemaquestion.png の
私は、これは受け入れられないと仮定します。だから私は、別の/より、パフォーマンスのデザインを思い付くしようとしています。どのようにバージョン2の音はあなたにいますか?バージョン2では、私は、数あるWikiHeadId上のグループ化の利点を得る - 。私は数がnvarchar型よりも優れている上でグループ化すると仮定しています。
または私はグループ化しないであろうバージョン3であり、極端な場合、しかし、等のコードでこれらの値をこのような値を複製するなど、いくつかの欠点を維持しています。
またはを、このようなシステムのためのより良い/既知のスキーマがあるのでしょうか?の
感謝します。
(ServerFaultのから移動 - 私は、ITの質問よりも、開発問題を考える)
解決
まず(と好奇心のうち)どのように現在のスキーマは、現在のバージョンが何であるかを示しているのでしょうか?あなただけの同じDocumentTitleを持つ複数の「WikiDocument」のエントリを持っていますか?
私はまた、あなたがバージョン・レベルで「LastActivity」を必要とする理由については明らかではありませんよ。私は「LastActivityは、」「バージョン」の概念をどのように適合するか表示されません - の最ものウィキでは、「バージョン」は、追記型です:あなたはバージョンを変更する場合は、あなたがしていますの新しいのバージョンを作成し、そのバージョンの最後の更新型の値の概念は無意味である - 。それは本当にただ「datecreated」の
本当に、あなたのデザインのための「自然」スキーマは#2です。個人的に、私は「それが痛いまでそれが動作するまで、その後、非正規化する正規化」古いDBの公理のファンのビットです。 #2は、よりよい設計(重複なしで、シンプルな)、クリーナーです、そしてあなたは、バージョン3への非正規化するために何の緊急の理由がない場合、私は気にしないでしょう。
結局、それがダウンし、これに来る:あなたは、パフォーマンス上の問題を観察してきたので、「よりパフォーマンス」のデザインを心配する、またはあなたが仮に<全角>のでされているはいくつかを持っているのでしょうか? #2が十分に機能してはならない本当の理由はありません。グループは、SQL Serverで必ずしも悪いニュースではない - 適切な被覆インデックスがクエリのためにあるかどうそれだけで使い、その後、グループ化された値を見つけるために、インデックス内の特定のレベルに移動することができますので、実際には、それは非常によく行うことができますインデックスの残りの列は、MIN / MAX /何に使用します。 NVARCHARによってグループ化、特に悪いわけではない - それは問題であることが観察されていない場合(非バイナリ)けれども、それについて心配しないでください照合それは少しトリッキーすることができます - しかし、バージョン2で、必要にあなたBY GROUPは右、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)
...
またはそれがないパフォーマンスのために、あなたの人生が容易になり、単にので便利非正規化であってもよい。何でも、
他のヒント
これはアウトを確認してください。
これは、に基づいているものをウィキペディア MediaWikiのの、のデータベーススキーマです。
これはかなりよく文書化見て、あなたのための興味深い読み取りだろう。
このページます。