WSTAW ... NA DUPLIKATOWANYM KLUCZU (nic nie rób)

184

Mam tabelę z unikalnym kluczem dla dwóch kolumn:

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

Chcę wstawić wiersz do tej tabeli, ale jeśli klucz istnieje, nie rób nic! Nie chcę generować błędu, ponieważ klucze istnieją.

Wiem, że istnieje następująca składnia:

INSERT ... ON DUPLICATE KEY UPDATE ...

ale czy jest coś takiego:

INSERT ... ON DUPLICATE KEY DO NOTHING 

?

ufk
źródło

Odpowiedzi:

331

Tak, użyj INSERT ... ON DUPLICATE KEY UPDATE id=id(nie spowoduje to aktualizacji wiersza, nawet jeśli idjest przypisane do siebie).

Jeśli nie przejmujesz się błędami (błędami konwersji, błędami klucza obcego) i automatycznym wyczerpaniem pola (jest zwiększane, nawet jeśli wiersz nie zostanie wstawiony z powodu duplikatu klucza), użyj INSERT IGNORE.

ceejayoz
źródło
5
żeby dodać IGNORE po INSERT, reszta składni jest taka sama?
ufk
25
@ufk: INSERT IGNOREbez ON DUPLICATE KEYczęści, np.INSERT IGNORE INTO xpo.user_permanent_gift (...) VALUES (...)
BoltClock
125
Pamiętaj, że INSERT IGNORE ignoruje również inne błędy, takie jak błędy konwersji danych.
mjcopple,
36
więc użyję ON DUPLICATE KEY UPDATE id = id. Chcę tylko zignorować duplikaty kluczy, a nie inne błędy.
ufk
7
uważaj INSERT IGNORE zwiększy kolumnę automatycznego przyrostu, nawet jeśli wiersz nie zostanie wstawiony
WorM
9

JAK WDROŻYĆ „wstaw, jeśli nie istnieje”?

1. REPLACE INTO

plusy:

  1. prosty.

Cons:

  1. za wolno.

  2. klawisz auto-inkrementacji ZMIENI (zwiększy się o 1), jeśli są pasujące wpisy unique keylub primary key, ponieważ usuwa stary wpis, a następnie wstawia nowy.

2) INSERT IGNORE

plusy:

  1. prosty.

Cons:

  1. klucz automatycznej inkrementacji nie zmieni się, jeśli będą pasujące wpisy, unique keylub primary keyindeks indeksu automatycznej inkrementacji wzrośnie o 1

  2. niektóre inne błędy / ostrzeżenia będą ignorowane, takie jak błąd konwersji danych.

3) INSERT ... ON DUPLICATE KEY UPDATE

plusy:

  1. Dzięki temu możesz łatwo wdrożyć funkcję „zapisz lub aktualizuj”

Cons:

  1. wygląda stosunkowo skomplikowanie, jeśli chcesz wstawić nie aktualizować.

  2. klucz automatycznej inkrementacji nie zmieni się, jeśli będą pasujące wpisy, unique keylub primary keyindeks indeksu automatycznej inkrementacji wzrośnie o 1

4. Jakikolwiek sposób, aby zatrzymać zwiększanie klucza automatycznego przyrostu, jeśli istnieją dopasowania wejściowe unique keylub primary key?

Jak wspomniano w komentarzu poniżej przez @toien: „kolumna automatycznego przyrostu będzie zależała od innodb_autoinc_lock_modekonfiguracji po wersji 5.1”, jeśli używasz innodbjako silnika, ale ma to również wpływ na współbieżność, więc należy ją dobrze rozważyć przed użyciem. Jak dotąd nie widzę lepszego rozwiązania.

Kim
źródło
automatyczna inkrementacja kolumny nastąpi w zależności od innodb_autoinc_lock_modekonfiguracji po wersji 5.1
toien
1

Użyj ON DUPLICATE KEY UPDATE ...,
Negatywny: ponieważ UPDATEwykorzystuje zasoby do drugiego działania.

Użyj INSERT IGNORE ...,
Negatywne: MySQL nie wyświetli żadnych błędów, jeśli coś pójdzie nie tak, więc nie możesz sobie z nimi poradzić. Używaj go tylko wtedy, gdy nie zależy ci na zapytaniu.

Abdul Aziz Al Basyir
źródło
@abdul jest wsparcie mysql, co tu wyjaśniłeś?
Lalit Tarsariya,