INSERT ... ON DUPLICATE KEY(什么都不做)

ufk*_*ufk 175 mysql sql unique-key

我有一个表,其中包含两列唯一键:

CREATE  TABLE `xpo`.`user_permanent_gift` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`fb_user_id` INT UNSIGNED NOT NULL ,
`gift_id` INT UNSIGNED NOT NULL ,
`purchase_timestamp` TIMESTAMP NULL DEFAULT now() ,
PRIMARY KEY (`id`) ,
UNIQUE INDEX `user_gift_UNIQUE` (`fb_user_id` ASC, `gift_id` ASC) );
Run Code Online (Sandbox Code Playgroud)

我想在该表中插入一行,但如果该键存在,则什么都不做!我不希望生成错误,因为密钥存在.

我知道有以下语法:

INSERT ... ON DUPLICATE KEY UPDATE ...
Run Code Online (Sandbox Code Playgroud)

但是有类似的东西:

INSERT ... ON DUPLICATE KEY DO NOTHING 
Run Code Online (Sandbox Code Playgroud)

cee*_*yoz 303

是的,有INSERT ... ON DUPLICATE KEY UPDATE id=id,或者你可以id.

  • 请注意,INSERT IGNORE还会忽略其他错误,例如数据转换失败. (119认同)
  • 所以我将使用ON DUPLICATE KEY UPDATE id = id.我只想忽略密钥重复而不是任何其他类型的错误. (35认同)
  • @ufk:`INSERT IGNORE`没有'ON DUPLICATE KEY`部分,例如`INSERT IGNORE INTO xpo.user_permanent_gift(...)VALUES(...)` (23认同)
  • 只是在INSERT之后添加IGNORE,其余的语法是一样的吗? (5认同)
  • 注意INSERT IGNORE将增加自动增量列,即使未插入行也是如此 (5认同)
  • 还可以确认在某些情况下 INSERT IGNORE 会增加 AUTO_INCRMENT 值,即使由于重复和 IGNORE 而从未实际使用过 ID。 (2认同)
  • @mpen不,它不会那样工作:语句的“UPDATE”部分仅适用于现有行,因此“column=column”将“column”设置为其现有值*,即没有更改。如果您*想要*将其更新为新值(例如允许更改 id 列的大小写),那么您可以使用 `column=VALUES(column)`,或者从 MySQL v8.0.19 开始使用 `column= new.column` 其中“new”是您为要插入的行指定的别名。请参阅https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html。 (2认同)

Kim*_*Kim 21

如何实现“如果不存在则插入”?

1. REPLACE INTO

优点:

  1. 简单的。

缺点:

  1. 太慢了。

  2. 如果有条目匹配或,自动递增键将更改(增加 1),因为它删除旧条目然后插入新条目。unique keyprimary key

2. INSERT IGNORE

优点:

  1. 简单的。

缺点:

  1. 如果有条目匹配,自增键不会改变,unique key或者primary key自增索引会增加 1

  2. 一些其他错误/警告将被忽略,例如数据转换错误。

3. INSERT ... ON DUPLICATE KEY UPDATE

优点:

  1. 您可以使用此轻松实现“保存或更新”功能

缺点:

  1. 如果您只想插入而不是更新,则看起来相对复杂。

  2. 如果有条目匹配,自增键不会改变,unique key或者primary key自增索引会增加 1

4.如果有条目匹配unique key或,有primary key什么方法可以停止自动递增键的增加?

正如@toien在下面的评论中提到的:innodb_autoinc_lock_mode如果您innodb用作引擎,“自动增量列将取决于5.1版之后的配置” ,但这也会影响并发性,因此在使用前需要仔细考虑。到目前为止,我没有看到任何更好的解决方案。