Mysql中自增字段(AUTO_INCREMENT)的一些常识

Mysql中自增字段(AUTO_INCREMENT)的一些常识

在系统开发过程中,我们经常要用到唯一编号。使用过mysql的人都应该知道,mysql有一个定义列为自增的属性:AUTO_INCREMENT。

指定了AUTO_INCREMENT的列必须要建索引,不然会报错,索引可以为主键索引,当然也可以为非主键索引。(不一定要做主键)





1

2

3

mysql> create
table t4 (id int
auto_increment);

ERROR 1075 (42000): Incorrect table
definition; there can be only
one auto column
and it must be defined as
a key

mysql>

下面的定义把t5表的主键定义为了name,而非自增的id字段





1

2

3

mysql>

mysql> create
table t5 (id int
auto_increment,name
varchar(20) primary
key,key(id));

Query OK, 0 rows
affected (0.01 sec)

指定了auto_increment的列,在插入时:


  1. 如果把一个NULL插入到一个AUTO_INCREMENT数据列里去,MySQL将自动生成下一个序列编号。编号从1开始,并1为基数递增。


  2. 当插入记录时,没有为AUTO_INCREMENT明确指定值,则等同插入NULL值。





    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    mysql> insert into t5 (id,name) values (null,‘test‘);

    Query OK, 1
    row affected (0.00
    sec)

        

    mysql> select * from t5;

    +----+------+

    | id | name |

    +----+------+

    2
    | test |

    +----+------+

    1 row in set (0.00 sec)


  3. 上面语句等同于下面语句:





    1

    mysql> insert into t5 (name) values (‘test‘);


  4. 当插入记录时,如果为AUTO_INCREMENT字段明确指定了一个数值,则会出现两种情况:

    情况一,如果插入的值与已有的编号重复,则会出现出 错信息,因为AUTO_INCREMENT数据列的值必须是唯一的;

    情况二,如果插入的值大于已编号的值,则会把该插入到数据列中,并使在下一个编号将从这个新值开始递增。





    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    ## 初始表

    mysql> show create table t2\G;

    *************************** 1. row ***************************

           Table: t2

    Create Table: CREATE TABLE `t2` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=MyISAM DEFAULT CHARSET=utf8

        

    ## 插入数据

    mysql> insert into t2 values (null),(null),(null); 

    Query OK, 3
    rows affected (0.00
    sec)

        

    ## auto_increment变成4

    mysql> show create table t2\G;

    *************************** 1. row ***************************

           Table: t2

    Create Table: CREATE TABLE `t2` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=MyISAM AUTO_INCREMENT=8
    DEFAULT CHARSET=utf8

        

    ## 插入7

    mysql> insert into t2 values (7);

    Query OK, 1
    row affected (0.00
    sec)

        

    ## auto_increment变成8

    mysql> show create table t2\G;

    *************************** 1. row ***************************

           Table: t2

    Create Table: CREATE TABLE `t2` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=MyISAM AUTO_INCREMENT=8
    DEFAULT CHARSET=utf8

    换句话说,就是自增字段可以跳过一些编号。


  5. 对于MyISAM表,如果用UPDATE命令更新自增列,如果列值与已有的值重复,则会出错。如果大于已有值,则下一个编号从该值开始递增。但是对于innodb表,update
    auto_increment字段,会导致发生报错

    MyISAM表的update如下所示





    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    ## 当前状态

    mysql> show create table t2\G;

    *************************** 1. row ***************************

           Table: t2

    Create Table: CREATE TABLE `t2` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=MyISAM AUTO_INCREMENT=8
    DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

       

    ## 将id=7的数据update为10

    mysql> update t2 set
    id=10 where id=7;

    Query OK, 1
    row affected (0.00
    sec)

    Rows matched: 1 
    Changed: 1 
    Warnings: 0

       

    ## 最新的auto_increment变为11

    mysql> show create table t2\G;

    *************************** 1. row ***************************

           Table: t2

    Create Table: CREATE TABLE `t2` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=MyISAM AUTO_INCREMENT=11
    DEFAULT CHARSET=utf8

    1
    row in set (0.00 sec)

    Innodb表的update操作如下所示

    (可以看到在update前后,表定义语句没有变化),接着执行insert会导致主键错误!





    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    mysql> show create table t3\G;

    *************************** 1. row ***************************

           Table: t3

    Create Table: CREATE TABLE `t3` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=8
    DEFAULT CHARSET=utf8

    1 row in set (0.00 sec)

       

    ## updae更新操作

    mysql> update t3 set
    id=10 where id=7;

    Query OK, 1
    row affected (0.27
    sec)

    Rows matched: 1 
    Changed: 1 
    Warnings: 0

       

    mysql> show create table t3\G;

    *************************** 1. row ***************************

           Table: t3

    Create Table: CREATE TABLE `t3` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=8
    DEFAULT CHARSET=utf8

    1
    row in set (0.00 sec)

    Innodb表继续插入会导致报错,但是只会报错一次,跳过10之后会正常插入





    1

    2

    3

    4

    5

    6

    7

    8

    mysql> insert into t3 values (null);

    Query OK, 1
    row affected (0.46
    sec)

       

    mysql> insert into t3 values (null);

    Query OK, 1
    row affected (0.11
    sec)

       

    mysql> insert into t3 values (null);

    ERROR 1062
    (23000): Duplicate entry ‘10‘
    for key ‘PRIMARY‘


  6. 被delete语句删除的id值,除非sql中将id重新插入,否则前面空余的id不会复用。

  7. delete from t3该语句不会引起auto_increment的变化,





    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    mysql> delete
    from t3;

    Query OK, 8
    rows affected (0.34
    sec)

      

    mysql> show create table t3\G;

    *************************** 1. row ***************************

           Table: t3

    Create Table: CREATE TABLE `t3` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB AUTO_INCREMENT=18
    DEFAULT CHARSET=utf8

    1
    row in set (0.00 sec)

    truncate table t3 该语句会引起auto_increment的变化,从头开始。





    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    mysql> truncate table t3;

    Query OK, 0
    rows affected (0.53
    sec)

      

    mysql> show create table t3\G;

    *************************** 1. row ***************************

           Table: t3

    Create Table: CREATE TABLE `t3` (

      `id` int(11) NOT NULL AUTO_INCREMENT,

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

    1
    row in set (0.00 sec)


  8. last_insert_id()函数可获得自增列自动生成的最后一个编号。但该函数只与服务器的本次会话过程中生成的值有关。如果在与服务器的本次会话中尚未生成AUTO_INCREMENT值,则该函数返回0。

修改AUTO_INCREMENT字段的起始值

可用alter table table_name AUTO_INCREMENT=n命令来重设自增的起始值。

但是如果设置的n比目前的数值小的话,执行的sql不会报错,但是不会生效!MyISAM和Innodb均是如此。





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

mysql> show create table t2;

+-------+-----------------------

 CREATE TABLE `t2` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  PRIMARY KEY (`id`)

) ENGINE=MyISAM AUTO_INCREMENT=14
DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

  

mysql>

mysql> alter table t2 auto_increment=2;

Query OK, 6
rows affected (0.04
sec)

Records: 6 
Duplicates: 0 
Warnings: 0

  

mysql> show create table t2;

+-------+--------------------

 CREATE TABLE `t2` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  PRIMARY KEY (`id`)

) ENGINE=MyISAM AUTO_INCREMENT=14
DEFAULT CHARSET=utf8

auto_increment_increment & auto_increment_offset 两个变量的介绍

这两个参数作用:控制自增列AUTO_INCREMENT的行为,用于MASTER-MASTER之间的复制,防止出现重复值。

两个变量均可以设置为全局或局部变量,并且假定每个值都可以为1到65,535之间的整数值。将其中一个变量设置为0会使该变量为1。如果试图将这些变量设置为大于65,535或小于0的值,则会将该值设置为65,535。如果向将auto_increment_increment或auto_increment_offset设置为非整数值,则会给出错误,并且变量的实际值在这种情况下保持不变。

两个值的含义:

auto_increment_increment:自增值的自增量

auto_increment_offset: 自增值的偏移量

设置了两个值之后,改服务器的自增字段值限定为:

auto_increment_offset +
auto_increment_increment*N
  的值,其中N>=0,但是上限还是要受定义字段的类型限制。

比如:

auto_increment_offset=1

auto_increment_increment=2

那么ID则是所有的奇数[1,3,5,7,.....]

如果:

auto_increment_offset=5

auto_increment_increment=10

那么ID则是所有的奇数[5,15,25,35,.....]

查看当前值:





1

2

3

4

5

6

7

mysql> show variables like ‘%auto_increment%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 1    
|

| auto_increment_offset    | 1    
|

+--------------------------+-------+

配置auto-increment-increment&auto-increment-offset的值:

(1):修改配置文件,重启mysqld

vi my.cnf

auto-increment-increment = 2

auto-increment-offset = 2

加入到mysqld相关的配置中

(2):通过set命令修改,不需要重启mysqld,一般需要用set global来设置





1

2

set
global auto_increment_increment=2;

set
global auto_increment_offset=2;

注意:在一个会话中,如果用set global
修改了mysql的某个变量值,如果不退出session,重新连接,你用show variables 看到的还是修改之前的值,因为show variables
默认返回的是当前session的值,最好用show session variables  和 show global variables
来查看对应的变量值。

下面是个例子:





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

mysql> set
global auto_increment_increment=2;

Query OK, 0
rows affected (0.00
sec)

 

mysql> show variables like ‘%auto_increment%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 1    
|

| auto_increment_offset    | 1    
|

+--------------------------+-------+

2 rows in set (0.00 sec)

 

mysql> show session variables like ‘%auto_increment%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 1    
|

| auto_increment_offset    | 1    
|

+--------------------------+-------+

2 rows in set (0.00 sec)

 

mysql> show global variables like ‘%auto_increment%‘;      

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 2    
|

| auto_increment_offset    | 1    
|

+--------------------------+-------+

2 rows in set (0.00 sec)

当然也可以只设定当前session有效





1

2

set
session auto_increment_increment=2;

set
session auto_increment_offset=2;

具体的例子:

 

auto_increment_increment=2

auto_increment_offset=1





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

mysql> truncate t2;

Query OK, 0
rows affected (0.00
sec)

 

mysql>

mysql>

mysql> set
session auto_increment_increment=2;

Query OK, 0
rows affected (0.00
sec)

 

mysql> set
session auto_increment_offset=1;

Query OK, 0
rows affected (0.00
sec)

 

mysql> show session variables like ‘%auto_incre%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 2    
|

| auto_increment_offset    | 1    
|

+--------------------------+-------+

2 rows in set (0.00 sec)

 

mysql>  insert into t2 values (null),(null),(null),(null),(null),(null);

Query OK, 6
rows affected (0.00
sec)

Records: 6 
Duplicates: 0 
Warnings: 0

 

mysql> select * from t2;

+----+

| id |

+----+

1
|

3
|

5
|

7
|

9
|

| 11
|

+----+

6 rows in set (0.00 sec)

auto_increment_increment=2

auto_increment_offset=2





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

mysql> truncate t2;

Query OK, 0
rows affected (0.00
sec)

 

mysql>

mysql> set
session auto_increment_increment=2;

Query OK, 0
rows affected (0.00
sec)

 

mysql> set
session auto_increment_offset=2;

Query OK, 0
rows affected (0.00
sec)

 

mysql> show session variables like ‘%auto_incre%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 2    
|

| auto_increment_offset    | 2    
|

+--------------------------+-------+

2 rows in set (0.00 sec)

 

mysql>  insert into t2 values (null),(null),(null),(null),(null),(null);

Query OK, 6
rows affected (0.00
sec)

Records: 6 
Duplicates: 0 
Warnings: 0

 

mysql> select * from t2;

+----+

| id |

+----+

2
|

4
|

6
|

8
|

| 10
|

| 12
|

+----+

6 rows in set (0.00 sec)

auto_increment_increment=10

auto_increment_offset=5





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

mysql> truncate t2;

Query OK, 0
rows affected (0.00
sec)

 

mysql> set
session auto_increment_increment=10;

Query OK, 0
rows affected (0.00
sec)

 

mysql>  set
session auto_increment_offset=5;

Query OK, 0
rows affected (0.00
sec)

 

mysql> show session variables like ‘%auto_incre%‘;

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| auto_increment_increment | 10   
|

| auto_increment_offset    | 5    
|

+--------------------------+-------+

2 rows in set (0.00 sec)

 

mysql> insert into t2 values (null),(null),(null),(null),(null),(null);

Query OK, 6
rows affected (0.00
sec)

Records: 6 
Duplicates: 0 
Warnings: 0

 

mysql> select * from t2;

+----+

| id |

+----+

5
|

| 15
|

| 25
|

| 35
|

| 45
|

| 55
|

+----+

6 rows in set (0.00 sec)

一个很重要的问题:如果在原有的序列中强制插入一个值,比如上面的例子,下一个数据我插入57,那再往后生成的值会受前面插入数据的影响吗?

答案是: 不会的!!





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

mysql> insert into t2 values (57),(58);

Query OK, 2
rows affected (0.01
sec)

Records: 2 
Duplicates: 0 
Warnings: 0

 

mysql> select * from t2;

+----+

| id |

+----+

5
|

| 15
|

| 25
|

| 35
|

| 45
|

| 55
|

| 57
|

| 58
|

+----+

8 rows in set (0.00 sec)

 

mysql> insert into t2 values (null),(null),(null);

Query OK, 3
rows affected (0.00
sec)

Records: 3 
Duplicates: 0 
Warnings: 0

 

mysql> select * from t2;

+----+

| id |

+----+

5
|

| 15
|

| 25
|

| 35
|

| 45
|

| 55
|

| 57
|

| 58
|

| 65
|

| 75
|

| 85
|

+----+

11 rows in set (0.00 sec)

时间: 2024-12-23 21:41:21

Mysql中自增字段(AUTO_INCREMENT)的一些常识的相关文章

mysql自增字段AUTO_INCREMENT重排或归零

由于删除了某些记录行,导致自增字段不连续了,重排或归零的方法: 方法1:truncate table 你的表名//这样不但重新定位自增的字段,而且会将表里的数据全部删除,慎用! 方法2:delete from 你的表名dbcc checkident(你的表名,reseed,0) //重新定位自增的字段,让它从1开始 方法3:如果你要保存数据,用phpmyadmin导出数据库,编辑sql文件,将其中的自增下一个id号改好,再导入. 方法4:MyISAM数据表可用alter table table_

mysql中多个字段共同确定唯一性

create table tbl_table ( id integer not null auto_increment, fname varchar(255), lname varchar(255), CONSTRAINT tbl_table PRIMARY KEY (id), unique (fname,lname) ) mysql中多个字段共同确定唯一性

mysql中的null字段值的处理及大小写问题

在MySQL中,NULL字段的处理,需要注意,当在处理查询条件中有NULL,很有可能你得到的值不是想要的,因为,在MySQL中,判断NULL值相等(=)或者不等(!=)都会返回false.主要出现在常见的SELECT以及WHERE字句中. 为了处理这种特殊的情况,MySQL提供了如下的关键字进行特殊处理: IS NULL: 当列的值是NULL,此运算符返回true. IS NOT NULL: 当列的值不为NULL, 运算符返回true. <=>: 比较操作符(不同于=运算符),当比较的的两个值

mysql中的保留字段

摘要 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versio····这句话对于咱们并不陌生,无非就是多了","之类的问题.但是你如果无意之中添加了一个mysql中的保留字段作为数据库中存贮的字段名,悲剧就这样发生了. mysql 保留字 目录[-] mysql的保留字段 前几天因为功能的临时变更,需要给数据表添加一个字段用来区别导入的批次,我就

INNODB自增主键的一些问题 vs mysql获得自增字段下一个值

今天发现 批量插入下,自增主键不连续了....... InnoDB AUTO_INCREMENT Lock Modes This section describes the behavior of AUTO_INCREMENT lock modes used to generate auto-increment values, and how each lock mode affects replication. Auto-increment lock modes are configured

MySQL设置自增字段

1.MySQL每张表只能有1个自增字段,这个自增字段即可作为主键,也可用作非主键使用,但是请注意将自增字段当做非主键使用时必须为其添加唯一索引,否则系统将会报错 1)将自动增长字段设置为主键 CREATE TABLE t1 ( id INT auto_increment PRIMARY KEY, sid INT ); 2)将自动增长字段设置为非主键 CREATE TABLE t2 ( sid INT PRIMARY KEY, id INT auto_increment UNIQUE ); 3)将

mysql中的保留字段,说多了都是泪啊!!!!

前几天因为功能的临时变更,需要给数据表添加一个字段用来区别导入的批次,我就在mysql中添加了group字段,没想到我的噩梦就此展开····· 本来程序已经接近收尾,本想着今早来公司给程序来个欢乐的结尾,没想到····每次导入excel表总是提示我sql语句错误,我变在sql语句上添添减减,也没有把错误搞定,整整一个上午外加下午两个小时,简直已经到了抓狂的程度.简直要跪地苦思冥想,但是还是没有搞定这个错误. 把问题放在一边,继续搞其他的东西····当在写一个group by 语句时,突然意识到,

PHP操作Mysql中的BLOB字段

1.MySQL中BLOB字段类型 BLOB类型的字段用于存储二进制数据. MySQL中,BLOB是个类型系列,包括:TinyBlob.Blob.MediumBlob.LongBlob,这几个类型之间的唯一区别是在存储文件的最大大小上不同. MySQL的四种BLOB类型 TinyBlob:  最大 255字节 Blob:      最大 65K MediumBlob:最大 16M LongBlob:  最大 4G 注意:如果你存储的文件过大,数据库的性能会下降很多. 2.PHP操作BLOB案例 [

怎么重置mysql的自增列AUTO_INCREMENT初时值

重置 MySQL 自增列 AUTO_INCREMENT 初时值 注意, 使用以下任意方法都会将现有数据删除. 方法一: delete from tb1; ALTER TABLE tbl AUTO_INCREMENT = 100; 1 2 (好处, 可以设置 AUTO_INCREMENT 为任意值开始) 提示:如果表列和数据很多, 速度会很慢, 如90多万条, 会在10分钟以上. 方法二: truncate tb1; 1 (好处, 简单, AUTO_INCREMENT 值重新开始计数.) 怎么重置