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已經是不連續了。
原因:
參數innodb_autoinc_lock_mode = 1時,每次會“預申請”多余的id(handler.cc:compute_next_insert_id),而insert執行完成后,會特別將這些預留的id空出,就是特意將預申請后的當前最大id回寫到表中(dict0dict.c:dict_table_autoinc_update_if_greater)。
這個預留的策略是“不夠時多申請幾個”, 實際執行中是分步申請。至于申請幾個,是由當時“已經插入了幾條數據N”決定的。當auto_increment_offset=1時,預申請的個數是 N-1。
所以會發現:插入只有1行時,你看不到這個現象,并不預申請。而當有N>1行時,則需要。多申請的數目為N-1,因此執行后的自增值為:1+N+(N-1)。測試中為10行,則:1+10+9 =20,和 16不一致?原因是:當插入8行的時候,表的AUTO_INCREMENT已經是16了,所以插入10行時,id已經在第8行時預留了,所以直接使用,自增值仍為16。所以當插入8行的時候,多申請了7個id,即:9,10,11,12,13,14,15。按照例子中的方法插入8~15行,表的AUTO_INCREMENT始終是16
驗證:
插入16行:猜測 預申請的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。所以當插入16行的時候,多申請了17,18,19...,31 。
所以導致ID不連續的原因是因為innodb_autoinc_lock_mode = 1時,會多申請id。好處是:一次性分配足夠的auto_increment id,只會將整個分配的過程鎖住。
5.1.22前 默認: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獲得自增字段下一個值
標簽:mysql???int???configure???sel???limit???section???not???互斥量???好處
本條技術文章來源于互聯網,如果無意侵犯您的權益請點擊此處反饋版權投訴
本文系統來源:http://www.cnblogs.com/micro-chen/p/6942151.html
總結
以上是生活随笔為你收集整理的mysql 主键 下一个值_INNODB自增主键的一些问题 vs mysql获得自增字段下一个值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ext springmvc mysql_
- 下一篇: mysql子查询sysdate_Orac