3

在我的表中,我有两个字段:v_idip_address. 仅当 IP 地址尚不存在时,我才想在此表中插入一些数据。

谷歌搜索后,我遇到了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 作为参数传入也是如此。

有人有线索吗?谢谢。

4

3 回答 3

6

您必须创建一个UNIQUE索引ip_address才能INSERT IGNORE工作:

ALTER TABLE 24h_visits
    ADD UNIQUE INDEX(ip_address)

但是,我还没有看到您的全部架构,但我会假设有一个列存储上次访问的时间戳。这是唯一有意义的方法(因此您可以不时清除超过 24 小时的访问)。

在这种情况下,您实际上不想要INSERT IGNOREINSERT ... 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,这(我认为)并不完全正确。

于 2011-08-31T01:34:10.610 回答
5

UNIQUE约束添加到您的ip_address列。

然后,如果它尝试添加重复ip_address行(除非您使用INSERT IGNORE),您的查询将失败。

于 2011-08-31T01:33:40.953 回答
3

其他答案实际上并没有回答这个问题:创建唯一索引可以防止插入重复项,这是一个好主意,但它没有回答“如果不存在如何插入”。
这就是你的做法:

INSERT IGNORE INTO 24h_visits (ip_address)
select ?
where not exists (select * from 24h_visits where ip_address = ?)

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

于 2011-08-31T01:41:52.723 回答