i-aș recomanda utilizarea INSERT...ON DUPLICATE KEY UPDATE
.
Dacă utilizați INSERT IGNORE
, atunci rândul nu va fi introdus dacă are ca rezultat o cheie duplicată. Dar declarația nu va genera o eroare. În schimb, generează un avertisment. Aceste cazuri includ:
- Introduceți o tastă duplicată în coloanele cu
PRIMARY KEY
sauUNIQUE
restricții. - Introduceți o coloană într-o coloană cu o restricție
NOT NULL
. - Introduceți un rând la o masă de partiție, dar valorile care inserează nu sunt atribuite unei partiții.
dacă utilizați REPLACE
mysql face de fapt un DELETE
urmat de către un intern, care are unele efecte secundare neașteptate:
- este atribuită o nouă identificare auto-inclejată.
- Rândurile dependente cu tastele externe pot fi îndepărtate (dacă sunt folosite tastele externe cascade) sau evită
REPLACE
. - declanșează focul care trage focul despre
DELETE
sunt executate inutil. - Efectele secundare sunt, de asemenea, răspândite la sclavi de replicare Ion.
Corecție: Ambele REPLACE
și INSERT...ON DUPLICATE KEY UPDATE
sunt invenții non-standard, proprietari, specifice Mysql. ANSI SQL 2003 definește un MERGE
care poate rezolva aceeași nevoie (și mai mult), dar MySQL nu acceptă declarația MERGE
.
Un utilizator a încercat să editeze acest post (ediția a fost respinsă de moderatori). Ediția a încercat să adauge o afirmație că INSERT...ON DUPLICATE KEY UPDATE
face o nouă atribuire a identificării auto-inclejate. Este adevărat că noul ID este generat, dar nu este utilizat în rândul schimbat.
A se vedea demonstrația de mai jos, testate cu serverul permanent 5.5.28. Variabila de configurare innodb_autoinc_lock_mode=1
(valoarea implicită):
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\GCREATE 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=latin1mysql> 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\GCREATE 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
Cele de mai sus arată că declarația iodku detectează duplicatul , și invocă actualizarea pentru a schimba valoarea u
. Notă AUTO_INCREMENT=3
indică faptul că a fost generată o identificare, dar nu a fost folosit în rând.
în timp ce REPLACE
Ștergeți rândul original și introduceți un nou rând, generarea și stocarea unei noi identificări auto-incoree:
mysql> select * from foo;+----+------+| id | u |+----+------+| 1 | 20 |+----+------+mysql> replace into foo (u) values (20);mysql> select * from foo;+----+------+| id | u |+----+------+| 3 | 20 |+----+------+