二、为什么要创建一个自增整型主键?
前言
是不是经常听到有人说,建表时候必须建一个自增的主键ID!为什么要这样说?是不是必须建呢?抱着这样的疑问,我们继续往下看!
索引模型
在解释上边的疑问前,我们需要知道索引这个东西。简单来说索引就像新华字典的目录一样,能快速帮我们定位到查询的字。我们可以根据笔画、拼音等来查找,相应的 Mysql 也有不同的索引类型。Mysql常见的有哈希表、有序数组、搜索树三种。
-
哈希表
1、哈希表顾名思义就是以 Key->Value 存储数据的结构,简单来说就是把Value放到一个数组中,用哈希哈数把Key换算成一个地址。然后将数组放在这个位置。
2、需要注意的是存在哈希碰撞,所以存在多个Key计算为同一个哈希值,这种情况 Mysql 会在重复哈希值后面跟一个链表。当查询时候会先找到这个哈希值的位置,然后遍历这个链表找到对应的记录。
3、哈希表这种结构适合等值查找的情况,比如memcac、redis这种NoSql的存储引擎。范围查找的话,估计要了它的老命。 -
有序数组
1、有序数组适合等值查找和范围查找(二分法等算法)。
2、更新数据代价高,若插入的数据在已有数据中间。后面的数据就得往后移,可能造成叶分裂情况。
3、所以有序数组适合于数据只读型,静态存储引擎。 -
搜索树
1、二叉搜索树:特点左子节点小于父节点,父节点小于右子节点。所以查询更新复杂度都是O(log(N)), 查询很快。但是数据量树高也会大,同时数据块也多了,可能导致一次查询访问多个数据块。索引不仅是在内存中,也放在硬盘中,这样的话需要耗费不少的寻址时间。特别是机械盘!所以一般不用二叉搜索树。2、N叉搜索数。
1、N一般取决于数据块的大小,一些资料中说到 InnoDB整数字段索引一般是1200。比如树高4,那就可以存大约 1200的三次方大约17亿了。查一次数据最多需要查询三次硬盘。若存在内存中会更少。
2、N叉搜索树有种不错的读写效率以及对硬盘的友好性。目前是用的最多的。
索引类型
1、一般分为两类:主键索引、非主键索引。在一些引擎中也叫聚簇索引和二级索引。
2、区别:
- 主键索引
叶子节点存储的是数据叶,也就是包含了数据行。 - 二级索引
叶子节点存储的是主键的值。所以说主键要是text、varchar这些类型,二级索引就会很大。所以主键最好整型,int才四个字节;bigint也就八个字节!
回表
含义:通过二级索引查到主键的值,然后再通过主键索引查到对应的值的过程。
索引二级索引需要扫描两次搜索树,所以尽量用主键查询。
叶分裂
以InnoDB举例:lonoDB使用B+树类型,所以在插入数据时候,当新数据在已有数据范围内,就需要后面的数据往后搬,空出位置。如果不巧的是当前数据叶满了,就需要申请新的数据叶,把后面的数据搬过去。这就叫叶分裂。
所以有一个自增的主键就不会出现这种情况,新的数据只需追加即可。
疑虑解答
Q:我就不建主键会怎么样?
A:innoDB会默认建一个Rowid做主键!
Q:主键索引的子节点存什么?
A:page(叶),一个数据叶可以存多行。
Q:数据叶多行怎么定位具体行?
A:里面是一个有序数组,使用二分法查找。
Q:直接删掉主键索引行吗?
A:行!但不好,会导致所有二级索引失效,并且会使用RowId作为主键。
Q:为啥二级索引子节点不是数据的存储地址?
A:MyiSam是这样的。但是如果修改数据位置,这种情况就不好使了。
后记
敲码不易,转载请注明来源!谢谢。