Высокопроизводительная вики-схема - PullRequest
0 голосов
/ 11 июля 2009

Я использую MS SQL Server 2005.

Какая лучшая схема для Wiki-подобной системы? где пользователи редактируют / редактируют представление, и система отслеживает эти представления.

Допустим, мы делаем простую вики-систему. Будет отслеживать каждую ревизию плюс просмотры и последние действия каждой ревизии. На других экранах система отобразит «Последние поступления» и «Самые просматриваемые», а также поиск по названию.

Моя текущая схема (и я знаю, что она плохая) использует одну таблицу. Когда мне нужно увидеть «Последние материалы», я сортирую по «LatestActivity», группирую по «DocumentTitle», затем беру первые N записей. Я предполагаю, что группировка (особенно группировка по nvarchar) - это плохие новости. Для вывода списка самых просматриваемых я также делаю то же самое: сортировка по просмотрам, группировка по имени, первые N записей. В большинстве случаев я также буду делать "ГДЕ DocumentName LIKE '% QUERY-HERE%'".

Моя текущая схема "Версия 1", см. Ниже: альтернативный текст http://www.anaimi.com/junk/schemaquestion.png

Полагаю, это неприемлемо. Поэтому я пытаюсь придумать другой / более производительный дизайн. Как звучит версия 2 для вас? Во второй версии я получаю преимущество группирования по WikiHeadId, который является числом - я предполагаю, что группировка по числу лучше, чем nvarchar.

Или крайний случай - версия 3, где я не буду группировать, но имеет несколько недостатков, таких как дублирование значений, сохранение этих значений в коде и т. Д.

Или существует ли лучшая / известная схема для таких систем?

Спасибо.

(перенесено из ServerFault - я думаю, что это вопрос развития больше, чем вопрос ИТ)

Ответы [ 2 ]

2 голосов
/ 15 июля 2009

Во-первых (и из любопытства), как текущая схема показывает текущую версию? У вас есть только несколько записей WikiDocument с одним и тем же названием документа?

Мне также непонятно, зачем вам нужна «LastActivity» на уровне версии. Я не понимаю, как «LastActivity» соответствует понятию «версия» - в большинстве вики «версии» записываются один раз: если вы изменяете версию, то вы создаете новая версия, так что концепция последнего обновленного значения типа в версии не имеет смысла - на самом деле это просто «дата создания».

Действительно, «естественная» схема для вашего дизайна - №2. Лично я немного поклонник старой аксиомы БД: «нормализуй, пока не болит, потом денормализуй, пока не заработает». № 2 - более чистый и приятный дизайн (простой, без дублирования), и если у вас нет срочных причин для денормализации до версии 3, я бы не стал беспокоиться.

В конечном счете, все сводится к следующему: вас беспокоит «более производительный» дизайн, потому что вы наблюдали проблемы с производительностью, или потому что у вас гипотетически может их есть? Нет никакой реальной причины, по которой № 2 не должен работать хорошо. Группировка не обязательно является плохой новостью в SQL Server - фактически, если для запроса имеется соответствующий индекс покрытия, он может работать очень хорошо, поскольку может просто перейти к определенному уровню в индексе, чтобы найти сгруппированные значения, а затем использовать остальные столбцы индекса использовать в MIN / MAX / что угодно. Группировка по NVARCHAR не особенно плоха - если это не является проблемой, не беспокойтесь об этом, хотя (недвоичные) сопоставления могут сделать это немного сложнее - но в версии 2, где вам нужно GROUP BY вы можете сделать это с помощью WikiHeadId, верно?

Одна вещь, которая может облегчить жизнь, если вы выполняете много операций с текущей версией (как я полагаю, вы сделаете это), - добавить FK обратно из таблицы head в таблицу body, указывая текущую версию. Если вы хотите просмотреть текущие версии с наибольшим количеством совпадений, с номером 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)
...

или что-то еще, что может быть полезной денормализацией только потому, что она делает вашу жизнь проще, а не для производительности.

0 голосов
/ 13 июля 2009

Проверьте это .

Это схема базы данных для mediawiki , на которой основана википедия.

Это выглядит довольно хорошо задокументировано и будет интересным для вас.

С этой страницы .

...