连锁知识点总括,自增列重复值相关主题材料

 

导读:

图片 1

1 innodb 自增列现身重复值的标题

MySQL的自增列(AUTO_INCREMENT)和其它数据库的自增列相比,有那八个特点和不一样点(以致分化存款和储蓄引擎、不一致版本也可以有后生可畏对不等的风味),令人倍感有一点点稍稍复杂。上面大家从一些测验初叶,来认识、领悟一下那上头的分歧平时知识点:

在接收MySQL建表时,大家漫不经心会创建一个自增字段,并以此字段作为主键。本篇作品将以问答的款式呈报关于自增id的所有事。

    在叁遍宕机之后重启Mysql服务器并上涨数据的进度中窥见了自增主键列的自增数值会回降,引致有数量上有冲突。经过后生可畏番的各种审核之后察觉原来是主键自增值回落了,引致自增主键有重复招致外键关联失效引起的。

  先从难点初叶,再次出现下那个bug 

 

注: 本文所讲的都是依照Innodb存款和储蓄引擎。

大家来举个例证说美素佳儿下绘声绘色的场面,举个例子,创建几个个InNoDB引擎表:

use test;
drop table t1;
create table t1(id int auto_increment, a int, primary key (id)) engine=innodb;
insert into t1 values (1,2);insert into t1 values (null,2);
insert into t1 values (null,2);
select * from t1;
 ---- ------ 
| id | a |
 ---- ------ 
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
 ---- ------ 
delete from t1 where id=2;
delete from t1 where id=3;
select * from t1;
 ---- ------ 
| id | a |
 ---- ------ 
| 1 | 2 |
 ---- ------ 

 

下边话相当少说了,来叁只随着小编看看详细的介绍吧

CREATE TABLE `bsession`  (

这边大家关闭mysql,再开发银行mysql,然后再插入一条数据 

自增列悠久化难点

1.MySQL为什么提出将自增列id设为主键?

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

insert into t1 values (null,2);
select * FROM T1;
 ---- ------ 
| id | a |
 ---- ------ 
| 1 | 2 |
 ---- ------ 
| 2 | 2 |
 ---- ------ 

 

万生龙活虎大家定义了主键,那么InnoDB会选取主键作为集中索引、若无显式定义主键,则InnoDB会选拔第二个不满含有NULL值的头一无二索引作为主键索引、假诺也不曾这么的独一索引,则InnoDB会选拔置于6字节长的ROWID作为隐含的聚焦索引(ROWID随着行记录的写入而主键依次增加,那几个ROWID不像ORACLE的ROWID那样可援用,是包罗的卡塔尔国。 数据记录本人被存于主索引的叶子节点上。那将须要同一个叶子节点内的各条数据记录按主键顺序存放,因而每当有一条新的笔录插入时,MySQL会依照其主键将其插入适当的节点和地方,借使页面达到装载因子,则开发叁个新的页 要是表使用自增主键,那么每一次插入新的笔录,记录就能够挨个增多到当前索引节点的世袭地方,当生龙活虎页写满,就能够自行开荒八个新的页 假如选拔非自增主键,由于每回插入主键的值相近于自由,因而老是新记录都要被插到现存索引页得中间有个别地点,当时MySQL不能不为了将新记录插到卓殊岗位而移动多少,以致指标页面可能早就被回写到磁盘上而从缓存中清掉,那个时候又要从磁盘上读回来,那扩展了过多支付,同期频仍的移动、分页操作产生了大气的碎片,得到了远远不足紧凑的目录布局,后续不能不经过OPTIMIZE TABLE来重新建立表并优化填充页面。

`aname` varchar(80) NOT NULL DEFAULT ‘’,

  大家来看插入了(2,2),而只要自身从不重启,插入相通数量我们赢得的应有是(4,2卡塔尔国;

假使三个表具备自增列,当前最大自增列值为9, 删除了自增列6、7、8、9的笔录,重启MySQL服务后,再往表里面插入数据,自增列的值为6照旧10吗?  就算表的存储引擎为MyISAM呢,又会是如何境况? 上面实验蒙受为MySQL 5.7.21

综上来讲:当大家应用自增列作为主键时,存取功效是最高的。

PRIMARY KEY (`id`)

  上边的测量检验反映了mysql重启后,innodb存款和储蓄引擎的表自增id大概现身重复使用的景况。

 

2.自增列id一定是一而再的啊?

) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

  自增id重复使用在某个场景下回出现难题。依旧用地点的例证,假使t1有个历史表t1_history用来存t1表的历史数据,那么mysqld重启前,ti_history中或然已经有了(2,2)那条数据,而重启后大家又插入了(2,2),当新插入的(2,2卡塔尔迁移到历史表时,会背离主键限制。

 

自增id是拉长的 不肯定三番五次。

图片 2

 

mysql> drop table if exists test;

Query OK, 0 rows affected (0.08 sec)

 

mysql> create table test(id int auto_increment primary key, name varchar(32)) ENGINE=InnoDB;

Query OK, 0 rows affected (0.02 sec)

 

 

mysql> insert into test(name)

    -> select 'kkk1' from dual union all

    -> select 'kkk2' from dual union all

    -> select 'kkk3' from dual union all

    -> select 'kkk4' from dual union all

    -> select 'kkk5' from dual union all

    -> select 'kkk6' from dual union all

    -> select 'kkk7' from dual union all

    -> select 'kkk8' from dual union all

    -> select 'kkk9' from dual;

Query OK, 9 rows affected (0.01 sec)

Records: 9  Duplicates: 0  Warnings: 0

 

 

mysql> select * from test;

 ---- ------ 

| id | name |

 ---- ------ 

|  1 | kkk1 |

|  2 | kkk2 |

|  3 | kkk3 |

|  4 | kkk4 |

|  5 | kkk5 |

|  6 | kkk6 |

|  7 | kkk7 |

|  8 | kkk8 |

|  9 | kkk9 |

 ---- ------ 

9 rows in set (0.00 sec)

 

mysql> delete from test where id>=6;

Query OK, 4 rows affected (0.00 sec)

大家先来看下MySQL 对自增值的保存计谋:

创立表测量检验表

2 innodb 自增列现身重复值的来头

 

InnoDB 引擎的自增值,其实是保存在了内部存款和储蓄器里,并且到了 MySQL 8.0 版本后,才有了“自增值长久化”的力量,也就是才贯彻了“借使产生重启,表的自增值能够还原为 MySQL 重启前的值”,具体意况是:在 MySQL 5.7 及从前的本子,自增值保存在内部存款和储蓄器里,并不曾悠久化。每一回重启后,第3回展开表的时候,都会去找自增值的最大值 max 1 作为那些表当前的自增值。例如来讲,假若二个表当前数据行里最大的 id 是 10,AUTO_INCREMENT=11。这个时候,大家删除 id=10 的行,AUTO_INCREMENT 依然 11。但借使马上重启实例,重启后这些表的 AUTO_INCREMENT 就会变成 10。也等于说,MySQL 重启可能会订正一个表的 AUTO_INCREMENT 的值。在 MySQL 8.0 版本,将自增值的改变记录在了 redo log 中,重启的时候依靠 redo log 苏醒重启此前的值。

前段时间布置10条数据,再删除最后的几条,

  

重启MySQL服务后,然后大家插入一条记下,字段ID会从怎么着值开始吧? 如下所示,假设表的积攒引擎为InnoDB,那么插入的数额的自增字段值为6.

导致自增id不总是的意况只怕有:

INSERT INTO `bsession` (`aname`) values ('a'),('a'),('a'),('a'),('a'),('a'),('a'),('a'),('a'),('a’);

mysql> show create table t1G;
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=innodb AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

 

3.insert ... select语句批量申请自增id

DELETE FROM `bsession` where `id` in (8,9,10);

    建表时能够内定 AUTO_INCREMENT值,不钦定期默感到1.那几个值表示目前自增列的起头值大小,假诺新插入的多少尚未点名自增列的值,那么自增列的值即为那么些初步值。建表时那几个值会存储在.frm文件中。那么大家插入新的数量后,自增列的初叶值会变大,那一个变大的值会存回.frm文件呢?

 

3.自增id有上限吗?

图片 3

   对于innodb表,这么些值不会存回.frm中.而是存在内部存款和储蓄器中(dict_table_struct.autoinc)。那么又问,既然那些值未有存回.frm中,为何咱们每一回插入新的值后, show create table t1寻访AUTO_INCREMENT值是追随变化的。其实show create table t1并从未去读frm取AUTO_INCREMENT,值,而是一向从dict_table_struct.autoinc取得的(ha_innobase::update_create_info)。

图片 4

自增id是整型字段,大家常用int类型来定义拉长id,而int类型有上限 即进步id也可能有上限的。下表列举下 int 与 bigint 字段类型的约束:

依傍数据操作

   .frm中的AUTO_INCREMENT值,就算不是实时更新的,但在咱们在施行一些DDL重新建立表示照旧更新auto_increment值的。

 

类型

删去操作之后,表中的多少独有7条,最大的’id’ = 7。今后进展数据库重启,并再次插入10条数据。那时自增列是从8上马计数,如故从11从头计数呢?作者想许多个人都觉着会从11方始计数,生成新记录,但实际上情况会超越大家的料想,下边我们实在验证一下:

 

 

大小

图片 5

   知道了AUTO_INCREMENT是实时存款和储蓄内部存款和储蓄器中的,同有的时候间.frm中的AUTO_INCREMENT值时不实时的。那么,mysqld 重启后,从什么地方获得AUTO_INCREMENT呢? 内部存储器值分明是错失了,.frm中的AUTO_INCREMENT是不标准的(超级大或然比实际偏小).实际上mysql接受实践肖似select max(id卡塔尔国 1 from t1;方法来获得AUTO_INCREMENT。而这种措施就能促成自增id重复的来头。

接下去,我们创设三个MyISAM类型的测量检验表。如下所示:

范围

亲眼见到神迹

 

 

int 4字节 (-2147483648,2147483647) bigint 8字节 (-9223372036854775808,9223372036854775807) (0,18446744073709551615)

你一定会问了,那是干什么吗?

3 myisam也可以有其一难题呢

mysql> drop table if exists test;

Query OK, 0 rows affected (0.01 sec)

 

mysql> create table test(id int auto_increment  primary key, name varchar(32)) engine=MyISAM;

Query OK, 0 rows affected (0.02 sec)

 

mysql> 

 

insert into test(name)

select 'kkk1' from dual union all

select 'kkk2' from dual union all

select 'kkk3' from dual union all

select 'kkk4' from dual union all

select 'kkk5' from dual union all

select 'kkk6' from dual union all

select 'kkk7' from dual union all

select 'kkk8' from dual union all

select 'kkk9' from dual;

 

 

mysql> delete from test where id>=6;

Query OK, 4 rows affected (0.00 sec)

从上表能够看来:当自增字段使用int有号子类型时,最大可达2147483647即21亿多;使用int无符号类型时,最大可达4294967295即42亿多。当然bigint能表示的约束越来越大。

如出生龙活虎辙笔者也以为到很诡异,于是就理解MySql的InnoDB引擎是什么样管理自增列的:

    myisam是从未有过那个主题素材的。myisam表.frm文件也存AUTO_INCREMENT值,同innodb雷同,这一个值亦不是实时的。myisam会将以此值实时存款和储蓄在.MYI文件中(mi_state_info_write)。mysqld重起后会从.MYI中读取AUTO_INCREMENT值(mi_state_info_read卡塔尔(قطر‎。由此,myisam表重启是不会自然则然自增id重复的难题。

 

上边大家测量检验下当自增id达到最大时再一次插入数据会怎么着:

原因是InnoDB引擎对AUTO_INCREMENT流量计是寄放在到主内部存款和储蓄器中的,并不是硬盘。所以当重启后内部存款和储蓄器数据就抛弃了!

 

剔除了id>=6的笔录后,重启MySQL服务,如下所示,测量试验结果为id =10, 那么为何现身差别的四个结实吧?那个是因为InnoDB存款和储蓄引擎中,自增主键未有悠久化,而是放在内部存款和储蓄器中,关于自增主键的分配,是由InnoDB数据字典里面二个计数器来支配的,而该流速计只在内部存款和储蓄器中保障,并不社长久化到磁盘中。当数据库重启时,该计数器会通过SELECT MAX(ID卡塔尔(قطر‎ FROM TEST FOR UPDATE这样的SQL语句来起首化(分裂表对应分裂的SQL语句), 其实那是二个bug来着, 对应的链接地址为: 8.0 ,才将自增主键的流速計悠久化到redo log中。每一遍流量计产生退换,都会将其写入到redo log中。假如数据库发生重启,InnoDB会依据redo log中的流量计新闻来开头化其内部存款和储蓄器值。 而对应与MySIAM存款和储蓄引擎,自增主键的最大值存放在数据文件在那之中,每一回重启MySQL服务都不会影响其值变化。

create table t(id int unsigned auto_increment primary key) auto_increment=4294967295;insert into t values;// 成功插入一行 4294967295show create table t;/* CREATE TABLE `t`  unsigned NOT NULL AUTO_INCREMENT,PRIMARY KEY  ENGINE=InnoDB AUTO_INCREMENT=4294967295;*/insert into t values;//Duplicate entry '4294967295' for key 'PRIMARY'

我们来看官方文书档案:https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html,中的【InnoDB AUTO_INCREMENT Counter Initialization】生机勃勃节的亲力亲为表明:

4 innodb 自增列现身重复难点修复

 

从实验能够看来,当自增id到达最大时将不能扩张,第一个 insert 语句插入数据成功后,那几个表的AUTO_INCREMENT 未有改革,就变成了第二个insert 语句又得到同样的自增 id 值,再试图施行插入语句,报主键冲突错误。

图片 6

    myisam选择将AUTO_INCREMENT实时存款和储蓄在.MYI文件尾部中。实际上.MYI底部还或许会实时存别的音讯,约等于说写AUTO_INCREMENT只是个顺带的操作。其属性损耗能够忽视。InnoDB 表假诺要消除那么些标题,有三种方法。1)将auto_increment最大值悠久到frm文件中。2)将 auto_increment最大值持久到集中索引根页trx_id所在的岗位。第意气风发种艺术直接写文件质量消耗十分的大,那是风流浪漫额外的操作,实际不是以个顺带的操作。如是我们利用第二种方案。为啥选用仓储在聚焦索引根页页头trx_id。页头trx_id中存存款和储蓄trx_id,只对二级索引页和insert buf 页头有效(MVCC卡塔尔国.而聚焦索引根页页头trx_id这一个值是绝非选择的,始终维持开始值0.正巧这一个职位8个字节可寄放自增值的值。大家每回更新AUTO_INCREMENT值时,同期将这些值改正到集中索引根页页头trx_id的职位。 这一个写操作跟真正的多寡写操作一样,坚决守住write-ahead log原则,只不过这里只供给redo log ,而不必要undo log。因为我们无需回滚AUTO_INCREMENT的变通(即回滚后自增列值会保留,即使insert 回滚了,auto_increment值不会回滚)

 

4.关于自增列 大家该怎么保险?

MySQL官方网站表达

    因此,AUTO_INCREMENT值存储在聚焦索引根页trx_id所在的职位,实际上是对内部存款和储蓄器根页的更换和多了一条redo log(量超小),而这些redo log 的写入也是异步的,能够说是本来业务log的叁个附带操作。由此AUTO_INCREMENT值存款和储蓄在聚焦索引根页那个特性损耗是相当小的。

图片 7

维护方面注重提供以下2点提出:

可是那一个天性将在Mysql的下四个本子8.0中更换,自增流速计每一遍改换时,当前的最大自增流速計值将会被写入redo log中,并保留到各种检查点的 InnoDB引擎的私有系统表中,完毕自增流速计的悠久化,重启后会保持风姿洒脱致。

 

 

1.字段类型选拔方面:推荐使用int无符号类型,若可预测该表数据量将不胜大 可改用bigint无符号类型。

当服器在Crash中的复苏重启过程中,InnoDB使用存款和储蓄在系统字典表里的眼下最大自增值初阶化到内部存款和储蓄器,而且从最后一个检查点早前扫描Redo Log中写入的流速计值。要是Redo Log中的值超过内部存款和储蓄器中的计数器值,Redo Log中的值将会被采用。

5 修复后的属性相比

 

2.多关怀大表的自增值,幸免发生主键溢出处境。

关于三番伍回版本中对于 自增列的拍卖体制 请查看官方文书档案的亲力亲为表达,这里不在赘述。https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

  笔者们新添了全局参数innodb_autoinc_persistent  取值on/off; on 表示将AUTO_INCREMENT值实时存储在集中索引根页。off则应用原始办法只存储在内部存款和储蓄器。 

 

总结

 

自增列细节个性

上述就是那篇随笔的全部内容了,希望本文的内容对大家的学习恐怕办事富有自然的参谋学习价值,谢谢大家对台本之家的支撑。

./bin/sysbench --test=sysbench/tests/db/insert.lua --mysql-port=4001 --mysql-user=root --mysql-table-engine=innodb --mysql-db=sbtest --oltp-table-size=0 --oltp-tables-count=1 --num-threads=100 --mysql-socket=/u01/zy/sysbench/build5/run/mysql.sock  --max-time=7200 --max-requests run
set global innodb_autoinc_persistent=off;
tps: 22199 rt:2.25ms
set global innodb_autoinc_persistent=on;
tps: 22003 rt:2.27ms

 

能够观看质量损耗在%1以下。

1:SQL模式的NO_AUTO_VALUE_ON_ZERO值影响AUTO_INCREMENT列的行事。

 

 

6 改进

mysql> drop table if exists test;

Query OK, 0 rows affected (0.01 sec)

 

mysql> create table test(id int auto_increment primary key, name varchar(32));

Query OK, 0 rows affected (0.02 sec)

 

mysql> select @@sql_mode;

 ------------------------------------------------------------------------------------------------------------------------------------------- 

| @@sql_mode                                                                                                                                |

 ------------------------------------------------------------------------------------------------------------------------------------------- 

| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |

 ------------------------------------------------------------------------------------------------------------------------------------------- 

1 row in set (0.00 sec)

 

mysql> insert into test(id, name) value(0, 'kerry');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  1 | kerry |

 ---- ------- 

1 row in set (0.00 sec)

 

mysql> 

  新扩展参数innodb_autoinc_persistent_interval 用于控制长久化auto_increment值的频率。举个例子:innodb_autoinc_persistent_interval=100,auto_incrememt_increment=1时,即每九十八遍insert会调节长久化一遍auto_increment值。每一回长久的值为:当前值 innodb_autoinc_persistent_interval.

 

  

如上所示,假诺在SQL形式里面未有设置NO_AUTO_VALUE_ON_ZERO的话,那么在暗中认可设置下,自增列暗许日常从1上马自增,插入0大概null代表生成下二个自增加值。假使顾客愿意插入的值为0,而该列又是自拉长的,那么这一个选项就必需设置

测验结果如下

 

  innodb_autoinc_persistent=OFF

innodb_autoinc_persistent=ON

innodb_autoinc_persistent_interval=1

innodb_autoinc_persistent=ON

innodb_autoinc_persistent_interval=10

innodb_autoinc_persistent=ON

innodb_autoinc_persistent_interval=100

TPS 22199 22003

22069

22209

RT(ms)

2.25

2.27 2.26 2.25
mysql> SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";

Query OK, 0 rows affected (0.00 sec)

 

mysql> insert into test(id, name) value(0, 'kerry');

Query OK, 1 row affected (0.01 sec)

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  0 | kerry |

|  1 | kerry |

 ---- ------- 

2 rows in set (0.00 sec)

 

mysql> 

 

 

留心:要是大家应用须要敞开innodb_autoinc_persistent,应该在参数文件中钦定,

 

innodb_autoinc_persistent= on

 如果这样指定set global innodb_autoinc_persistent=on;重启后将不会从聚集索引根页读取auto_increment最大值. 

 

多少个疑问:

2:纵然把叁个NULL值插入到三个AUTO_INCREMENT数据列里去,MySQL将自动生成下三个行列编号。如下所示,这一个语法对于领会SQL Server中自增字段的人来来看,大约就是出乎意料的业务。

1 对此innodb和 myisam 存款和储蓄引擎,.frm中的AUTO_INCREMENT是剩下的。别的存款和储蓄引擎未有色金属商讨所究,不清楚有未有用途。

 

2 innodb表,重启通过select max(id卡塔尔国 1 from t1收获AUTO_INCREMENT值,假使id上有索引那么这几个讲话使用索引查找就一点也不慢。那么,那几个能够分解mysql 为何供给自增列必得含有在目录中的原因。 若无一些名索引,则报如下错误,

mysql> drop table if exists test;

Query OK, 0 rows affected (0.03 sec)

 

mysql> create table test(id int auto_increment primary key, name varchar(32));

Query OK, 0 rows affected (0.05 sec)

 

mysql> insert into test(id , name) value(null, 'kerry');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  1 | kerry |

 ---- ------- 

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

 

而myisam表竟然也会有其风度翩翩供给,以为是多余的。

 

 

 

附:

3:获取当前自增列的值

innodb_autoinc_lock_mode 这些参数首要消除自增列主备复制难题的,用于调整自增列值接二连三性的。与本文毫无干系,详细能够参见这里

 

innodb 自增列现身重复值的题材先从难点伊始,再次出现下这一个bug use test; drop table t1; create table t1(id int auto_increment, a int , primary key (id)) engine...

    获取当前自增列的值,能够应用 LAST_INSERT_ID函数,注意,那几个是四个连串函数,可获取自增列自动生成的终极八个值。但该函数只与服务器的本次对话进程中生成的值有关。如若在与服务器的这次对话中未有生成AUTO_INCREMENT值,则该函数重回0

 

mysql> select last_insert_id();

 ------------------ 

| last_insert_id() |

 ------------------ 

|                1 |

 ------------------ 

1 row in set (0.00 sec)

 

mysql> insert into test(name) value('jimmy');

Query OK, 1 row affected (0.00 sec)

 

mysql> select last_insert_id();

 ------------------ 

| last_insert_id() |

 ------------------ 

|                2 |

 ------------------ 

1 row in set (0.00 sec)

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  1 | kerry |

|  2 | jimmy |

 ---- ------- 

2 rows in set (0.00 sec)

 

黄金时代旦要博得自增列的下贰个值,那么能够采纳show create table tablename查看。如下截图所示

 

图片 8

 

 

4:自增列跳号

 

MySQL中,自增字段可以跳号:能够插入一条钦命自增列值的记录(就算插入的值超过自增列的最大值),如下所示,当前自增列最大值为1,作者插入三个200的值,然后就能以200为根底继续自增,而且笔者还足以继续插入ID=100的记录,不必要任何附加设置。

 

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  1 | kerry |

 ---- ------- 

1 row in set (0.00 sec)

 

mysql> insert into test value(200, 'test');

Query OK, 1 row affected (0.01 sec)

 

mysql> select * from test;

 ----- ------- 

| id  | name  |

 ----- ------- 

|   1 | kerry |

| 200 | test  |

 ----- ------- 

2 rows in set (0.00 sec)

 

mysql> insert into test(name) value('test2');

Query OK, 1 row affected (0.01 sec)

 

mysql> select * from test;

 ----- ------- 

| id  | name  |

 ----- ------- 

|   1 | kerry |

| 200 | test  |

| 201 | test2 |

 ----- ------- 

3 rows in set (0.00 sec)

 

mysql> 

mysql> insert into test(id, name) value(100, 'ken');

Query OK, 1 row affected (0.01 sec)

 

mysql> select * from test;

 ----- ------- 

| id  | name  |

 ----- ------- 

|   1 | kerry |

| 100 | ken   |

| 200 | test  |

| 201 | test2 |

 ----- ------- 

4 rows in set (0.00 sec)

 

 

除此以外叁个是关于自增列逻辑跳号难点,在二个事务里面,使用蒙受事情回滚,自增列就能够跳号,如下所示,id从201 跳到 203了。

 

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

 

mysql> insert into test(name) value('kkk');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

 ----- ------- 

| id  | name  |

 ----- ------- 

|   1 | kerry |

| 100 | ken   |

| 200 | test  |

| 201 | test2 |

| 202 | kkk   |

 ----- ------- 

5 rows in set (0.00 sec)

 

mysql> rollback;

Query OK, 0 rows affected (0.00 sec)

 

mysql> insert into test(name) value('kkk');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

 ----- ------- 

| id  | name  |

 ----- ------- 

|   1 | kerry |

| 100 | ken   |

| 200 | test  |

| 201 | test2 |

| 203 | kkk   |

 ----- ------- 

5 rows in set (0.00 sec)

 

本来,无论MySQL如故任何关系型数据库,都会蒙受这种逻辑跳号的图景,举例ORACLE的行列也会存在这里种逻辑跳号难题。为抓实自增列的生功能率,都将生成自增值的操作设计为非事务性操作,表现为当工作回滚时,事务中生成的自增值不会被回滚。

 

5:truncate table操作会挑起自增列从头开端计数

 

mysql> truncate table test;

Query OK, 0 rows affected (0.01 sec)

 

mysql> insert into test(name) value('kerry');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  1 | kerry |

 ---- ------- 

1 row in set (0.00 sec)

 

mysql> 

 

6:修改AUTO_INCREMENT的值来修正自增伊始值。

 

mysql> select * from test;

 ---- ------- 

| id | name  |

 ---- ------- 

|  1 | kerry |

 ---- ------- 

1 row in set (0.00 sec)

 

mysql> alter table test auto_increment=100;

Query OK, 0 rows affected (0.00 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> insert into test(name) value('k3');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

 ----- ------- 

| id  | name  |

 ----- ------- 

|   1 | kerry |

| 100 | k3    |

 ----- ------- 

2 rows in set (0.00 sec)

 

本来MySQL还应该有部分连锁知识点,这里未有做总结,首借使从未遇到过有关情状。以往遇到了再做计算,别的一面,写本领文章,很难左右逢源,那样太耗费时间也太累人了!

 

 

 

参谋资料:

 

本文由星彩网app下载发布于星彩彩票app下载,转载请注明出处:连锁知识点总括,自增列重复值相关主题材料

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。