何时使用不同的永不拒绝(“插入或更新”)MySQL语句?

时间:2011-12-21 20:50:38

标签: mysql database insert

应用程序中的标准问题是如果记录不存在则插入记录 - 如果记录存在则更新。在PRIMARY KEY未知的情况下,通常会发出SELECT,然后在找到记录后运行INSERTUPDATE来解决此问题。

但是,我知道至少有三种方法可以将记录插入数据库,即使记录已经存在。就个人而言,如果已经存在,我宁愿删除新的插入请求,但是在某些情况下,您可能会倾向于删除数据库中的记录并使用新的插入请求。

CREATE TABLE IF NOT EXISTS `table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `foo` int(10) unsigned NOT NULL,
  `bar` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `row` (`foo`,`bar`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

以下是三种方法:

  1. INSERT IGNORE INTO table (foo, bar) VALUES (2,3);

  2. INSERT INTO table (foo, bar) VALUES (2,3) ON DUPLICATE KEY UPDATE;

  3. REPLACE INTO table (foo, bar) VALUES (2,3);

  4. 在什么时候应该使用这些方法? 有人可以提供一些正确使用场景的例子吗?

2 个答案:

答案 0 :(得分:5)

    如果您只想插入新行,则应使用
  • INSERT

    假设您要存储日志条目,您需要记录每个事件,请使用INSERT


    如果您希望表中存在特定的密钥,则应使用
  • INSERT IGNORE,如果它是创建它的当前插入,或者它已经是本

    假设您有一个电话号码表和使用次数,您会找到一个您不确定的新电话号码,但是您希望它在那里。

    您使用INSERT IGNORE确保它在那里。


    如果要确保表中存在特定键,则应使用
  • REPLACE INTO,如果存在,则您需要使用新值,而不是存在

    您还有另一个包含电话号码的表格,这次您会找到一个新号码和一个与之关联的名称。

    您使用REPLACE INTO查找并更新完整的记录,或只是插入新信息。


  • <强> INSERT INTO ... ON DUPLICATE KEY UPDATE ...

    请注意,是另一种编写REPLACE INTO的方法,只要您确定存在特定密钥,就应该使用上述内容,但如果确实存在更新列中的部分,而非所有列。

    例如,如果您要存储来自某个IP的访问次数以及该用户访问过的第一个页面。

    INSERT INTO visitors (ip,visits,first_page) VALUES (<ip>,1,<current_page>) ON DUPLICATE KEY visits = visits +1;

答案 1 :(得分:3)

在你的问题中,你有

INSERT INTO `table` (foo, bar) VALUES (2,3) ON DUPLICATE KEY UPDATE;

只有当行索引为UNIQUE时才能工作:

CREATE TABLE IF NOT EXISTS `table` (  
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `foo` int(10) unsigned NOT NULL,  
  `bar` int(10) unsigned NOT NULL,  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `row` (`foo`,`bar`)  
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;  

否则,为什么只有一个索引?

此外,ON DUPLICATE KEY子句允许您更新非索引列。

至于REPLACE,请注意REPLACE实际上是DELETEINSERT