2008-12-05 3 views
13

Я пишу, что будет приложением для интрасети, и одна из его функций примерно аналогична голосованию по содержанию - в отличие от того, что делают SO, Amazon и многие другие сайты.Хранение «голосов» в базе данных

Предположим, что каждый votable часть контента имеет уникальный идентификатор, и каждый пользователь (они подлинности) имеет уникальный идентификатор, самый простой способ, казалось бы иметь «голосов» стол ...

ContentID int 
UserID int 
VoteValue int 

Но это создает одну строку за голос - с миллионами частей контента и десятками тысяч пользователей, эта таблица будет огромной огромной. Это лучший способ сделать это? Я имею в виду, если int принимает 4 байта, каждая строка принимает 12 байтов. Если миллион штук контента получит 100 голосов, то это 400 МБ + на складе, да? Кажется ... как много :). Даже если VoteValue является tinyint (что, вероятно, хорошо) и только 1 байт, это все еще пара сотен мегабайт в таблице. Я имею в виду.

Есть ли более умный способ? Должен ли я хранить эту таблицу «голосов» в отдельной базе данных (игнорируя потенциальные проблемы с целостностью данных), чтобы разделить ее на «основные» данные с точки зрения хранения и производительности?

(я понимаю, что в современном мире 400MB не тонна - но это, кажется, как много раз, чтобы сохранить голоса, да)

ответ

7

Лично до тех пор, пока у вас есть хорошие показатели в месте, вы идя по правильному пути. В зависимости от вашего использования, для производительности вы можете попытаться избежать попадания в таблицу голосов, сохранив информацию вторичного счета, но в целом, если вы должны отслеживать, что ВОЗ проголосовала за что-то, вам нужно сделать это так, как вы указали.

Я бы не стал переезжать в другую базу данных, если вы действительно заинтересованы в SQL Server, вы можете создать отдельную файловую группу, чтобы ее удержать ..... но, скорее всего, не нужно.

11

Ну, да, но вам нужно посмотреть на картинку большего размера. С миллионом частей СОДЕРЖАНИЕ:

(Размер содержания) >> (Размер голосов): где «>>» означает «намного больше».

Если у вас есть миллион частей контента, то это может быть терабайт данных, где в качестве голосов 400 МБ. Большое дело?

Я хотел бы также добавить, если вы беспокоитесь о масштабируемости, проверить этот блог:

http://highscalability.com/

4

Если вам необходимо отслеживать ли пользователь проголосовал за определенный элемент, и если есть разные значения голосов (например, от 1 звезды до 5 звезд), то это примерно так же компактно, как и получается.

Не забывайте, что для разумных скоростей доступа вам необходимо индексировать данные (два индекса, возможно, один с ContentID в качестве ведущего столбца, один с идентификатором пользователя в качестве ведущего столбца).

Вам нужно будет решить, есть ли причина не хранить таблицу отдельно от других таблиц. Что это означает, зависит от используемой СУБД - с помощью Informix таблица будет находиться в одной и той же базе данных, но хранится в другом dbspace, и вы можете иметь индексы, хранящиеся в двух других разных доменах.

4

Возможно, вам также понадобится идентификатор автора содержимого в таблице, для более простого обнаружения нарушений в голосовании. (Да, это, по-видимому, избыточная информация.Альтернатива регулярно строит сводную таблицу, чтобы увидеть, кто голосует на кого)

Для чего это стоит, таблица perlmonks голоса выглядит следующим образом:.

`vote_id` int(11) NOT NULL default '0', 
`voter_user` int(11) NOT NULL default '0', 
`voted_user` int(11) default NULL, 
`weight` int(11) NOT NULL default '0', 
`votetime` datetime NOT NULL default '0000-00-00 00:00:00', 
`ip` varchar(16) default NULL, 
PRIMARY KEY (`vote_id`,`voter_user`), 
KEY `voter_user_idx` (`voter_user`,`votetime`), 
KEY `voted_user_idx` (`voted_user`,`votetime`) 

(vote_id это идентификатор контента IP является IP-адрес.)

0

Я бы сказал, что вам нужно выяснить, как эти голоса будут использоваться и спроектировать конкретные запросы для вашей модели данных. Это не обязательно модель SQL. Если вы приехали из мира SQL, прохождение через официальное руководство MongoDB помогает очистить ум для начала.

Например, если вам нужно хранить и отображать голоса только на одной странице проблемы, может быть удобно хранить голоса в одном поле строки проблемы, которая будет выглядеть как id1:id2:id3:. Предполагая, что все идентификаторы имеют одинаковую длину, есть некоторые интересные свойства:

  1. сосчитать все голоса за вопрос:

    len(issue.votes)/len(id)

  2. Find я голосовал по вопросу

    myid in issue.votes

  3. На все проблемы, по которым вы голосовали:

    select issue.id from issues where issue.votes contains(myid)

  4. Найти наиболее голосовала выпуски

    select issue.id from issues order by len(issue.votes) desc limit 10

Эта архитектура позволяет избежать дорогостоящих вычислений на чтения в этих конкретных случаях, но обновление issue.votes на голосование может быть более дорогим, чем добавление строки в таблицу. В этом случае 100 голосов с 4 байтами на разделитель id + составляют 500 байтов. В предложенном вами варианте 100 голосов - 800 байт.

Отказ от ответственности: Я никогда не реализовывал ничего подобного, это всего лишь идея.

Смежные вопросы