Mysql
 sql >> база данни >  >> RDS >> Mysql

INSERT IGNORE срещу INSERT ... ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИРАН КЛЮЧ

Бих препоръчал да използвате INSERT...ON DUPLICATE KEY UPDATE .

Ако използвате INSERT IGNORE , тогава редът всъщност няма да бъде вмъкнат, ако доведе до дублиран ключ. Но изявлението няма да генерира грешка. Вместо това генерира предупреждение. Тези случаи включват:

  • Вмъкване на дублиран ключ в колони с PRIMARY KEY или UNIQUE ограничения.
  • Вмъкване на NULL в колона с NOT NULL ограничение.
  • Вмъкване на ред в разделена таблица, но стойностите, които вмъквате, не се съпоставят с дял.

Ако използвате REPLACE , MySQL всъщност извършва DELETE последвано от INSERT вътрешно, което има някои неочаквани странични ефекти:

  • Разпределя се нов идентификатор за автоматично увеличение.
  • Зависимите редове с външни ключове може да бъдат изтрити (ако използвате каскадни външни ключове) или да предотвратите REPLACE .
  • Задействания, които се задействат при DELETE се изпълняват ненужно.
  • Страничните ефекти се разпространяват и в копия.

корекция: и двете REPLACE и INSERT...ON DUPLICATE KEY UPDATE са нестандартни, патентовани изобретения, специфични за MySQL. ANSI SQL 2003 дефинира MERGE изявление, което може да реши същата нужда (и повече), но MySQL не поддържа MERGE изявление.

Потребител се опита да редактира тази публикация (редактирането беше отхвърлено от модераторите). Редактирането се опита да добави твърдение, което INSERT...ON DUPLICATE KEY UPDATE причинява разпределяне на нов идентификатор за автоматично увеличение. Вярно е, че новият идентификатор е генериран , но не се използва в променения ред.

Вижте демонстрация по-долу, тествана с Percona Server 5.5.28. Конфигурационната променлива innodb_autoinc_lock_mode=1 (по подразбиране):

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

Горното показва, че операторът IODKU открива дубликата и извиква актуализацията, за да промени стойността на u . Обърнете внимание на AUTO_INCREMENT=3 показва, че идентификаторът е генериран, но не е използван в реда.

Докато REPLACE изтрива оригиналния ред и вмъква нов ред, генерирайки и съхраняване на нов идентификатор за автоматично увеличение:

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. Как да покажа съпоставянето на база данни в MySQL

  2. MySQL и MariaDB Балансиране на натоварването с ProxySQL

  3. PDO MySQL:Използвайте PDO::ATTR_EMULATE_PREPARES или не?

  4. Урок за MySQL:MySQL IN изявление (разширено)

  5. Съхраняване на изображение в базата данни директно или като base64 данни?