当前位置: 首页 > 科技观察

自增ID插入后发生了什么?

时间:2023-03-19 13:35:33 科技观察

《??MySQL自增ID,居然大部分人都搞错了????》中的作业题,有小部分人答对了,但不能把原理说清楚。今天简单说一下作业题中的答案和相关知识点。作业题是这样的:droptablet1;createtablet1(idintnotnullauto_increment,namevarchar(10)unique,countintdefault0,primarykey(id),index(name))engine=innodb;insertintot1(id,name)values(1,"神剑");insertintot1(id,name)values(111,"111"),(NULL,"abc"),(222,"222"),(NULL,"xyz");执行后ids为:(1,'shenjian')(111,'111')//允许指定值(112,'abc')//忽略NULL,从最大值开始增加(222,'222')//允许指定值(223,'xyz')//忽略NULL,从最大值开始增加如果继续执行下面语句:insertintot1(name)values("shenjian"),("aaa"),("bbb")重复键更新计数=100;请问:会不会执行报错?如果报错,为什么?如果没有报错,得到的数据是什么?知其然,知其所以然。先系统的说一下相关知识点,InnoDB自增键,插入,如何插入,插入后发生了什么?画外音:本文以MySQL5.6和InnoDB引擎为例。什么是插入?MySQL有一系列可以向数据库中添加数据的语句,称为insert-like语句。不同的插入方式对自增键有不同的影响。画外音:自增键指的是auto_increment,大家应该会经常用到。有多少种插入方式?说的更详细一点,一般来说,插入方式分为三类:simpleinsert,bulkinsert,mixed-modeinsert,什么是simpleinsert?普通的插入/替换语句,无论是单次插入还是多次插入,都是简单的插入。画外音:不包含递归子查询;不包含插入...重复键更新...;比如作业题中的数据表:insertintot1(id,name)values(1,"shenjian");insertintot1(name)values("zhangsan"),("lisi"),("万维网”);都是简单的插入。简单插入的特点是可以预先知道要插入的行数。因此,这种类型的插入在处理自增键时是最容易的。画外音:很容易保证自增键的连续性。什么是批量插入(bulkinsert)?相对于简单插入,插入时插入的行数是未知的,属于批量插入。比如作业题中的数据表:insertintot1(name)selectnamefromt2;另外像:replace...select...load数据都是批量插入的。由于无法事先知道要插入多少行,所以在处理自增列时,每插入一行都会分配一个新的自增值。画外音,官网原文是:InnoDB随着每一行的处理,一次一个地为AUTO_INCREMENT列赋新值。这里的潜台词是,当批量插入事务并发时,“有可能”同一事务的自增键不连续。什么是混合模式插入?比如作业题中的SQL:insertintot1(id,name)values(111,"111"),(NULL,"abc"),(222,"222"),(NULL,"xyz");有些行插入时指定了自增键,不需要数据库生成;有些行插入时没有自动递增键(NULL),这需要数据库生成。画外音:具体走哪条分支,只有真正执行了才知道。并且,作业题中的如下SQL:insertintot1(name)values("shenjian"),("aaa"),("bbb")onduplicatekeyupdatecount=100;有些行插入实际上是修改,有些行插入实际上只是插入。画外音:具体走哪条分支,要等到实际执行时才知道。insert...onduplicatekeyupdate...这种情况最为复杂,可能会导致系统生成的自增值在update阶段无法使用。画外音,官网原文是:一个INSERT后跟一个UPDATE,其中AUTO_INCREMENT列的分配值在update阶段可能会用到也可能不会用到。说了这么多,对于作业题,ids为:(1,'shenjian')(111,'111')//允许指定值(112,'abc')//忽略NULL,自增maximumvalue(222,'222')//允许指定值(223,'xyz')//忽略NULL,从最大值开始增加如果继续执行下面的语句,答案会是什么?insertintot1(name)values("shenjian"),("aaa"),("bbb")重复键更新计数=100;答案如下:For:insert("shenjian"),("aaa"),("bbb")系统认为是批量插入,所以生成了三个连续的自增键224、225、226.Next:onduplicatekeyupdate...结果出现一行插入冲突,其实是更新,导致224的自增值没有用,所以出现“不连续”的奇怪现象自增值”出现。