问:如果有一张表,里面有个字段为id的自增主键,当已经向表里面插入了10条数据之后,删除了id为8、9、10的数据,再把mysql重启,之后再插入一条数据,那么这条数据的id值应该是多少,是8还是11?
实际测试结果:
root@martin*localhost 16:38:29 >create table emp1(c_id int not null primary key auto_increment);
Query OK, 0 rows affected (5.86 sec)
root@martin*localhost 16:39:25 >alter table emp1 add column c_name varchar(20);
Query OK, 0 rows affected (0.82 sec)
Records: 0 Duplicates: 0 Warnings: 0
root@martin*localhost 16:40:11 >show create table emp1\G;
*************************** 1. row ***************************
Table: emp1
Create Table: CREATE TABLE `emp1` (
`c_id` int(11) NOT NULL AUTO_INCREMENT,
`c_name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
root@martin*localhost 16:40:15 >insert into emp1 (c_name) values('oracle数据库');
Query OK, 1 row affected (0.38 sec)
root@martin*localhost 16:41:10 >insert into emp1 (c_name) values('mysql数据库');
Query OK, 1 row affected (0.07 sec)
root@martin*localhost 16:41:18 >insert into emp1 (c_name) values('mem数据库');
Query OK, 1 row affected (0.12 sec)
root@martin*localhost 16:41:30 >insert into emp1 (c_name) values('Mem数据库');
Query OK, 1 row affected (0.30 sec)
root@martin*localhost 16:42:21 >insert into emp1 (c_name) values('pg数据库');
Query OK, 1 row affected (0.15 sec)
root@martin*localhost 16:42:34 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 5 | mem数据库 |
| 7 | Mem数据库 |
| 9 | pg数据库 |
+------+-----------------+
5 rows in set (0.00 sec)
root@martin*localhost 16:42:37 >delete from emp1 where c_id=9;
Query OK, 1 row affected (0.23 sec)
root@martin*localhost 16:42:51 >delete from emp1 where c_id=7;
Query OK, 1 row affected (0.08 sec)
root@martin*localhost 16:42:55 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 5 | mem数据库 |
+------+-----------------+
3 rows in set (0.00 sec)
root@martin*localhost 16:42:58 >shutdown;
Query OK, 0 rows affected (0.00 sec)
[mysql@martin02 ~]$ /etc/init.d/mysqld3308 start
Starting MySQL...... [ OK ]
root@martin*localhost 16:43:38 >insert into emp1 (c_name) values('ok数据库');
Query OK, 1 row affected (5.06 sec)
root@martin*localhost 16:43:54 >insert into emp1 (c_name) values('hello数据库');
Query OK, 1 row affected (0.08 sec)
root@martin*localhost 16:43:58 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 5 | mem数据库 |
| 7 | ok数据库 |
| 9 | hello数据库 |
+------+-----------------+
备注: 通过前期插入9条数据后,再删除c_id 为 7和9的数据,然后关闭数据库实例,启动后,插入数据库,发现id 填补了之前的id值。
原因: 关闭数据库实例后,innodb 内部计数器消失,再启动时,数据库重新初始化,通过已有的数据最大键值为基数。
##############################################################
root@martin*localhost 16:44:07 >insert into emp1 (c_name) values('pg数据库');
Query OK, 1 row affected (0.42 sec)
root@martin*localhost 16:45:42 >insert into emp1 (c_name) values('mssql数据库');
Query OK, 1 row affected (0.26 sec)
root@martin*localhost 16:45:47 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 5 | mem数据库 |
| 7 | ok数据库 |
| 9 | hello数据库 |
| 11 | pg数据库 |
| 13 | mssql数据库 |
+------+-----------------+
7 rows in set (0.00 sec)
root@martin*localhost 16:45:49 >delete from emp1 where c_id=13;
Query OK, 1 row affected (0.39 sec)
root@martin*localhost 16:46:08 >delete from emp1 where c_id=11;
Query OK, 1 row affected (0.05 sec)
root@martin*localhost 16:46:13 >delete from emp1 where c_id=5;
Query OK, 1 row affected (0.13 sec)
root@martin*localhost 16:46:22 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 7 | ok数据库 |
| 9 | hello数据库 |
+------+-----------------+
4 rows in set (0.00 sec)
root@martin*localhost 16:46:34 >insert into emp1 (c_name) values('1as数据库');
Query OK, 1 row affected (0.44 sec)
root@martin*localhost 16:46:54 >insert into emp1 (c_name) values('2as数据库');
Query OK, 1 row affected (0.38 sec)
root@martin*localhost 16:47:09 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 7 | ok数据库 |
| 9 | hello数据库 |
| 15 | 1as数据库 |
| 17 | 2as数据库 |
+------+-----------------+
6 rows in set (0.00 sec)
这里在没有重启数据库实例情况下,删除数据库后,再插入,其innodb 内部计数器未中断持续工作,计数器在累计计数,并通过binglog持久化。
############################################
root@martin*localhost 16:47:14 >shutdown;
Query OK, 0 rows affected (0.00 sec)
[mysql@martin02 ~]$ /etc/init.d/mysqld3308 start
Starting MySQL..... [ OK ]
root@martin*localhost 16:47:56 >insert into emp1 (c_name) values('3as数据库');
Query OK, 1 row affected (5.08 sec)
root@martin*localhost 16:48:09 >select * from emp1;
+------+-----------------+
| c_id | c_name |
+------+-----------------+
| 1 | oracle数据库 |
| 3 | mysql数据库 |
| 7 | ok数据库 |
| 9 | hello数据库 |
| 15 | 1as数据库 |
| 17 | 2as数据库 |
| 19 | 3as数据库 |
+------+-----------------+
7 rows in set (0.00 sec)
这里即使重启数据库实例,但是这之间并没有任何改变,计数器初始化后还是以最后持久化数据为基数,继续进行。