既然这块知识不清楚,那就自己回去实践吧。首先创建一个最简单的表,只包含一个自增id,插入一条数据。创建表t0(idintunsignedauto_increment主键);插入t0值(空);通过show命令showcreatetablet0;查看表情况CREATETABLE`t0`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=2DEFAULTCHARSET=utf8可以发现AUTO_INCREMENT已经自动变为2,距离用完还很远。我们可以计算出当前声明的最大自增ID,因为这里定义的是intunsigned,所以可以达到2的32次方-1=4294967295这里有个小技巧,可以直接声明初始值AUTO_INCREMENTwhencreatetablet1(idintunsignedauto_incrementprimarykey)auto_increment=4294967295;insertintot1values(null);同样,通过show命令查看t1的表结构CREATETABLE`t1`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=4294967295DEFAULTCHARSET=utf8即可发现AUTO_INCREMENT变成了4294967295,再次插入数据时,得到如下异常结果17:28:03insertintot1values(null)ErrorCode:1062.Duplicateentry'4294967295'forkey'PRIMARY'0.00054sec显示再次插入时,使用的自增ID还是4294967295,报主键冲突错误。4294967295,这个数已经可以应付大部分场景了,如果你的服务会频繁的插入删除数据,还是有跑完的风险,建议使用bigintunsigned,这个数比较大。然而,还有另一种情况。建表时没有显示主键怎么办?如果是这种情况,InnoDB会自动为你创建一个长度为6字节的不可见的row_id,InnoDB维护一个全局的dictsys.row_id被创建,所以主键未定义的表共享这个row_id。每插入一条数据,将全局row_id作为主键id,然后将全局row_id加1。全局row_id在代码实现类型中使用了bigintunsigned,但实际上只保留了6个字节用于row_id,这样设计会有一个问题:如果全局row_id一直上升,直到2的48次方-1,那么此时+1,row_id的低48位全为0。结果,当一个新行插入数据,得到的row_id为0,有主键冲突的可能。所以,为了避免这个隐患,每张表都需要有一个主键。
