Pregunta

Estoy usando MS SQL Server 2005.

¿Cuál es el mejor esquema para un sistema Wiki-como? donde los usuarios editar / revisar una presentación y el sistema realiza un seguimiento de estas presentaciones.

Digamos que estamos haciendo un sistema simple basado en wiki. Hará un seguimiento de cada revisión, más puntos de vista y la última actividad de cada revisión. En otras pantallas, el sistema mostrará una lista de "envíos recientes" y "Más vistos", además de buscar por título.

Mi esquema actual (y sé que es malo) es el uso de una sola tabla. Cuando necesito para ver los "envíos recientes" Me ordenar por "LatestActivity", el grupo de "DocumentTitle", a continuación, tomar primeros n registros. Asumo una gran cantidad de agrupación (especialmente agrupamiento en nvarchar) es una mala noticia. Para la inclusión de los más vistos también hago lo mismo: ordenar por puntos de vista, grupo por su nombre, tomar primeros n registros. La mayoría de las veces, yo también voy a hacer un "DONDE COMO DocumentName '% CONSULTA AQUÍ-%'".

Mi esquema actual es "Versión 1", ver más abajo: alt text http://www.anaimi.com/junk/schemaquestion.png

Asumo que esto no es aceptable. Así que estoy tratando de llegar a otro diseño / más-performante. ¿Cómo funciona la versión 2 de sonido para usted? En la versión de dos consigo la ventaja de agrupación en WikiHeadId que es un número -. Asumo que agrupa más de un número es mejor que nvarchar

O el caso extremo que es la versión 3, donde voy a hacer ninguna agrupación, pero tiene varias desventajas, tales como la duplicación de los valores, el mantenimiento de estos valores en el código, etc.

o ¿Hay un esquema mejor / más conocido para tales sistemas?

Gracias.

(desplazado desde ServerFault - Creo que es una cuestión de desarrollo más que una cuestión de TI)

¿Fue útil?

Solución

En primer lugar (y por curiosidad) ¿cómo el esquema actual indica cuál es la versión actual es? ¿Usted apenas tiene varias entradas de 'WikiDocument' con el mismo DocumentTitle?

Además, no tengo claro por qué necesita un 'LastActivity' a un nivel de versión. No veo cómo 'LastActivity' encaja con el concepto de 'Versión' - en más wikis, las 'versiones' son de una sola escritura: si modifica una versión, entonces usted está la creación de un nueva versión, por lo que el concepto de un valor-última actualización de la versión de tipo no tiene sentido -. No deja de ser 'DateCreated'

En realidad, el esquema 'natural' para su diseño es el # 2. En lo personal, estoy un poco de un fan de la vieja DB axioma 'normalizar hasta que duela, a continuación, desnormalizar hasta que funcione'. # 2 es un limpiador, un mejor diseño (simple, sin duplicación), y si usted no tiene ninguna razón urgente para desnormalizar a la versión 3, no me molestaría.

En última instancia, todo se reduce a esto: estás preocupando de diseño 'con más prestaciones' porque usted ha observado problemas de rendimiento, o porque hipotéticamente podría tener alguna? No hay ninguna razón real # 2 no debería funcionar bien. Agrupación no es necesariamente una mala noticia en SQL Server - de hecho, si hay un índice de cobertura apropiada para la consulta, se puede llevar a cabo muy bien, ya que sólo puede navegar a un nivel particular en el índice para encontrar los valores agrupados, a continuación, utilizar las columnas restantes del índice a utilizar para MIN / MAX / lo que sea. Agrupación por NVARCHAR no es particularmente malo - si no se observa que es un problema, no se preocupe de ello, aunque (no binarios) colaciones pueden hacer que sea un poco difícil - pero en la versión 2, donde es necesario GROUP BY puede hacerlo por WikiHeadId, ¿verdad?

Una cosa que puede hacer la vida más fácil, si lo hace una gran cantidad de operaciones de la versión actual (como supongo que lo haría), añadir una FK de la mesa de cabeza a la mesa de cuerpo, lo que indica la versión actual. Si desea ver los versiones actuales con el mayor número de hits, con # 2 Tal como está ahora podría ser:

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

o alternativamente

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

ambos de los cuales son repulsivo. Si el WikiHead mantiene un puntero a la versión actual, es sólo

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

o lo que sea, que puede ser una desnormalización útil sólo porque hace la vida más fácil, no para el rendimiento.

Otros consejos

este a cabo.

Es el esquema de base de datos para MediaWiki , lo que Wikipedia se basa en.

Se ve bastante bien documentado y sería una lectura interesante para usted.

A partir de este .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top