mysql 主键 下一个值_INNODB自增主键的一些问题 vs mysql获得自增字段下一个值
root@localhost : test 04:23:28>show variables like ‘innodb_autoinc_lock_mode‘;
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_autoinc_lock_mode | 1 |
+--------------------------+-------+
1 row in set (0.00 sec)
root@localhost : test 04:23:31>create table tmp_auto_inc(id int auto_increment primary key,talkid int)engine = innodb default charset gbk;
Query OK, 0 rows affected (0.16 sec)
root@localhost : test 04:23:35>insert into tmp_auto_inc(talkid) select talkId from talk_dialog limit 10;
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
root@localhost : test 04:23:39>show create table tmp_auto_inc\G;
*************************** 1. row ***************************
Table: tmp_auto_inc
Create Table: CREATE TABLE `tmp_auto_inc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`talkid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
插入10條記錄,但表的AUTO_INCREMENT=16,再插入一條的時候,表的自增id已經(jīng)是不連續(xù)了。
原因:
參數(shù)innodb_autoinc_lock_mode = 1時,每次會“預(yù)申請”多余的id(handler.cc:compute_next_insert_id),而insert執(zhí)行完成后,會特別將這些預(yù)留的id空出,就是特意將預(yù)申請后的當(dāng)前最大id回寫到表中(dict0dict.c:dict_table_autoinc_update_if_greater)。
這個預(yù)留的策略是“不夠時多申請幾個”, 實際執(zhí)行中是分步申請。至于申請幾個,是由當(dāng)時“已經(jīng)插入了幾條數(shù)據(jù)N”決定的。當(dāng)auto_increment_offset=1時,預(yù)申請的個數(shù)是 N-1。
所以會發(fā)現(xiàn):插入只有1行時,你看不到這個現(xiàn)象,并不預(yù)申請。而當(dāng)有N>1行時,則需要。多申請的數(shù)目為N-1,因此執(zhí)行后的自增值為:1+N+(N-1)。測試中為10行,則:1+10+9 =20,和 16不一致?原因是:當(dāng)插入8行的時候,表的AUTO_INCREMENT已經(jīng)是16了,所以插入10行時,id已經(jīng)在第8行時預(yù)留了,所以直接使用,自增值仍為16。所以當(dāng)插入8行的時候,多申請了7個id,即:9,10,11,12,13,14,15。按照例子中的方法插入8~15行,表的AUTO_INCREMENT始終是16
驗證:
插入16行:猜測 預(yù)申請的id:1+16+(16-1)= 32,即:AUTO_INCREMENT=32
root@localhost : test 04:55:45>create table tmp_auto_inc(id int auto_increment primary key,talkid int)engine = innodb default charset gbk;
Query OK, 0 rows affected (0.17 sec)
root@localhost : test 04:55:48>insert into tmp_auto_inc(talkid) select talkId from sns_talk_dialog limit 16;
Query OK, 16 rows affected (0.00 sec)
Records: 16 Duplicates: 0 Warnings: 0
root@localhost : test 04:55:50>show create table tmp_auto_inc\G;
*************************** 1. row ***************************
Table: tmp_auto_inc
Create Table: CREATE TABLE `tmp_auto_inc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`talkid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
和猜測的一樣,自增id到了32。所以當(dāng)插入16行的時候,多申請了17,18,19...,31 。
所以導(dǎo)致ID不連續(xù)的原因是因為innodb_autoinc_lock_mode = 1時,會多申請id。好處是:一次性分配足夠的auto_increment id,只會將整個分配的過程鎖住。
5.1.22前 默認(rèn):innodb_autoinc_lock_mode =?0
root@localhost : test 04:25:12>show variables like ‘innodb_autoinc_lock_mode‘;
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_autoinc_lock_mode | 0 |
+--------------------------+-------+
1 row in set (0.00 sec)
root@localhost : test 04:25:15>create table tmp_auto_inc(id int auto_increment primary key,talkid int)engine = innodb default charset gbk;
Query OK, 0 rows affected (0.17 sec)
root@localhost : test 04:25:17>insert into tmp_auto_inc(talkid) select talkId from talk_dialog limit 10;
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
root@localhost : test 04:25:21>show create table tmp_auto_inc\G;
*************************** 1. row ***************************
Table: tmp_auto_inc
Create Table: CREATE TABLE `tmp_auto_inc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`talkid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
INNODB自增主鍵的一些問題 vs mysql獲得自增字段下一個值
標(biāo)簽:mysql???int???configure???sel???limit???section???not???互斥量???好處
本條技術(shù)文章來源于互聯(lián)網(wǎng),如果無意侵犯您的權(quán)益請點擊此處反饋版權(quán)投訴
本文系統(tǒng)來源:http://www.cnblogs.com/micro-chen/p/6942151.html
總結(jié)
以上是生活随笔為你收集整理的mysql 主键 下一个值_INNODB自增主键的一些问题 vs mysql获得自增字段下一个值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ext springmvc mysql_
- 下一篇: mysql子查询sysdate_Orac