Question

J'utilise MS SQL Server 2005.

Quel est le meilleur schéma pour un système semblable Wiki? où les utilisateurs modifier / réviser une soumission et le système garde la trace de ces arguments.

Disons que nous faisons un système de wiki simple. Gardera une trace de chaque révision ainsi que des vues et dernière activité de chaque révision. Dans d'autres écrans, le système liste « Dernières soumissions » et « Les plus populaires », plus une recherche par titre.

Mon schéma actuel (et je sais que sa mauvaise) utilise une seule table. Quand je dois voir les « Dernières soumissions » Je Tri « LatestActivity », groupe par « DocumentTitle », puis prendre n premiers enregistrements. Je suppose que beaucoup de regroupement (regroupement en particulier sur nvarchar) est de mauvaises nouvelles. Pour la liste les plus regardées Je fais aussi le même: trier par vues, groupe par nom, prendre les premiers enregistrements de N. La plupart du temps, je vais aussi faire un « OU DocumentName LIKE '% QUERY-ICI% ».

Mon schéma actuel est "Version 1", voir ci-dessous: texte alt http://www.anaimi.com/junk/schemaquestion.png

Je suppose que ce n'est pas acceptable. Donc, je suis en train de trouver un autre / design plus-performant. Comment fonctionne la version 2 de son pour vous? Dans la version deux, je reçois l'avantage de regrouper sur WikiHeadId qui est un nombre -. Je suppose le regroupement sur un certain nombre est mieux que nvarchar

Ou le cas extrême qui est la version 3, où je ferai pas de regroupement, mais présente plusieurs inconvénients tels que la duplication des valeurs, le maintien de ces valeurs dans le code, etc.

ou est-il une meilleure / schéma connu pour de tels systèmes?

Merci.

(déplacé de ServerFault - je pense que sa question de développement plus qu'une question IT)

Était-ce utile?

La solution

Tout d'abord (et par curiosité) comment le schéma actuel indique que la version actuelle est? Avez-vous juste plusieurs entrées « WikiDocument » avec le même DocumentTitle?

Je suis pas non plus clairement pourquoi vous avez besoin d'un « LastActivity » à un niveau de version. Je ne vois pas comment « LastActivity » correspond au concept d'une « version » - dans plus wikis, les « versions » sont en écriture une fois: si vous modifiez une version, vous êtes la création d'un nouveau Version, de sorte que le concept d'une valeur de type dernière mise à jour sur la version est dénuée de sens -. il est vraiment juste « dateCreated »

En fait, le schéma « naturel » pour votre conception est # 2. Personnellement, je suis un peu fan de l'ancien axiome DB 'normaliser jusqu'à ce que ça fait mal, dénormaliser puis jusqu'à ce qu'il fonctionne. # 2 est un produit de nettoyage, plus belle conception (simple, sans double emploi), et si vous avez aucune raison urgente de dénormaliser à la version 3, je ne dérange pas.

En fin de compte, il se résume à ceci: vous soucier de la conception « plus performant » parce que vous avez observé des problèmes de performance, ou parce que vous hypothétiquement peut avoir? Il n'y a pas vraiment de raison # 2 devrait ne pas fonctionner correctement. Le regroupement est pas nécessairement de mauvaises nouvelles dans SQL Server - en fait, s'il y a un indice de couverture approprié pour la requête, il peut effectuer très bien car il peut simplement accéder à un niveau particulier dans l'index pour trouver les valeurs regroupées, puis utilisez les colonnes restantes de l'indice à utiliser pour MIN / MAX / whatever. Regroupement par NVARCHAR est pas particulièrement mauvais - si ce n'est pas observé un problème, ne vous inquiétez pas à ce sujet, bien que (non binaires) rendre réalisables peuvent un peu délicat - mais dans la version 2, où vous devez GROUP BY vous pouvez le faire par WikiHeadId, non?

Une chose qui peut rendre la vie plus facile, si vous faites beaucoup d'opérations sur la version actuelle (comme je suppose que vous), d'ajouter un FK retour de la table de la tête à la table du corps, ce qui indique la version actuelle. Si vous voulez voir les versions actuelles avec le plus grand nombre de hits, avec # 2 dans son état actuel, il pourrait être:

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

ou bien

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

toutes deux sont dégueulasses. Si le WikiHead garde un pointeur vers la version actuelle, il est juste

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

ou autre, qui peut être un utile dénormalisation juste parce qu'il rend votre vie plus facile, et non pas pour la performance.

Autres conseils

Vérifier cette sur.

Il est le schéma de base de données pour mediawiki, ce wikipedia est basé sur.

Il semble assez bien documenté et serait une lecture intéressante pour vous.

A partir de cette de .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top