仅当记录尚不存在时才INSERT INTO查询

时间:2011-08-31 01:31:45

标签: mysql sql insert-into

在我的表格中,我有两个字段:v_idip_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作为参数传入。

任何人都有线索?感谢。

3 个答案:

答案 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 = ?)

此外,此方法不需要对架构进行任何更改。