Mysql数据库之auto_increment

Posted wangwust

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql数据库之auto_increment相关的知识,希望对你有一定的参考价值。

一、概述

    在数据库应用中,我们经常需要用到自动递增的唯一编号来标识记录。在mysql中,可通过数据列的auto_increment属性来自动生成。可在建表时可用“auto_increment=n”选项来指定一个自增的初始值。可用“alter table table_name auto_increment=n”命令来重设自增的起始值,当然在设置的时候Mysql会取数据表中auto_increment列的最大值 + 1与n中的较大者作为新的auto_increment值。

    Myql的auto_increment属性具有以下特性:

    • 具有auto_increment属性的数据列应该是一个正数序列,如果把该数据列声明为UNSIGNED,这样序列的编号个数可增加一倍。比如tinyint数据列的最大编号是127,如果加上UNSIGNED,那么最大编号变为255
    • auto_increment数据列必须有唯一索引,以避免序号重复;必须具备NOT NULL属性

    实际应用中发现,在delete掉某张innoDB表的全部数据并重启Mysql会导致该表的auto_increment列变为1。特测试多种情况下auto_increment列的变化并记录如下。

二、实验

   1、innoDB与MyISAM对比

  (1)首先,创建一张引擎为innoDB的表测试一下delete掉所有数据然后重启Mysql之后,auto_increment的情况:

mysql> CREATE TABLE `table1` (
    -> `id` bigint(20) NOT NULL auto_increment,
    -> `create_time` datetime DEFAULT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

mysql> insert into table1(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table1(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table1(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table1(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table1(create_time) values (now());
Query OK, 1 row affected

mysql> select * from table1;
+----+---------------------+
| id | create_time         |
+----+---------------------+
|  1 | 2017-02-28 16:25:11 |
|  2 | 2017-02-28 16:25:21 |
|  3 | 2017-02-28 16:25:23 |
|  4 | 2017-02-28 16:25:23 |
|  5 | 2017-02-28 16:25:24 |
|  6 | 2017-02-28 16:25:26 |
+----+---------------------+
6 rows in set

mysql> delete from table1;
Query OK, 6 rows affected

mysql> select * from table1;
Empty set

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table1\';
 
+----------------+
| auto_increment |
+----------------+
|              7 |
+----------------+
1 row in set

    可见,执行delete操作清空表之后,表table1的auto_increment值仍然是正常的。重启数据库之后:

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table1\'; 
+----------------+
| auto_increment |
+----------------+
|              1 |
+----------------+
1 row in set

     可见,table1表的auto_increment值变成了1。

     结论:innoDB引擎的表,在执行delete清空操作之后,表的auto_increment值不会受到影响;一旦重启Mysql数据库,那么auto_increment值将变成1!

  (2)下面我们创建一个引擎为MyISAM的表,测试delete掉所有数据,并重启数据库之后auto_increment的值如何变化:

mysql> CREATE TABLE `table2` (
    -> `id` bigint(20) NOT NULL auto_increment,
    -> `create_time` datetime DEFAULT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

mysql> insert into table2(create_time) values (now());
Query OK, 1 row affected

mysql> 
mysql> 
mysql> insert into table2(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table2(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table2(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table2(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table2(create_time) values (now());
Query OK, 1 row affected

mysql> select * from table2;
+----+---------------------+
| id | create_time         |
+----+---------------------+
|  1 | 2017-02-28 17:05:22 |
|  2 | 2017-02-28 17:05:25 |
|  3 | 2017-02-28 17:05:26 |
|  4 | 2017-02-28 17:05:27 |
|  5 | 2017-02-28 17:05:28 |
|  6 | 2017-02-28 17:05:29 |
+----+---------------------+
6 rows in set

mysql> delete from table2;
Query OK, 6 rows affected

mysql> select * from table2;
Empty set

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table2\'; 
+----------------+
| auto_increment |
+----------------+
|              7 |
+----------------+
1 row in set

    delete清空操作并不会对table2的auto_increment产生任何影响。重启数据库之后:

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table2\'; 
+----------------+
| auto_increment |
+----------------+
|              7 |
+----------------+
1 row in set

   可见,表table2的auto_increment仍然为7。

   结论:MyISAM引擎的表,在执行delete操作之后,表的auto_increment值不会受到影响;重启Mysql数据库,auto_increment值也不会受到影响!

   2、创建表时指定auto_increment

   本节我们测试创建innoDB引擎的表时指定auto_increment会不会对auto_increment产生影响:

mysql> CREATE TABLE `table3` (
    -> `id` bigint(20) NOT NULL auto_increment,
    -> `create_time` datetime DEFAULT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB auto_increment=1000 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table3\';
+----------------+
| auto_increment |
+----------------+
|           1000 |
+----------------+
1 row in set

mysql> insert into table3(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table3(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table3(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table3(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table3(create_time) values (now());
Query OK, 1 row affected

mysql> select * from table3;
+------+---------------------+
| id   | create_time         |
+------+---------------------+
| 1000 | 2017-02-28 17:15:13 |
| 1001 | 2017-02-28 17:15:14 |
| 1002 | 2017-02-28 17:15:15 |
| 1003 | 2017-02-28 17:15:15 |
| 1004 | 2017-02-28 17:15:16 |
+------+---------------------+
5 rows in set

mysql> delete from table3;
Query OK, 5 rows affected

mysql> select * from table3;
Empty set

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table3\';
+----------------+
| auto_increment |
+----------------+
|           1005 |
+----------------+
1 row in set

     可见,delete操作并不会影响到表table3的auto_increment值。重启数据库之后:

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table3\';
+----------------+
| auto_increment |
+----------------+
|              1 |
+----------------+
1 row in set

   表table3的auto_increment变成了1。

   结论:在创建innoDB表时,无论指定或不指定auto_increment,delete清空+重启数据库都会使表的auto_increment值变成1。

   3、delete的时候添加where 1

   本节讨论在执行delete操作时,加where 1:

mysql> CREATE TABLE `table4` (
    -> `id` bigint(20) NOT NULL auto_increment,
    -> `create_time` datetime DEFAULT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> 
mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table4(create_time) values (now());
Query OK, 1 row affected

mysql> select * from table4;
+----+---------------------+
| id | create_time         |
+----+---------------------+
|  1 | 2017-02-28 17:21:33 |
|  2 | 2017-02-28 17:21:34 |
|  3 | 2017-02-28 17:21:35 |
|  4 | 2017-02-28 17:21:36 |
|  5 | 2017-02-28 17:21:36 |
|  6 | 2017-02-28 17:21:37 |
|  7 | 2017-02-28 17:21:38 |
+----+---------------------+
7 rows in set

mysql> delete from table4 where 1;
Query OK, 7 rows affected

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table4\';
+----------------+
| auto_increment |
+----------------+
|              8 |
+----------------+
1 row in set

   重启数据库之后:

mysql> select auto_increment from information_schema.tables where table_schema = database() and table_name=\'table4\';
+----------------+
| auto_increment |
+----------------+
|              1 |
+----------------+
1 row in set

   可见,网上的所流传的delete清空操作时添加where 1并没用。

   结论:delete innoDB表时,添加或不添加where 1,在数据库重启之后auto_increment都会被重置为1。

    4、如果表中有数据,但是数据id小于auto_increment会怎么样?

   本节测试当innoDB表中有数据,但是auto_increment列最大的那个值小于表的auto_increment值会怎样。我们先插入一些数据到表中,然后删除末尾的几条数据:

mysql> CREATE TABLE `table5` (
    -> `id` bigint(20) NOT NULL auto_increment,
    -> `create_time` datetime DEFAULT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

mysql> insert into table5(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table5(create_time) values (now());
Query OK, 1 row affected

mysql> insert into table5(create_time) values (now());
Query OK, 1 row affected

以上是关于Mysql数据库之auto_increment的主要内容,如果未能解决你的问题,请参考以下文章

MySQL查询和修改auto_increment的方法

在 mysql 表 auto_increment 中创建一个 ID(事后)

MySQL中auto_increment的基本特性

更新 MySQL 数据库中所有表的 AUTO_INCREMENT 值

mysql中auto_increment(整数)的限制是多少

(MYSQL) Auto_increment 基于另一个表的最大 id 的临时表?