2016-06-06 6 views

Antwort

1

Auto_increment-Wert wird auch bei INSERT-Abfragen inkrementiert. Der Trick ist, dass es inkrementiert werden kann, auch wenn keine echten Zeilen hinzugefügt werden. Es gibt mehrere Fälle, und ich werde sie mit kleinen Demo-Tabelle erklären:

CREATE TABLE test (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    name VARCHAR(255) NOT NULL, 
    PRIMARY KEY (id), 
    UNIQUE KEY (name) 
) ENGINE = INNODB; 

[email protected]/test> Show table status like 'test'\G 
*************************** 1. row *************************** 
      Name: test 
     Engine: InnoDB 
     Version: 10 
    Row_format: Compact 
      Rows: 0 
Avg_row_length: 0 
    Data_length: 16384 
Max_data_length: 0 
    Index_length: 16384 
     Data_free: 0 
Auto_increment: 1 <-- Next auto_increment field value 
    Create_time: 2016-06-06 14:39:48 
    Update_time: NULL 
    Check_time: NULL 
     Collation: utf8_general_ci 
     Checksum: NULL 
Create_options: 
     Comment: 
1 row in set (0.00 sec) 

Fall # 1: INSERT

[email protected]/test> INSERT IGNORE INTO test (name) VALUES ("One"); 
Query OK, 1 row affected (0.00 sec) 

[email protected]/test> INSERT IGNORE INTO test (name) VALUES ("One"); 
Query OK, 0 rows affected (0.01 sec) 

[email protected]/test> SELECT * FROM test ORDER BY id; 
+----+------+ 
| id | name | 
+----+------+ 
| 1 | One | 
+----+------+ 
1 row in set (0.00 sec) 

[email protected]/test> Show table status like 'test'\G 
*************************** 1. row *************************** 
      Name: test 
     Engine: InnoDB 
     Version: 10 
    Row_format: Compact 
      Rows: 1 
Avg_row_length: 16384 
    Data_length: 16384 
Max_data_length: 0 
    Index_length: 16384 
     Data_free: 0 
Auto_increment: 3 
    Create_time: 2016-06-06 14:39:48 
    Update_time: NULL 
    Check_time: NULL 
     Collation: utf8_general_ci 
     Checksum: NULL 
Create_options: 
     Comment: 
1 row in set (0.00 sec) 

Fall # 2 IGNORE: INSERT ... ON DUPLICATE KEY UPDATE

[email protected]/test> INSERT INTO test (name) VALUES ("One") ON DUPLICATE KEY UPDATE name=VALUES(name); 
Query OK, 0 rows affected (0.00 sec) 

[email protected]/test> SELECT * FROM test ORDER BY id; 
+----+------+ 
| id | name | 
+----+------+ 
| 1 | One | 
+----+------+ 
1 row in set (0.00 sec) 

[email protected]/test> INSERT INTO test (name) VALUES ("One") ON DUPLICATE KEY UPDATE name=VALUES(name); 
Query OK, 0 rows affected (0.00 sec) 

[email protected]/test> Show table status like 'test'\G 
*************************** 1. row *************************** 
      Name: test 
     Engine: InnoDB 
     Version: 10 
    Row_format: Compact 
      Rows: 1 
Avg_row_length: 16384 
    Data_length: 16384 
Max_data_length: 0 
    Index_length: 16384 
     Data_free: 0 
Auto_increment: 5 
    Create_time: 2016-06-06 14:39:48 
    Update_time: NULL 
    Check_time: NULL 
     Collation: utf8_general_ci 
     Checksum: NULL 
Create_options: 
     Comment: 
1 row in set (0.00 sec) 

Fall # 3: mit Fehlern INSERT

[email protected]/test> INSERT INTO test (name) VALUES ("One"); 
ERROR 1062 (23000): Duplicate entry 'One' for key 'name' 

[email protected]/test> Show table status like 'test'\G 
*************************** 1. row *************************** 
      Name: test 
     Engine: InnoDB 
     Version: 10 
    Row_format: Compact 
      Rows: 1 
Avg_row_length: 16384 
    Data_length: 16384 
Max_data_length: 0 
    Index_length: 16384 
     Data_free: 0 
Auto_increment: 6 
    Create_time: 2016-06-06 14:39:48 
    Update_time: NULL 
    Check_time: NULL 
     Collation: utf8_general_ci 
     Checksum: NULL 
Create_options: 
     Comment: 
1 row in set (0.00 sec) 

Sie können mehr über die Gründe lesen, warum diese Löcher in diesem Artikel aufgetreten sind: https://www.percona.com/blog/2011/11/29/avoiding-auto-increment-holes-on-innodb-with-insert-ignore/ oder MySQL-Dokumentation: http://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html#innodb-auto-increment-lock-modes

+0

http://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment -handling.html Hier die erwähnten Arten von Auto-Inkrementen. sie zu einem von ihnen zu ändern wird Hilfe sein oder wird es zu Leistungseinbußen führen? – meet

+0

Soweit ich sehen kann, kann der "traditionelle" Sperrmodus (innodb_autoinc_lock_mode = 0) Löcher in der ID-Sequenz vermeiden, aber dieser Modus kann zu Leistungsproblemen führen, weil er bei jeder INSERT-Anweisung eine Sperre auf Tabellenebene erhält und gleichzeitige Einfügungen blockiert . Alle anderen Sperrmodi können die Löcher erzeugen. – pryazhnikov

+0

habe es vielen Dank. – meet

0

Beim Zurücksetzen von Transaktionen, die Zeilen einfügen würden, werden die Werte für den automatischen Inkrementierungszähler übersprungen.

0

Mit INSERT IGNORE und INSERT ... ON DUPLICATE KEY wird der Auto Increment Counter erhöht.

Verwandte Themen