我有一个弹出式旋转器,每天计算unic用户的ip(同一日期用户不允许重复ip)
$userip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
$date = date('Y-m-d');
$result = mysql_query("SELECT `ip` FROM `popupip` where ip = '$userip' AND userid = $secid AND date='$date'");
$num = mysql_num_rows($result);
if ($num > 0) {
// **it is duplicate Do not insert it in popupip table**
}else{
// **it is not duplicate ip insert it in popupip table**
}
上面的代码就是一个例子。我知道完整的代码。
但是当我查看我的phpmyadmin popupip
表时,会有一些重复的ip用户(同一天用户的IP地址完全相同)
怎么可能?
额外信息:
在popupip
userid
中是int(11),date
是“日期类型,如2014-05-30”,ip
是varchar。
此页面可以通过弹出页面“尽可能快地同时打开”。在用户同时快速打开页面和重复创建ip之间是否存在关联? MySQL中有错误吗? (也许是个大错!!!!)
答案 0 :(得分:2)
是的,有可能。这是一个竞争条件的经典案例。
快速解释:
有2个请求同时通过第一次检查,获取$num == 0
并且都插入新行。
要消除它,您需要创建涵盖UNIQUE
列
(user_id, ip, date)
约束
长篇解释:
答案 1 :(得分:2)
如果多个请求同时来自同一个ip,则有可能其中一些请求在执行insert查询之前执行select查询(导致多个插入具有相同的ip和日期)
解决方法是使用ip,user_id和date创建一个UNIQUE索引(您可以通过运行以下查询在phpMyAdmin中轻松完成此操作):
ALTER TABLE `popupip` ADD UNIQUE (`ip`, `user_id`, `date`);
之后,您可以优化代码,只需执行" INSERT IGNORE"只有在表中已经存在组合(ip,user_id,date)时才会插入的查询:
mysql_query("INSERT IGNORE INTO `popupip` (`ip`, `user_id`, `date`) VALUES ('$userip', $secid, '$date');");
使用这个解决方案,你不需要做额外的" SELECT"查询,或者"如果"检查是否有结果。