14

我正在编写一个将成为 Intranet 应用程序的东西,其功能之一大致类似于内容投票 - 与 SO、Amazon 和许多其他网站所做的没有什么不同。

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

ContentID int
UserID int
VoteValue int

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

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

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

4

5 回答 5

11

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

(内容大小)>>(投票大小):其中“>>”表示“更大”。

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

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

http://highscalability.com/

于 2008-12-05T01:19:04.587 回答
7

就个人而言,只要您有良好的索引,您就会以正确的方式进行。根据您的使用情况,为了提高性能,您可能会尝试通过存储辅助计数信息来避免触及投票表,但总体而言,如果您必须跟踪 WHO 投票了某事,则需要按照您列出的方式进行。

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

于 2008-12-05T01:15:27.700 回答
4

如果您需要跟踪用户是否为某个特定项目投票,并且如果有不同的投票值(例如 1 星到 5 星),那么这将尽可能紧凑。

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

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

于 2008-12-05T01:19:52.433 回答
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 地址。)

于 2008-12-05T03:25:46.767 回答
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投票可能比在表中添加一行更昂贵。在这种情况下,每个 id + 分隔符 4 字节的 100 票是 500 字节的字符串。在您提议的变体中,100 票是 800 字节。

免责声明:我从来没有实现过这样的东西,这只是一个想法。

于 2013-06-26T08:41:18.270 回答