0

我正在构建具有投票能力的应用程序(+1/-1),并试图为此拥有简单快速的 mysql 表结构。到目前为止,我的想法很简单,并且是这样的:

tbl_votes存储特定对象的投票值:

CREATE TABLE IF NOT EXISTS `tbl_votes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `vote` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

tbl_votes_ips存储 IP<=>投票历史,因此某些 IP 只能投票一次:

CREATE TABLE IF NOT EXISTS `tbl_votes_ips` (
  `vote` int(11) NOT NULL,
  `ip` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

目的是在插入新值时减少 SQL 调用。目的是在高负载的网站上使用。此类功能的最佳实践是什么?

请分享你的经验。

PS我有为vote-ip对制作唯一密钥的想法,所以我不选择而只是处理mysql“非唯一值”错误:

ALTER TABLE `tbl_votes_ips` ADD UNIQUE (
`vote` ,
`ip`
);

但这不适用于用户更改它的选择的情况。所以无论如何我需要打额外的电话来搜索 IP 和投票。

4

3 回答 3

2

备选方案 A

需要用户注册和登录。

备选方案 B

  • 设置一个独特的cookie。如果它在以后的访问中出现,请使用它。
  • 连接浏览器用户代理 + IP 地址并创建一个哈希值。如果 cookie 不存在,则在以后的访问中使用该哈希值作为该用户是否投票的代理。它将有大约 85% 的可靠性。
  • 如果您愿意,您可以包含除用户代理 + IP 之外的更多因素,但这涉及更多。有关更多详细信息,请参阅Panopticlick

备选方案 C

使用Evercookie。如果您走这条路,请在您的隐私政策中非常清楚地表明您正在这样做。公司因使用但未披露这些技术的使用而被起诉(有些成功,有些不成功,但无论哪种方式都花费了他们的时间和金钱)。

限制

请记住,这些技术中的任何一种对某人来说都不是那么难解决。多个用户注册只是一个免费的电子邮件帐户。如果您回收有线电视盒,许多家庭互联网连接都会获得新的 IP。智能手机通过在街上行驶一英里左右来获得新的 IP。如果用户的系统上有多个浏览器,即使 Panopticlick 也会失败。

于 2013-03-11T17:44:01.750 回答
0

使用唯一的密钥,例如

PRIMARY KEY (vote, ip)

然后一个简单的

INSERT INTO tbl_votes_ips (vote, ip) VALUES ($vote, $ip) 
ON DUPLICATE KEY UPDATE SET vote=VALUES(vote)

这可以作为单个查询完成,mysql 将决定它应该是插入还是更新。

而且,正如 Eric J 上面提到的,对于任何共享一个公共代理/nat 网关的用户组,您的系统将会崩溃。并且也不会处理 IPv6 上的用户。虽然它还不是特别普遍,但它已经到了不能再忽视 IPv6 支持的地步了。

于 2013-03-11T17:25:39.433 回答
0

每个用户投票怎么样?让用户能够使用电子邮件进行注册,并确保您将确认电子邮件发送到他们的电子邮件,以便他们进行验证。然后你得到你的唯一标识符来禁止同一个用户对一个项目进行多次投票,无论他们从哪里登录。

如果您希望不允许一组用户对某个部分进行投票,那么您需要创建一个用户类并与 users 表相关联,以便 John 和 Smith 拥有相同的用户类并且只允许投票一次。

于 2013-03-11T17:33:52.840 回答