207
votes

I have a table with a unique key for two columns:

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) );

I want to insert a row into that table, but if the key exists, to do nothing! I don't want an error to be generated because the keys exist.

I know that there is the following syntax:

INSERT ... ON DUPLICATE KEY UPDATE ...

but is there something like:

INSERT ... ON DUPLICATE KEY DO NOTHING 

?

3

3 Answers

369
votes

Yes, use INSERT ... ON DUPLICATE KEY UPDATE id=id (it won't trigger row update even though id is assigned to itself).

If you don't care about errors (conversion errors, foreign key errors) and autoincrement field exhaustion (it's incremented even if the row is not inserted due to duplicate key), then use INSERT IGNORE.

20
votes

HOW TO IMPLEMENT 'insert if not exist'?

1. REPLACE INTO

pros:

  1. simple.

cons:

  1. too slow.

  2. auto-increment key will CHANGE(increase by 1) if there is entry matches unique key or primary key, because it deletes the old entry then insert new one.

2. INSERT IGNORE

pros:

  1. simple.

cons:

  1. auto-increment key will not change if there is entry matches unique key or primary key but auto-increment index will increase by 1

  2. some other errors/warnings will be ignored such as data conversion error.

3. INSERT ... ON DUPLICATE KEY UPDATE

pros:

  1. you can easily implement 'save or update' function with this

cons:

  1. looks relatively complex if you just want to insert not update.

  2. auto-increment key will not change if there is entry matches unique key or primary key but auto-increment index will increase by 1

4. Any way to stop auto-increment key increasing if there is entry matches unique key or primary key?

As mentioned in the comment below by @toien: "auto-increment column will be effected depends on innodb_autoinc_lock_mode config after version 5.1" if you are using innodb as your engine, but this also effects concurrency, so it needs to be well considered before used. So far I'm not seeing any better solution.

1
votes

Use ON DUPLICATE KEY UPDATE ...,
Negative : because the UPDATE uses resources for the second action.

Use INSERT IGNORE ...,
Negative : MySQL will not show any errors if something goes wrong, so you cannot handle the errors. Use it only if you don’t care about the query.