2009-07-10 6 views
0

Ich benutze MS SQL Server 2005.Hochleistungs-Wiki-Schema

Was ist das beste Schema für ein Wiki-ähnliches System? Benutzer bearbeiten/überarbeiten eine Einreichung und das System verfolgt diese Eingaben.

Sagen wir, wir machen ein einfaches Wiki-basiertes System. Verfolgt jede Revision sowie die Ansichten und die letzten Aktivitäten jeder Revision. In anderen Bildschirmen wird das System "Letzte Eingaben" und "Meist gesehen" sowie eine Suche nach Titel anzeigen.

Mein aktuelles Schema (und ich weiß, es ist schlecht) verwendet eine einzige Tabelle. Wenn ich die "neusten Einreichungen" sehen muss, sortiere ich nach "LatestActivity", gruppiere nach "DocumentTitle" und nimm dann die ersten N Datensätze. Ich nehme an, dass viele Gruppierungen (vor allem die Gruppierung auf nvarchar) schlechte Nachrichten sind. Für die Auflistung der am meisten angesehenen mache ich auch das gleiche: nach Ansichten sortieren, nach Namen gruppieren, erste N Datensätze aufnehmen. Meistens mache ich auch einen "WHERE DocumentName LIKE '% QUERY-HERE%'".

Mein aktuelles Schema ist "Version 1", siehe unten: alt text http://www.anaimi.com/junk/schemaquestion.png

Ich nehme an, dies nicht akzeptabel ist. Also versuche ich mir ein anderes/performanteres Design zu überlegen. Wie klingt Version 2 für Sie? In Version zwei habe ich den Vorteil, auf WikiHeadId zu gruppieren, was eine Zahl ist - ich gehe davon aus, dass die Gruppierung über eine Nummer besser ist als nvarchar.

Oder der Extremfall der Version 3 ist, wo ich keine Gruppierung tun, aber einige Nachteile, wie Werte dupliziert hat, diese Werte im Code beibehalten usw.

Oder gibt es ein besseres/bekannt Schema für solche Systeme?

Danke.

(von ServerFault bewegt - ich denke, es ist eine Entwicklung Frage mehr als eine IT-Frage)

Antwort

2

Erstens (und aus Neugier), wie zeigt das aktuelle Schema, was die aktuelle Version ist? Haben Sie mehrere WikiDocument-Einträge mit demselben DocumentTitle?

Ich bin auch nicht klar, warum Sie eine 'LastActivity' auf Versionsebene benötigen. Ich sehe nicht, wie "LastActivity" mit dem Konzept einer "Version" zusammenpasst - in am meisten Wikis, die 'Versionen' sind einmal beschreibbar: Wenn Sie eine Version ändern, dann erstellen Sie eine neue Version, so dass das Konzept eines letzten aktualisierten Typ-Wertes auf der Version bedeutungslos ist - es ist wirklich nur 'datecreated'.

Wirklich ist das "natürliche" Schema für Ihr Design # 2. Persönlich bin ich ein bisschen ein Fan des alten DB-Axioms, normalisieren, bis es weh tut, dann denormalisieren, bis es funktioniert. # 2 ist ein saubereres, netteres Design (einfach, ohne Duplizierung), und wenn Sie keinen dringenden Grund haben, Version 3 zu denormalisieren, würde ich mich nicht darum kümmern.

Letztendlich kommt es darauf an: Sorgen Sie sich um "leistungsfähigeres" Design, weil Sie Leistungsprobleme beobachtet haben, oder weil Sie möglicherweise haben könnten? Es gibt keinen wirklichen Grund, warum # 2 nicht gut funktionieren sollte. Gruppierung ist nicht unbedingt eine schlechte Nachricht in SQL Server - wenn ein passender Deckungsindex für die Abfrage vorhanden ist, kann sie sehr gut funktionieren, da sie einfach zu einer bestimmten Ebene im Index navigieren kann, um die gruppierten Werte zu finden, und dann verwenden die restlichen Spalten des Index, die zu MIN/MAX/was auch immer verwendet werden sollen. Die Gruppierung durch NVARCHAR ist nicht besonders schlecht - wenn es kein Problem ist, sollten Sie sich nicht darum kümmern, obwohl (nicht-binäre) Sortierungen es ein wenig schwierig machen können - aber in Version 2, wo Sie es brauchen GROUP BY Sie können es von WikiHeadId tun, richtig?

Eine Sache, die das Leben leichter machen kann, wenn Sie viele Operationen mit der aktuellen Version durchführen (wie ich annehmen würde), ein FK zurück von der Kopftabelle zur Körpertabelle hinzuzufügen und die aktuelle Version anzuzeigen. Wenn Sie die aktuellen Versionen mit der höchsten Anzahl von Treffern, die mit # 2 sehen möchten, wie es steht jetzt könnte es sein:

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 

oder alternativ

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

von denen beide eklig sind. Wenn der WikiHead einen Zeiger auf die aktuelle Version hält, es ist nur

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

oder was auch immer, die nur ein nützliches Denormalisierung sein kann, weil es das Leben einfacher macht, nicht für die Leistung.

+0

Danke. In der Version 1 habe ich das Attribut "Version" vergessen. Aber ich habe es trotzdem implementiert, um Version 2 zu verwenden. – ANaimi

0

prüfen this aus.

Es ist das Datenbankschema für mediawiki, auf dem Wikipedia basiert.

Es sieht ziemlich gut dokumentiert und wäre eine interessante Lektüre für Sie.

Von diesem page.