1.InnoDB存储引擎的数据结构必须需要一个主键才可以组织起来,如果用户使用InnoDB存储引擎建立表的时候,没有指定主键,则Mysql会自动的帮你找到一个合适的唯一索引作为主键,若找不到符合条件唯一索引条件的字段时,会生成类似于ROW_ID的虚拟列充当该InnoDB表的主键;
2.整型的存储比字段类型要小,而且应为是InnoDB存储引擎使用的是B+Tree数据结构,在进行查询数据是需要对每个元素进行比较,而整型的对比效率是高于其他数据结构的,字符串等。
使用自增主键作为InnoDB表的主键会存在一个问题?
Mysql中innodb_page_size = 16kb,选择BIGINT作为主键占用8b,地址也占8b 16kb/(8+8)b = 1000个元素,也就是1001阶的B+Tree树结构,那么每次新增新增一条记录都是在最右边的数据中插入新的数据,当插入1001个元素时,发生列变生成一个新的根节点,而此时的左子节点包含的元素个数是(1001-1)/2=500,此后不会再发生改变,因为每次插入的数据都是在整棵树的最右侧,以此类推会发现会有近乎一半的节点空间是浪费的。下图是以7阶的B+Tree示例:
B+树索引的分裂:
传统B+树页面分裂操做分析
- 50%分裂策略的优点:
- 分裂以后,两个页面的空间利用率是同样的;若是新的插入是随机在两个页面中挑选进行,那么下一次分裂的操做就会更晚触发;
- 50%分裂策略的劣势:
- 空间利用率不高:按照传统50%的页面分裂策略,索引页面的空间利用率在50%左右;
- 分裂频率较大:针对如上所示的递增插入(递减插入),每新插入两条记录,就会致使最右的叶页面再次发生分裂
B+树分裂操做的优化
因为传统50%分裂的策略,有不足之处,所以,目前全部的关系型数据库,包括Oracle/InnoDB/PostgreSQL
新的分裂策略,在插入元素时且超出当前页的最大容量,不移动原有页面的任何记录,只是将新插入的记录写到新页面之中
好处:
- 索引分裂的代价小:不须要移动记录;
- 索引分裂的几率下降:若是接下来的插入,仍旧是递增插入,那么须要插入4条记录,才能再次引发页面的分裂。相对于50%分裂策略,分裂的几率下降了一半;
- 索引页面的空间利用率提升:新的分裂策略,可以保证分裂前的页面,仍旧保持100%的利用率,提升了索引的空间利用率;
在InnoDB的实现中,为每一个索引页面维护了一个上次插入的位置,以及上次的插入是递增/递减的标识。根据这些信息,InnoDB可以判断出新插入到页面中的记录,是否仍旧满足递增/递减的约束,若满足约束,则采用优化后的分裂策略;若不满足约束,则退回到50%的分裂策略。