Pergunta

Estou usando o MS SQL Server 2005.

O que é o melhor esquema para um sistema de Wiki-like? onde os usuários editar / revisar a submissão e o sistema mantém o controle dessas apresentações.

Vamos dizer que nós estamos fazendo um sistema baseado em wiki simples. Vai manter o controle de cada revisão mais vistas e mais recente atividade de cada revisão. Em outras telas, o sistema irá listar "envios recentes" e "Mais Vista", além de pesquisar por título.

Meu esquema atual (e eu sei que é ruim) está usando uma única tabela. Quando eu preciso ver "Últimas Apresentações" Eu meio por "LatestActivity", grupo por "DocumentTitle", em seguida, tomar registros primeiros n. Eu presumo que um monte de agrupamento (especialmente agrupamento em nvarchar) é uma má notícia. Para listar os mais vistos Eu também fazer o mesmo: ordenar por pontos de vista, grupo por nome, tomar registros primeiros n. Na maioria das vezes, eu também estará fazendo um "ONDE DocumentName LIKE '% query-HERE%'".

Meu esquema atual é "Versão 1", veja abaixo: texto alt http://www.anaimi.com/junk/schemaquestion.png

Eu assumo isto não é aceitável. Então eu estou tentando chegar a um outro projeto / mais-performance. Como é que a versão 2 de som para você? Na versão dois eu obter a vantagem de agrupar em WikiHeadId que é um número -. Estou assumindo agrupamento ao longo de um número é melhor do que nvarchar

Ou o caso extremo que é a versão 3, onde vou fazer nenhum agrupamento, mas tem várias desvantagens, tais como a duplicação de valores, mantendo esses valores no código, etc.

ou há uma melhor / esquema conhecido por tais sistemas?

Graças.

(passou de ServerFault - eu acho que é uma questão de desenvolvimento mais do que uma questão de TI)

Foi útil?

Solução

Em primeiro lugar (e por curiosidade) como é que o esquema atual indicam que a versão atual é? Você apenas tem várias entradas de 'WikiDocument' com a mesma DocumentTitle?

Eu também não sou clara sobre por que você precisa de um 'LastActivity' em um nível de versão. Eu não ver como se encaixa 'LastActivity' com o conceito de uma 'versão' - em mais wikis, as 'versões' são write-once: se você modificar uma versão, então você está a criação de um new versão, então o conceito de uma última atualizado valor de tipo sobre a versão é sem sentido -. ele é realmente apenas 'DateCreated'

Na verdade, o esquema 'natural' para seu projeto é # 2. Pessoalmente, eu sou um pouco de um fã da DB velho axioma 'normalizar até doer, então denormalize até que ele funciona'. # 2 é um produto de limpeza, design agradável (simples, sem duplicação), e se você não tem nenhuma razão urgente de desnormalizar à versão 3, eu não me incomodaria.

Em última análise, tudo se resume a isto: você está se preocupando com projeto 'mais performance', porque você tem problemas de desempenho observados, ou porque você hipoteticamente pode ter algum? Não há nenhuma razão real # 2 não deve executar bem. O agrupamento não é necessariamente uma má notícia no SQL Server - na verdade, se há um apropriado cobrindo índice para a consulta, ele pode executar muito bem porque ele pode simplesmente navegar para um determinado nível no índice para encontrar os valores agrupados, então uso as colunas restantes do índice de usar a MIN / MAX / qualquer que seja. O agrupamento por NVARCHAR não é particularmente ruim - se não for observada a ser um problema, não se preocupe com isso, embora (não-binários) agrupamentos pode torná-lo um pouco complicado - mas na versão 2, onde você precisa GROUP BY você pode fazê-lo por WikiHeadId, certo?

Uma coisa que pode tornar a vida mais fácil, se você fizer um monte de operações na versão atual (como eu suponho que você faria), para adicionar uma volta FK da tabela de cabeça para a mesa de corpo, indicando a versão atual. Se você quiser ver os versões atuais com o maior número de hits, com # 2 tal como está agora, pode 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

ou alternativamente

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

sendo que ambos são icky. Se o WikiHead mantém um ponteiro para a versão atual, é apenas

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

ou qualquer outra coisa, o que pode ser uma desnormalização útil apenas porque facilita a sua vida, não para o desempenho.

Outras dicas

Verifique este fora.

É o esquema de banco de dados para mediawiki , o que wikipedia é baseado.

Parece muito bem documentado e seria uma leitura interessante para você.

A partir deste página .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top