代码之家  ›  专栏  ›  技术社区  ›  Don Jones

在数据库中存储“投票”

  •  14
  • Don Jones  · 技术社区  · 17 年前

    我正在编写一个内联网应用程序,它的一个功能大致类似于内容投票——与SO、亚马逊和许多其他网站所做的相似。

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

    ContentID int
    UserID int
    VoteValue int
    

    但这会为每一票创建一行——有数百万条内容和数万名用户,这个表格将是巨大的。这是最好的方法吗?我的意思是,如果一个int需要4个字节,那么每行需要12个字节。如果一百万条内容获得一百张选票,那么存储空间将超过400MB,对吗?似乎。..就像很多:)。即使VoteValue是一个tinyint(这可能很好)并且只有1个字节,表中仍然有几百兆字节。我是说希什。

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

    (我确实意识到,在当今世界,400MB不是一吨——但仅仅存储选票似乎就很多了,是吗?)

    5 回复  |  直到 17 年前
        1
  •  7
  •   Mitchel Sellers    17 年前

    好吧,是的,但你需要着眼于大局。拥有一百万条内容:

    (内容大小)>>(选票数量):其中“>>”表示“大得多”

    如果你有一百万条内容,那么这可能是一TB的数据,而投票量是400MB。这有什么大不了的,对吧?

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

    http://highscalability.com/

        2
  •  11
  •   BobbyShaftoe    17 年前

    就个人而言,只要你有好的索引,你就会以正确的方式去做。根据您的使用情况,为了表现,您可能会尝试通过存储二次计票信息来避免进入投票表,但总体而言,如果您必须跟踪世界卫生组织的投票情况,您需要按照您列出的方式进行。

    我不会费心转移到另一个数据库,如果你真的关心SQL Server,你可以创建一个单独的文件组来保存它……但很可能不是必需的。

        3
  •  4
  •   Jonathan Leffler    17 年前

    如果你需要跟踪用户是否对特定项目进行了投票,并且投票值不同(例如1星到5星),那么这是最紧凑的。

    不要忘记,为了获得合理的访问速度,您需要对数据进行索引(可能有两个索引——一个以ContentID为前导列,一个以userID为前导栏)。

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

        4
  •  4
  •   ysth    17 年前

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

    不管怎样,perlmongs的投票表看起来是这样的:

     `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地址。)

        5
  •  0
  •   anatoly techtonik Tony    12 年前

    我想说,你需要弄清楚这些投票将如何使用,并首先为你的数据模型设计特定的查询。这不一定是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 投票可能比在表格中添加一行更昂贵。在这种情况下,每个id有4个字节的100个投票+分隔符是500个字节的字符串。在你提出的变体中,100个投票是800个字节。

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