Mysql
 sql >> Baza danych >  >> RDS >> Mysql

INSERT IGNORE vs INSERT ... NA ZDUPLIKOWANY KLUCZ AKTUALIZACJI

Polecam użycie INSERT...ON DUPLICATE KEY UPDATE .

Jeśli używasz INSERT IGNORE , wiersz nie zostanie faktycznie wstawiony, jeśli spowoduje to zduplikowanie klucza. Ale oświadczenie nie wygeneruje błędu. Zamiast tego generuje ostrzeżenie. Te przypadki obejmują:

  • Wstawianie zduplikowanego klucza w kolumnach z PRIMARY KEY lub UNIQUE ograniczenia.
  • Wstawianie NULL do kolumny z NOT NULL ograniczenie.
  • Wstawianie wiersza do tabeli podzielonej na partycje, ale wstawiane wartości nie są mapowane na partycję.

Jeśli używasz REPLACE , MySQL faktycznie wykonuje DELETE po którym następuje INSERT wewnętrznie, co ma kilka nieoczekiwanych skutków ubocznych:

  • Przydzielono nowy identyfikator automatycznego przyrostu.
  • Zależne wiersze z kluczami obcymi mogą zostać usunięte (jeśli używasz kaskadowych kluczy obcych) lub uniemożliwić REPLACE .
  • Wyzwalacze uruchamiane po DELETE są niepotrzebnie wykonywane.
  • Efekty uboczne są również propagowane do replik.

korekta: oba REPLACE i INSERT...ON DUPLICATE KEY UPDATE są niestandardowymi, zastrzeżonymi wynalazkami specyficznymi dla MySQL. ANSI SQL 2003 definiuje MERGE oświadczenie, które może rozwiązać tę samą potrzebę (i więcej), ale MySQL nie obsługuje MERGE oświadczenie.

Użytkownik próbował edytować ten post (modyfikacja została odrzucona przez moderatorów). Edycja próbowała dodać roszczenie, które INSERT...ON DUPLICATE KEY UPDATE powoduje przydzielenie nowego identyfikatora automatycznego przyrostu. To prawda, że ​​nowy identyfikator jest generowany , ale nie jest używany w zmienionym wierszu.

Zobacz demonstrację poniżej, przetestowaną z Percona Server 5.5.28. Zmienna konfiguracyjna innodb_autoinc_lock_mode=1 (domyślnie):

mysql> create table foo (id serial primary key, u int, unique key (u));
mysql> insert into foo (u) values (10);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   10 |
+----+------+

mysql> show create table foo\G
CREATE TABLE `foo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `u` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

mysql> insert into foo (u) values (10) on duplicate key update u = 20;
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+

mysql> show create table foo\G
CREATE TABLE `foo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `u` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

Powyższe pokazuje, że instrukcja IODKU wykrywa duplikat i wywołuje aktualizację, aby zmienić wartość u . Zwróć uwagę na AUTO_INCREMENT=3 wskazuje, że identyfikator został wygenerowany, ale nie został użyty w wierszu.

Natomiast REPLACE usuwa oryginalny wiersz i wstawia nowy wiersz, generując i przechowywanie nowego identyfikatora automatycznego przyrostu:

mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  3 |   20 |
+----+------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wstawianie danych za pomocą mysqli

  2. ScaleGrid DBaaS rozszerza usługi hostingowe MySQL poprzez AWS Cloud

  3. Używanie OpenVPN do zabezpieczania dostępu do klastra baz danych w chmurze

  4. Jak stworzyć format json z mysql group-concat?

  5. SQL:Znajdź maksymalny rekord na grupę