InnoDB为什么要使用auto_Increment
在Mysql表设计中,通常会使用一个与业务无关的自增列做为主键。
这是因为Mysql默认使用B-Tree索引,你可以简单理解为“排好序的快速查找结构”。
如下是一个B-Tree的结构图,2层B+树,每个页面的扇出为4;并有1到6五条记录;上层记录保存每个页面的最小值;每个页面通过双向链表链接起来的;
当你插入记录7时,就会发生页面分裂:
如上可见分裂产生了记录移动,但是优化后的分裂操作无需记录移动:
在InnoDB的实现中,为每个索引页面维护了一个上次插入的位置,以及上次的插入是递增/递减的标识。根据这些信息,InnoDB能够判断出新插入到页面中的记录,是否仍旧满足递增/递减的约束,若满足约束,则采用优化后的分裂策略;
所以建议使用一列顺序递增的 ID 来作为主键,但不必是数据库的autoincrement字段,只要满足顺序增加即可 。很多大型应用会有顺序递增的ID生成器。
测试如下:
- CREATE TABLE `table1` (
- `id` int(10) NOT NULL AUTO_INCREMENT,
- `text` varchar(255) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=200001 DEFAULT CHARSET=utf8
- CREATE TABLE `table2` (
- `id` int(10) NOT NULL,
- `text` varchar(255) NOT NULL,
- KEY `id` (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8
脚本如下:
- $link = mysql_connect('127.0.0.1', 'root', 'mckee');
- mysql_select_db('test', $link);
- $count = 200000;
- $table1_data = range(1, $count);
- $text = 'just test!just test!just test!just test!just test!';
- $time1 = get_time();
- foreach ($table1_data as $row) {
- $id = rand(1,100000000);
- mysql_query("insert into table1(text) values ('{$text}')");
- }
- $time2 = get_time();
- foreach ($table1_data as $row) {
- $id = rand(1,100000000);
- mysql_query("insert into table2(id, text) values ({$id}, '{$text}')");
- }
- $time3 = get_time();
- echo 'tabe1 insert execute time:' . ($time2 - $time1) . PHP_EOL;
- echo 'tabe2 insert execute time:' . ($time3 - $time2) . PHP_EOL;
- function get_time()
- {
- list( $usec , $sec ) = explode ( " " , microtime ());
- return ((float) $usec + (float) $sec );
- }
InnoDB为什么要使用auto_Increment的更多相关文章
- Mysql引擎中MyISAM和InnoDB的区别有哪些?
简单的概括一下 InnoDB:支持事务处理等不加锁读取支持外键支持行锁不支持FULLTEXT类型的索引不保存表的具体行数,扫描表来计算有多少行DELETE 表时,是一行一行的删除InnoDB 把数据和 ...
- MySQL中MyISAM与InnoDB区别
原文:https://blog.csdn.net/frycn/article/details/70158313?utm_source=copy InnoDB:支持事务处理等不加锁读取支持外键支持行锁不 ...
- MySQL中MyISAM与InnoDB区别及选择(转)
InnoDB: 支持事务处理等 不加锁读取 支持外键 支持行锁 不支持FULLTEXT类型的索引 不保存表的具体行数,扫描表来计算有多少行 DELETE 表时,是一行一行的删除 InnoDB 把数据和 ...
- MySQL中MyISAM与InnoDB区别及选择
InnoDB:支持事务处理等不加锁读取支持外键支持行锁不支持FULLTEXT类型的索引不保存表的具体行数,扫描表来计算有多少行DELETE 表时,是一行一行的删除InnoDB 把数据和索引存放在表空间 ...
- MySQL使用AUTO_INCREMENT列的表注意事项之update自增列篇
1)对于MyISAM表,如果用UPDATE更新自增列,如果列值与已有的值重复,则会出错:如果大于已有的最大值,则会自动更新表的AUTO_INCREMENT,操作是安全的. (2)对于innodb表,u ...
- MyISAM和InnoDB区别 及选择
MySQL默认采用的是MyISAM. MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以 ...
- MySQL中MyISAM与InnoDB区别及选择,mysql添加外键
InnoDB:支持事务处理等不加锁读取支持外键支持行锁不支持FULLTEXT类型的索引不保存表的具体行数,扫描表来计算有多少行DELETE 表时,是一行一行的删除InnoDB 把数据和索引存放在表空间 ...
- mysql innodb myisam 比较
InnoDB: 支持事务处理等 不加锁读取 支持外键 支持行锁 不支持FULLTEXT类型的索引 不保存表的具体行数,扫描表来计算有多少行 DELETE 表时,是一行一行的删除 InnoDB 把数据和 ...
- MySql中存储引擎MyISAM与InnoDB区别于选择
InnoDB: 支持事务处理等 不加锁读取 支持外键 支持行锁 不支持FULLTEXT类型的索引 不保存表的具体行数,扫描表来计算有多少行 DELETE 表时,是一行一行的删除 InnoDB 把数据和 ...
随机推荐
- mac OS(OS X)的OI编译环境配置指南
编译环境:gdb+Atom 如何安装gdb: http://logic0.blog.163.com/blog/static/1889281462014183271283/ Atom下载地址: ht ...
- php 读取excel表格中的内容
<?php /** * excel表格内容在网页中显示 * * 首先需要下载PHPExcel 工具包 * 网址: http://phpexcel.codeplex.com/releases/vi ...
- zabbix 安装
php+nginx+mysql+zabbix 官方https://www.zabbix.com/documentation/3.0/manual/installation/install 1.安装依赖 ...
- CentOS 6.x安装Metasploit
现在开始安装Metasploit框架,前面的包安装成功之后,我们需要再安装一些Metasploit依赖的Ruby库,命令如下: gem install wirble pg sqlite3 msgpac ...
- thinkphp删除
$result = M('content')->where('id>0')->delete $result =M('content')->where(array('id'=&g ...
- linux远程登录(Telnet、SSH)
系统:RHEL 5.5 64位,使用CentOS的yum源并作更新处理 参考书目<Linux兵书>/电子工业出版社/刘丽霞,细节之处稍有变动. 一.Telnet(远程登录推荐SSH) 1. ...
- Python之路【第四篇】:模块
什么是模块: 模块就是一个功能的集合. 模块就和乐高积木差不多,你用这些模块组合出一个模型,然后也可以用这个模块加上其他的模块组合成一个新的模型 模块的种类: 1.内置模块(python自带的比如os ...
- Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件
第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...
- text-indent:2em详解
text-indent:2em; 解释一下:text的意思是文本,indent在计算机英语中意思是缩进,至于后面的2em意思就是2个相对单位: em又是什么单位? em这个单位的意思就是文字的高度,1 ...
- Autolayout学习(1)-了解Autoreszing
1. 为什么要有Autoreszing? 在Xcode6之前,如果定义了下面的一个布局,同时运行在不同尺寸设备下会显示不同的效果. (iPhone6-4.7inch) (iPhone5s-4inch) ...