在数据库中存储“投票”

时间:2008-12-05 01:12:36

标签: database vote

我正在编写一个内部网应用程序,它的一个功能大致类似于内容投票 - 与SO,亚马逊和许多其他网站不同。

假设每个可投票的内容都有一个唯一的ID,并且每个用户(他们都经过身份验证)都有一个唯一的ID,最简单的方法就是拥有一个“投票”表......

ContentID int
UserID int
VoteValue int

但是每次投票会创造一行 - 拥有数百万条内容和数万名用户,这张桌子将会非常巨大。这是最好的方法吗?我的意思是,如果一个int需要4个字节,每行需要12个字节。如果一百万条内容得到一百票,那就是400MB +的存储空间,是吗?似乎......很多:)。即使VoteValue是一个tinyint(可能很好)并且只有1个字节,表中仍然只有几百兆字节。我的意思是sheesh。

有更聪明的方法吗?我应该将这个“投票”表存储在一个单独的数据库中(忽略潜在的数据完整性问题),以便在存储和性能方面将其与“主”数据进行分区吗?

(我确实意识到,在今天的世界中,400MB并不是一吨 - 但看起来只是为了存储选票,是吗?)

5 个答案:

答案 0 :(得分:11)

嗯,是的,但你需要看一下大局。有一百万件内容:

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

如果您有一百万条内容,则可能是数TB的数据,其中投票数为400MB。大不了?

我还想补充一点,如果您担心可扩展性,请查看此博客:

http://highscalability.com/

答案 1 :(得分:7)

就个人而言,只要您拥有良好的指数,就会以正确的方式进行。根据您的使用情况,为了提高性能,您可以尝试通过存储辅助计数信息来避免点击投票表,但总体而言,如果您必须跟踪世界卫生组织投票的内容,则需要按照您列出的方式进行。

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

答案 2 :(得分:4)

如果您需要跟踪用户是否已投票选择某个特定项目,以及是否有不同的投票值(例如1星到5星),那么这就像它获得的那样紧凑。

不要忘记,对于合理的访问速度,您需要索引数据(可能是两个索引 - 一个以ContentID作为前导列,一个以userID作为前导列)。

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

答案 3 :(得分: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地址。)

答案 4 :(得分: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

  5. 此架构允许在这些特定情况下避免对读取进行昂贵的计算,但更新issue.votes投票可能比在表中添加行更昂贵。在这种情况下,每个id +分隔符有4个字节的100个投票是500字节的字符串。在您提议的变体中,100票是800字节。

    免责声明:我从未实施过这样的事情,这只是一个想法。