2008-12-05 52 views
13

我正在写什么是内联网应用程序,其中一个功能大致类似于内容投票 - 与SO,亚马逊和其他许多网站无异。在数据库中存储“选票”

假设每个可投票页面有一个唯一的ID,并且每个用户(他们认证)都有唯一的ID,最简单的方法似乎是有一个“票”表...

ContentID int 
UserID int 
VoteValue int 

但是这会为每票投票创建一行 - 包含数百万条内容和数以万计的用户,该表将会巨大巨大。这是做这件事的最好方法吗?我的意思是,如果一个int需要4个字节,每行需要12个字节。如果一百万条内容获得一百张选票,那么存储空间就是400MB +,是吗?似乎...很多:)。即使VoteValue是一个tinyint(这可能很好),只有1个字节,在表中仍然有几百兆字节。我的意思是sheesh。

有没有更聪明的方法?我应该将这张“投票”表格存储在单独的数据库中(忽略潜在的数据完整性问题),以便将它与存储和性能方面的“主要”数据分开吗?

(我认识到,在当今世界400MB不是一吨 - 但似乎像很多刚刚存储票,是啊)

回答

7

个人,只要你有好的指标到位,你是以正确的方式前进。根据您的使用情况和性能,您可能会尝试避免通过存储次要计数信息来达到投票表,但总体而言,如果您必须跟踪世卫组织投了票,您需要按照列出的方式进行。

我不会打扰移动到另一个数据库,如果你真的关心SQL Server中,你可以创建一个单独的文件组来保存它.....但最有可能没有必要。

11

嗯,是的,但你需要看看更大的图片。有一百万条CONTENT:

(内容大小)>>(票数的大小):其中“>>”的意思是“更大”。

如果你有一百万条内容,那么这可能是一个TB级的数据,因为票数是400MB。大处理权利?

我还要补充,如果你担心的可扩展性,看看这个博客:

http://highscalability.com/

4

如果您需要跟踪用户是否已经投票支持特定的项目,如果有不同投票的价值(例如1星到5星),那么它就像它得到的一样紧凑。不要忘记,为了达到合理的访问速度,您需要对数据进行索引(两个索引,可能 - 其中一个以ContentID作为主要列,另一个以userID作为主要列)。

您需要决定是否有理由不将表格与其他表格分开存储。这意味着取决于您使用的DBMS - 对于Informix,表将位于同一数据库中,但存储在不同的数据库空间中,并且您可能会将索引存储在另外两个不同的数据库空间中。

4

您可能还需要表格中内容作者的ID,以便更容易地检测投票滥用情况。 (是的,这大概是多余的信息。另一种是定期构建一个汇总表,看看谁在谁投票)

对于它的价值,在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的内容ID,IP是一个IP地址。)

0

我想说,你需要弄清楚如何使用这些投票,并首先为你的数据模型设计特定的查询。这不一定是SQL模型。如果你来自SQL世界,通过正式的MongoDB教程有助于澄清一开始的想法。

例如,如果您只需要存储和显示单个问题页面的投票,那么可能很方便将投票存储在问题的单个字符串字段中,看起来像id1:id2:id3:。假设所有ID的长度是相同的,也有一些有趣的特性:

  1. 计数所有选票的问题:

    len(issue.votes)/len(id)

  2. 查找我投在这个问题上

    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个每个id +分隔符4个字节的投票是500个字节的字符串。在你提出的变种中,100票是800字节。

声明:我从来没有实现过这样的事情,它只是一个想法。