在我的表格中,我有两个字段:v_id
和ip_address
。我想仅在IP地址不存在的情况下才将一些数据插入此表。
在Google发布之后,我遇到了INSERT IGNORE INTO
声明,这是我的代码:
public function update_visits($ip_address)
{
$sql = 'INSERT IGNORE INTO `24h_visits` (ip_address) VALUES (?)';
if($this->db->query($sql, array($ip_address)))
{
return TRUE;
}
return FALSE;
}
它运行正常并且没有错误,但是仍在进行重复的行,即使将相同的IP作为参数传入。
任何人都有线索?感谢。
答案 0 :(得分:6)
您必须在UNIQUE
上创建一个ip_address
索引才能使INSERT IGNORE
正常工作:
ALTER TABLE 24h_visits
ADD UNIQUE INDEX(ip_address)
但是,我还没有看到你的架构的全部内容,但我认为有一个列存储了上次访问的时间戳。这是唯一有意义的方法(因此您可以不时地清除超过24小时的访问次数)。
在这种情况下,您实际上不希望INSERT IGNORE
,而是INSERT ... ON DUPLICATE KEY UPDATE
。假设您有一个名为last_visit
的列:
INSERT INTO 24h_visits (ip_address, last_visit)
VALUES ('$ip_address', NOW())
ON DUPLICATE KEY UPDATE last_visit = NOW();
使用INSERT IGNORE
时,永远不会插入新行,因此您始终会在last_visit
上插入第一个值(我看到的方式)并不完全正确。
答案 1 :(得分:5)
将UNIQUE
约束添加到ip_address
列。
如果尝试添加重复的ip_address
行,则查询将失败(除非您使用INSERT IGNORE
)。
答案 2 :(得分:3)
其他答案实际上没有回答这个问题:创建一个唯一索引阻止插入副本,这是一个好主意,但它没有回答“如果不插入”已经在那里“ 你就是这样做的:
INSERT IGNORE INTO 24h_visits (ip_address)
select ?
where not exists (select * from 24h_visits where ip_address = ?)
此外,此方法不需要对架构进行任何更改。