MySQL自増主キー不連続テスト

34611 ワード

日常の仕事の中で、自増主キーがセットされているのに、自増IDが非連続的な場合があるのではないでしょうか.
テストテーブルおよび関連パラメータは次のように設定されます.
mysql> show variables like '%auto_increment%'; 
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+
2 rows in set (0.01 sec)
mysql> show create table test2\G
*************************** 1. row ***************************
       Table: test2
Create Table: CREATE TABLE `test2` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)

mysql> insert into test2(a,b) values(1,1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test2;
+----+------+------+
| id | a    | b    |
+----+------+------+
|  1 |    1 |    1 |
+----+------+------+
1 row in set (0.00 sec)
  • round 1(データ競合による)
  • mysql> insert into test2(a,b) values(2,1);
    ERROR 1062 (23000): Duplicate entry '1' for key 'idx_b'
    mysql> 
    mysql> insert into test2(a,b) values(2,2);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from test2;
    +----+------+------+
    | id | a    | b    |
    +----+------+------+
    |  1 |    1 |    1 |
    |  3 |    2 |    2 |
    +----+------+------+
    2 rows in set (0.00 sec)
    
    
  • round 2(トランザクションロールバックによる)
  • mysql> begin;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> insert into test2(a,b) values(3,3);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> rollback;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> 
    mysql> insert into test2(a,b) values(3,3);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from test2;
    +----+------+------+
    | id | a    | b    |
    +----+------+------+
    |  1 |    1 |    1 |
    |  3 |    2 |    2 |
    |  5 |    3 |    3 |
    +----+------+------+
    3 rows in set (0.00 sec)
    
  • round 3(手動で自増IDを指定することによる)
  • mysql> insert into test2 values(100,4,4);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from test2;
    +-----+------+------+
    | id  | a    | b    |
    +-----+------+------+
    |   1 |    1 |    1 |
    |   3 |    2 |    2 |
    |   5 |    3 |    3 |
    | 100 |    4 |    4 |
    +-----+------+------+
    4 rows in set (0.00 sec)
    mysql> show create table test2\G
    *************************** 1. row ***************************
           Table: test2
    Create Table: CREATE TABLE `test2` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      `a` int(11) DEFAULT NULL,
      `b` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `idx_b` (`b`)
    ) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
    1 row in set (0.00 sec)
    
  • round 4(ロットinsertによる)
  • mysql> select * from test2;
    +-----+------+------+
    | id  | a    | b    |
    +-----+------+------+
    |   1 |    1 |    1 |
    |   3 |    2 |    2 |
    |   5 |    3 |    3 |
    | 100 |    4 |    4 |
    +-----+------+------+
    4 rows in set (0.00 sec)
    mysql> create table test3 like test2;        
    Query OK, 0 rows affected (0.08 sec)
    
    mysql> 
    mysql> insert into test3(a,b) select a,b from test2;
    Query OK, 4 rows affected (0.00 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> select * from test3;
    +----+------+------+
    | id | a    | b    |
    +----+------+------+
    |  1 |    1 |    1 |
    |  2 |    2 |    2 |
    |  3 |    3 |    3 |
    |  4 |    4 |    4 |
    +----+------+------+
    4 rows in set (0.00 sec)
    mysql> insert into test3(a,b) values(5,5);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> 
    mysql> select * from test3;
    +----+------+------+
    | id | a    | b    |
    +----+------+------+
    |  1 |    1 |    1 |
    |  2 |    2 |    2 |
    |  3 |    3 |    3 |
    |  4 |    4 |    4 |
    |  8 |    5 |    5 |
    +----+------+------+
    5 rows in set (0.00 sec)
    
    ***************************************************
    
    

    備考1:ここでの一括挿入とは、insert...select、replace...select、load dataなどの文タイプを含み、insert into values()、()を含まない.備考2:test 2にN個のデータ(2のx次方<=N<2のx+1次方)があると仮定し、test 2非id列をtest 3に挿入し、test 3が挿入した次のデータのid値が2のx+1次方とする.example:test 2には33個のデータがあり、33>32(2の5次、33<64(2の6次)、test 3に挿入された34個のデータのidは64