【问题标题】:INSERT INTO query only if record doesn't already exist仅当记录不存在时才插入查询
【发布时间】:2011-08-31 01:31:45
【问题描述】:

在我的表格中,我有两个字段: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。

有人知道吗?谢谢。

【问题讨论】:

  • ip_address是表的主键吗?
  • 或许你可以使用WHERE NOT EXISTS

标签: mysql sql insert-into


【解决方案1】:

您必须在ip_address 上创建一个UNIQUE 索引才能使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 UNIQUE 约束是最好的方法。尽可能在数据库中强制执行完整性。
  • @alex: 你今天太 DBAish 了 :-)
  • @zerkms 不同的一天,不同的帽子:D
【解决方案2】:

UNIQUE 约束添加到您的ip_address 列。

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 我试图回答的不是问题,而是我相信 OP 真正想要的。
    • 我在责备您对 just 放置唯一索引的最初回答,我认为这是一个糟糕的主意 - 然后您必须在正常处理期间处理异常等。当然放索引,但你不想避免异常
    猜你喜欢
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2019-11-22
    • 1970-01-01
    • 2013-05-03
    • 2010-10-23
    • 1970-01-01
    相关资源
    最近更新 更多