InnoDB为什么要使用auto_Increment

在Mysql表设计中,通常会使用一个与业务无关的自增列做为主键。
这是因为Mysql默认使用B-Tree索引,你可以简单理解为“排好序的快速查找结构”。
如下是一个B-Tree的结构图,2层B+树,每个页面的扇出为4;并有1到6五条记录;上层记录保存每个页面的最小值;每个页面通过双向链表链接起来的;
当你插入记录7时,就会发生页面分裂:

如上可见分裂产生了记录移动,但是优化后的分裂操作无需记录移动:

在InnoDB的实现中,为每个索引页面维护了一个上次插入的位置,以及上次的插入是递增/递减的标识。根据这些信息,InnoDB能够判断出新插入到页面中的记录,是否仍旧满足递增/递减的约束,若满足约束,则采用优化后的分裂策略;
所以建议使用一列顺序递增的 ID 来作为主键,但不必是数据库的autoincrement字段,只要满足顺序增加即可 。很多大型应用会有顺序递增的ID生成器。
测试如下:


  1. CREATE TABLE `table1` (
  2. `id` int(10) NOT NULL AUTO_INCREMENT,
  3. `text` varchar(255) NOT NULL,
  4. PRIMARY KEY (`id`)
  5. ) ENGINE=InnoDB AUTO_INCREMENT=200001 DEFAULT CHARSET=utf8
  6. CREATE TABLE `table2` (
  7. `id` int(10) NOT NULL,
  8. `text` varchar(255) NOT NULL,
  9. KEY `id` (`id`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

脚本如下:


  1. $link = mysql_connect(‘127.0.0.1‘, ‘root‘, ‘mckee‘);
  2. mysql_select_db(‘test‘, $link);
  3. $count = 200000;
  4. $table1_data = range(1, $count);
  5. $text = ‘just test!just test!just test!just test!just test!‘;
  6. $time1 = get_time();
  7. foreach ($table1_data as $row) {
  8. $id = rand(1,100000000);
  9. mysql_query("insert into table1(text) values (‘{$text}‘)");
  10. }
  11. $time2 = get_time();
  12. foreach ($table1_data as $row) {
  13. $id = rand(1,100000000);
  14. mysql_query("insert into table2(id, text) values ({$id}, ‘{$text}‘)");
  15. }
  16. $time3 = get_time();
  17. echo ‘tabe1 insert execute time:‘ . ($time2 - $time1) . PHP_EOL;
  18. echo ‘tabe2 insert execute time:‘ . ($time3 - $time2) . PHP_EOL;
  19. function get_time()
  20. {
  21. list( $usec , $sec ) = explode ( " " , microtime ());
  22. return ((float) $usec + (float) $sec );
  23. }
时间: 2024-10-14 12:32:47

InnoDB为什么要使用auto_Increment的相关文章

Mysql中自增字段(AUTO_INCREMENT)的一些常识

Mysql中自增字段(AUTO_INCREMENT)的一些常识 在系统开发过程中,我们经常要用到唯一编号.使用过mysql的人都应该知道,mysql有一个定义列为自增的属性:AUTO_INCREMENT. 指定了AUTO_INCREMENT的列必须要建索引,不然会报错,索引可以为主键索引,当然也可以为非主键索引.(不一定要做主键) 1 2 3 mysql> create table t4 (id int auto_increment); ERROR 1075 (42000): Incorrect

MySQL 5.6 Reference Manual-14.6 InnoDB Table Management

14.6 InnoDB Table Management 14.6.1 Creating InnoDB Tables 14.6.2 Moving or Copying InnoDB Tables to Another Machine 14.6.3 Grouping DML Operations with Transactions 14.6.4 Converting Tables from MyISAM to InnoDB 14.6.5 AUTO_INCREMENT Handling in Inn

面试常问之——Mysql引擎中MyISAM和InnoDB的区别有哪些?

简单的概括一下 InnoDB:支持事务处理等不加锁读取支持外键支持行锁不支持FULLTEXT类型的索引不保存表的具体行数,扫描表来计算有多少行DELETE 表时,是一行一行的删除InnoDB 把数据和索引存放在表空间里面跨平台可直接拷贝使用InnoDB中必须包含AUTO_INCREMENT类型字段的索引表格很难被压缩 MyISAM:不支持事务,回滚将造成不完全回滚,不具有原子性不支持外键支持全文搜索保存表的具体行数,不带where时,直接返回保存的行数DELETE 表时,先drop表,然后重建表

MySQL使用AUTO_INCREMENT列的表注意事项之update自增列篇

1. 说明 (1)对于MyISAM表,如果用UPDATE更新自增列,如果列值与已有的值重复,则会出错:如果大于已有的最大值,则会自动更新表的AUTO_INCREMENT,操作是安全的. (2)对于innodb表,update auto_increment字段,如果列值与已有的值重复,则会出错:如果大于已有的最大值,可能会引入一个坑,会造成编号重复错误,插入数据失败的情况,可见在update自增列值是要注意. 环境描述:RHEL 6.4 x86_64 + MySQL 5.6.19 blog地址:h

zbb20180927 MySQL MyISAM InnoDB区别

MySQL MyISAM InnoDB区别 InnoDB:支持事务处理等不加锁读取支持外键支持行锁不支持FULLTEXT类型的索引不保存表的具体行数,扫描表来计算有多少行DELETE 表时,是一行一行的删除InnoDB 把数据和索引存放在表空间里面跨平台可直接拷贝使用InnoDB中必须包含AUTO_INCREMENT类型字段的索引表格很难被压缩 MyISAM:不支持事务,回滚将造成不完全回滚,不具有原子性不支持外键不支持外键支持全文搜索保存表的具体行数,不带where时,直接返回保存的行数DEL

MySQL之存储引擎InnoDB和MyISAM的区别及底层详解(转)

题外话:中华文化博大进深,从学Java到数据库,无一不体现出同一组件鱼和熊掌不可兼得的要义.自然,编程中安全和效率也很难同时做到完美,这一次InnoDB和MyISAM又让我大开眼界. 好了,Talk is cheap,show you the code: 测试环境:Mysql 5.7.20-log,IDEA 2018 首先创建两张表: testinnodb,testmyisam,sql如下: 1.同时大批量插入数据(百万级,million),小编采用了存储过程,代码及测试结果如下: 下面代码在I

php省市联动实现

设计模式:ajax实现,数据库格式:id,name,parent_id 数据库: CREATE TABLE IF NOT EXISTS `city` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(30) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREME

Android新闻案例clientserver达到,完全自己的新闻节目平台

一.建设新闻资料库 例如,下面的脚本代码:(正在使用mysql5.0 数据库) SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- Database: `newsdemo` -- 表的结构 `news` CREATE TABLE IF NOT EXISTS `news` ( `id` int(10) NOT NULL AUTO_INCREMENT, `title` text NOT

mysql分区功能详细介绍,以及实例

一.什么是数据库分区 下面来说一下什么是数据库分区,以mysql为例.mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的.如果一张表的数据量太大的话,那么myd,myi就会变的很大,查找数据就会变的很慢,这个时候我们可以利用mysql的分区功能,在物理上将这一张表对应的三个文件,分割成许多个小块,这样呢,我们查找