Auto_increment详解
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属性能正确工作,但以下情况还是有问题:
- INSERT DELAYED ... VALUES(LAST_INSERT_ID())不能被正确复制
- 存储过程插入的使用AUTO_INCREMENT属性的记录不能被正确复制
- 通过"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详解的更多相关文章
- [原创]mybatis详解说明
mybatis详解 2017-01-05MyBatis之代理开发模式1 mybatis-Dao的代理开发模式 Dao:数据访问对象 原来:定义dao接口,在定义dao的实现类 dao的代理开发模式 只 ...
- MySQL 数据类型 详解
MySQL 数据类型 详解 MySQL 的数值数据类型可以大致划分为两个类别,一个是整数,另一个是浮点数或小数.许多不同的子类型对这些类别中的每一个都是可用的,每个子类型支持不同大小的数据,并且 My ...
- MYSQL服务器my.cnf配置文档详解
MYSQL服务器my.cnf配置文档详解 硬件:内存16G [client] port = 3306 socket = /data/3306/mysql.sock [mysql] no-auto-re ...
- MySQL数据类型 int(M) 表示什么意思?详解mysql int类型的长度值问题
MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MySQL 的时候,我还以为 int(3) ...
- MySQL 索引详解大全
什么是索引? 1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 2. 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结 ...
- 最全面的 MySQL 索引详解
什么是索引? 1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 2.索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构 ...
- 详解MySQL中EXPLAIN解释命令
Explain 结果解读与实践 基于 MySQL 5.0.67 ,存储引擎 MyISAM . 注:单独一行的"%%"及"`"表示分隔内容,就象分开“第一 ...
- MySQL5日期类型DATETIME和TIMESTAMP相关问题详解
MySQL5日期类型DATETIME和TIMESTAMP相关问题详解 MySQL5的日期类型有三种:DATETIME.DATE和TIMESTAMP,除了DATE用来表示一个不带时分秒的是日期,另外两个 ...
- mysql show variables系统变量详解
mysql系统变量详解 mysqld服务器维护两种变量.全局变量影响服务器的全局操作.会话变量影响具体客户端连接相关操作. 服务器启动时,将所有全局变量初始化为默认值.可以在选项文件或命令行中指定的选 ...
随机推荐
- 一个页面中显示多个button时总行数计算公式。
总行数 = (按钮总数 + 每一行按钮数 - 1) / 每一行按钮数. 同理.假设我们要显示一定总数的item.每页固定数量,则总页数为. 总页数 = (总显示数量 + 每页显示的数量 - 1) / ...
- DeepLearning学习(1)--多层感知机
想直接学习卷积神经网络,结果发现因为神经网络的基础较弱,学习起来比较困难,所以准备一步步学.并记录下来,其中会有很多摘抄. (一)什么是多层感知器和反向传播 1,单个神经元 神经网络的基本单元就是神经 ...
- 初学c# -- 学习笔记(四)
想想,数据库先用mysql了,这玩意小且安装方便.前面web学了些,现在学winform的.数据库先看看便捷的mysql. 下载了一个mysql5.7版的,装上居然找不到密码,重装3.4回,找不到,说 ...
- 检测Java程序运行时间的2种方法(高精度的时间[纳秒]与低精度的时间[毫秒])
第一种是以毫秒为单位计算的. 代码如下: long startTime=System.currentTimeMillis(); //获取开始时间 doSomeThing(); //测试的代码段 lon ...
- exception 'yii\base\ErrorException' with message 'Class 'MongoClient' not found'
问题描述: 本来项目运行的好好的,搬了一次办公室(电脑主机一起搬的),第二天的时候就登录不了了. php版本和扩展没有改变,且没有修改任何配置,我尝试重启php5-fpm 服务,又重启nginx服务, ...
- Mediator(中介者)-对象行为型模式
1.意图 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 2.动机 通过将集体行为封装在一个单独的中介者对象中,中介者 ...
- ANDROID开发之问题积累及解决方案(二)
错误:“Binary XML file line # : Error inflating class” 原因:此异常是布局文件中有错引起的,那么返回到布局文件中看看. <?xml version ...
- iis7下配置php出现404.17错误的解决办法
服务器上建有几个PHP站点,都在正常运行.今天又新建了一个PHP站点,处理程序模块配置的和其他几个都一样,但就是跑不起来,一直提示404.17错误,重启服务器也不行. 最后实在没办法了,就把正常运行站 ...
- CentOS 6.5升级Python和安装IPython
<转自:http://www.noanylove.com/2014/10/centos-6-5-sheng-ji-python-he-an-zhuang-ipython/>自己常用.以做备 ...
- 【python】题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
# encoding:utf-8 # p001_1234threeNums.py def threeNums(): '''题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多 ...