Auto_increment

Mysql AUTO_INCREMENT

1.Innodb表的自动增长列可以手工插入,但是插入的值如果是空或者0,则实际插入的将是自动增长后的值
mysql> create table t1(id int not null auto_increment primary key,name varchar(10));
Query OK, 0 rows affected (0.06 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> insert into t1 values(0,'fanboshi');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values(null,'duyalan');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | fanboshi |
|  2 | duyalan  |
+----+----------+
2 rows in set (0.00 sec)
2.可以通过alter table t1 auto_incremenrt=n 语句强制设置自动增长列的初始值,默认从1开始,但是该强制的默认值是保留在内存中的,如果该值在使用之前数据库重新启动,那么这个强制的默认值就会丢失,就需要数据库启动后重新设置
mysql> alter table t1 auto_increment=5;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into t1 values(null,'handudu');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | fanboshi |
|  2 | duyalan  |
|  5 | handudu  |
+----+----------+
3 rows in set (0.00 sec)
3.可以是用last_insert_id()查询当前线程最后插入记录使用的值。如果一次插入多条记录,那么返回的是第一条记录使用的自动增长值。
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                5 |
+------------------+
1 row in set (0.00 sec)
注意last_insert_id()是所有表auto_increment的最新插入值,
因此在并发的情况下,获取某表的最新插入auto_increment可能出现错误
4.对于innodb表,自动增长列必须是索引,且必须是组合索引的第一列,且一个表只能有一个auto_increment属性。

mysql> create table t2(id int not null auto_increment,name varchar(10));
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

非主键
mysql> create table t2(id int not null auto_increment,name varchar(10),index(id));
Query OK, 0 rows affected (0.09 sec)

mysql> mysql> show index from t2;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t2    |          1 | id       |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

mysql> show index from t2;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t2    |          1 | id       |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)

不是主键,只是有索引
mysql> insert into t2 values(1,'fan');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 values(2,'fan');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t2;
+----+------+
| id | name |
+----+------+
|  1 | fan  |
|  2 | fan  |
+----+------+
2 rows in set (0.00 sec)

如果是组合索引,也必须是组合索引的第一列
mysql> create table t3(id1 int not null auto_increment,id2 int,name varchar(10),index(id2,id1));
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

但是对于MyISAM表,自动增长列可以使组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前面几列进行排序后递增的。

mysql> create table t3_myisam(id1 int not null auto_increment,id2 int,name varchar(10),index(id2,id1)) engine=myisam;
Query OK, 0 rows affected (0.04 sec)

mysql> insert into t3_myisam(id2,name) values(3,'fanboshi'),(1,'duyalan'),(1,'daduzi'),(2,'fan'),(5,'hehe'),(6,'keke');
Query OK, 6 rows affected (0.03 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from t3_myisam;
+-----+------+----------+
| id1 | id2  | name     |
+-----+------+----------+
|   1 |    3 | fanboshi |
|   1 |    1 | duyalan  |
|   2 |    1 | daduzi   |
|   1 |    2 | fan      |
|   1 |    5 | hehe     |
|   1 |    6 | keke     |
+-----+------+----------+
6 rows in set (0.00 sec)
好像看不出啥规律
再插入一次
mysql> insert into t3_myisam(id2,name) values(3,'fanboshi'),(1,'duyalan'),(1,'daduzi'),(2,'fan'),(5,'hehe'),(6,'keke');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0
mysql> select * from t3_myisam order by id2,id1;
+-----+------+----------+
| id1 | id2  | name     |
+-----+------+----------+
|   1 |    1 | duyalan  |
|   2 |    1 | daduzi   |
|   3 |    1 | duyalan  |
|   4 |    1 | daduzi   |
|   1 |    2 | fan      |
|   2 |    2 | fan      |
|   1 |    3 | fanboshi |
|   2 |    3 | fanboshi |
|   1 |    5 | hehe     |
|   2 |    5 | hehe     |
|   1 |    6 | keke     |
|   2 |    6 | keke     |
+-----+------+----------+
12 rows in set (0.00 sec)
id2=1有四个,所以id1有1,2,3,4
id2=2有俩,id1=1,2
自动增长列id1作为组合索引的第二列,对该表插入一些记录后,可以发现自动增长列是按照组合索引第一列id2进行排序后分组递增的

5.MyISAM 及INNODB表,表中auto_increment最大值被删除,将不会被重用。就是说会跳号

mysql> insert into t1(name) values('hehe');
Query OK, 1 row affected (0.02 sec)

mysql> select * from t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | fanboshi |
|  2 | duyalan  |
|  5 | handudu  |
|  6 | hehe     |
+----+----------+
4 rows in set (0.00 sec)

mysql> delete from t1 where id=6;
Query OK, 1 row affected (0.08 sec)

mysql> insert into t1(name) values('keke');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | fanboshi |
|  2 | duyalan  |
|  5 | handudu  |
|  7 | keke     |
+----+----------+
4 rows in set (0.00 sec)
6.用"WHERE auto_col IS NULL"条件选择出新插入的行,即在INSERT后马上用:

SELECT * FROM t4 WHERE id IS NULL;
选择出来的将是新插入的行,而非真正的满足"id IS NULL"条件的行。
但你要是再执行一次上述查询,则返回的又变成了真正的满足"a IS NULL"条件的行,
由于a是主键,因此肯定会返回空集。这看上去很诡异是吗,不过MySQL也不想这么干,为了支持 ODBC标准
不过可以将SQL_AUTO_IS_NULL设为0来禁止这一用法。
此方法获取last_insert_id不推荐

mysql> insert into t1(name) values('new');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1 where id is null;
Empty set (0.00 sec)

mysql> show variables like 'sql_auto_is_null';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| sql_auto_is_null | OFF   |
+------------------+-------+
1 row in set (0.00 sec)

mysql> set session sql_auto_is_null=on;
Query OK, 0 rows affected (0.02 sec)

mysql> show variables like 'sql_auto_is_null';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| sql_auto_is_null | ON    |
+------------------+-------+
1 row in set (0.00 sec)

mysql> select * from t1 where id is null;
+----+------+
| id | name |
+----+------+
|  8 | new  |
+----+------+
1 row in set (0.01 sec)

mysql> select * from t1 where id is null;
Empty set (0.00 sec)
7.AUTO_INCREMENT属性也给复制带来了麻烦。一般情况下复制AUTO_INCREMENT属性能正确工作,但以下情况还是有问题:
  1. INSERT DELAYED ... VALUES(LAST_INSERT_ID())不能被正确复制
  2. 存储过程插入的使用AUTO_INCREMENT属性的记录不能被正确复制
  3. 通过"ALTER TABLE"命令增加AUTO_INCREMENT属性时在主从节点上产生的值可能是不一样的,因为这个各行AUTO_INCREMENT属性的值取决于物理上的存储顺序。
8.对于replication的master-master方式 为防止auto_increment字段的重复,可做如下设置

A服务器的my.cnf设置如下:

auto_increment_offset = 1
auto_increment_increment = 2

这样A的auto_increment字段产生的数值是:1, 3, 5, 7, ...

B服务器的my.cnf设置如下:

auto_increment_offset = 2
auto_increment_increment = 2

这样B的auto_increment字段产生的数值是:2, 4, 6, 8, ...

8.根据官方的说明:If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. (如果auto_increment_offset的值大于auto_increment_increment的值,则auto_increment_offset的值会被忽略)

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> set session auto_increment_offset=5;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'auto_increment%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 5     |
+--------------------------+-------+
2 rows in set (0.00 sec)

mysql> create table t5 like t1;
Query OK, 0 rows affected (0.07 sec)

mysql> desc t5;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> insert into t5(name) values('fanboshi');
Query OK, 1 row affected (0.01 sec)

mysql> select * from t5;
+----+----------+
| id | name     |
+----+----------+
|  1 | fanboshi |
+----+----------+
1 row in set (0.00 sec)

mysql> set session auto_increment_increment=5;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t5(name) values('duyalan');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t5(name) values('heheda');
Query OK, 1 row affected (0.02 sec)

mysql> select * from t5;
+----+----------+
| id | name     |
+----+----------+
|  1 | fanboshi |
|  5 | duyalan  |
| 10 | heheda   |
+----+----------+
3 rows in set (0.00 sec)

Auto_increment详解的更多相关文章

  1. [原创]mybatis详解说明

    mybatis详解 2017-01-05MyBatis之代理开发模式1 mybatis-Dao的代理开发模式 Dao:数据访问对象 原来:定义dao接口,在定义dao的实现类 dao的代理开发模式 只 ...

  2. MySQL 数据类型 详解

    MySQL 数据类型 详解 MySQL 的数值数据类型可以大致划分为两个类别,一个是整数,另一个是浮点数或小数.许多不同的子类型对这些类别中的每一个都是可用的,每个子类型支持不同大小的数据,并且 My ...

  3. MYSQL服务器my.cnf配置文档详解

    MYSQL服务器my.cnf配置文档详解 硬件:内存16G [client] port = 3306 socket = /data/3306/mysql.sock [mysql] no-auto-re ...

  4. MySQL数据类型 int(M) 表示什么意思?详解mysql int类型的长度值问题

    MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MySQL 的时候,我还以为 int(3) ...

  5. MySQL 索引详解大全

    什么是索引? 1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 2. 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结 ...

  6. 最全面的 MySQL 索引详解

    什么是索引? 1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 2.索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构 ...

  7. 详解MySQL中EXPLAIN解释命令

    Explain 结果解读与实践   基于 MySQL 5.0.67 ,存储引擎 MyISAM .   注:单独一行的"%%"及"`"表示分隔内容,就象分开“第一 ...

  8. MySQL5日期类型DATETIME和TIMESTAMP相关问题详解

    MySQL5日期类型DATETIME和TIMESTAMP相关问题详解 MySQL5的日期类型有三种:DATETIME.DATE和TIMESTAMP,除了DATE用来表示一个不带时分秒的是日期,另外两个 ...

  9. mysql show variables系统变量详解

    mysql系统变量详解 mysqld服务器维护两种变量.全局变量影响服务器的全局操作.会话变量影响具体客户端连接相关操作. 服务器启动时,将所有全局变量初始化为默认值.可以在选项文件或命令行中指定的选 ...

随机推荐

  1. BZOJ2038: [2009国家集训队]小Z的袜子(hose)

    Time Limit: 20 Sec  Memory Limit: 259 MB Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天, ...

  2. oracle sql查询转义下划线

    1,看以下结果 select * from test where login like '%CF_%'; LOGIN------------------------------------------ ...

  3. mysql基础用法

    <1>内置函数: locate('aa', '字段名');查询aa在字段中是否存在,返回1或0 replace('字段名','需替换的字符','替换后的字符') <2>函数: ...

  4. 设置centos7语言显示环境

    1.查看可选语言显示包 locale -a ............(省略好多) zh_CNzh_CN.gb18030zh_CN.gb2312zh_CN.gbkzh_CN.utf8zh_HKzh_HK ...

  5. 检测Java程序运行时间的2种方法(高精度的时间[纳秒]与低精度的时间[毫秒])

    第一种是以毫秒为单位计算的. 代码如下: long startTime=System.currentTimeMillis(); //获取开始时间 doSomeThing(); //测试的代码段 lon ...

  6. 8086cpu-intel汇编指令简介

    jcxz   有条件跳转指令,cx为跳转条件.如果(cx)==0则跳转到指定标号处.跳转地址在机器码中已相对位置(-128~127)给出. 相当于                if((cx)==0) ...

  7. C. Shaass and Lights 组合数学

    http://codeforces.com/contest/294/problem/C 把那个数组n分段了,那么有两类. 1.开头和端点那些,就是只有一端在开始的,这个时候,要开完这些灯,只能循序渐进 ...

  8. 关于JS获取来路url问题

    Javascript 正常取来源网页的URL只要用: document.referrer 就可以了!   但,如果来源页是Javascript跳转过来的,上边的方法就拿不到了!所以用:   opene ...

  9. Visual Studio Entity Framework (EF) 生成SQL 代码 性能查询

    Visual Studio Entity Framework (EF) 生成SQL 代码 性能查询     SQL 中,有SQL Server Profiler可以用来查询性能以及查看外部调用的SQL ...

  10. 3.使用git提交项目到开源中国(gitosc)

    1.提交地址 使用的是开源中国git仓库 git.oschina.net 在windos环境下使用msysgit. 2.初始化化 username.email初始化 git config --glob ...