1. 哈希表
数据结构最重要的部分
哈希表的时间复杂度是 O(1)
哈希表不适合做数据库的索引。
因为哈希表只能比较相等,无法查找 >、< 这样的范围查询。
但是数据库又要经常使用范围查询,所以需要有合适的解决方案。
所以数据库没有使用 哈希表
2. 二叉搜索树
考虑到如果是最坏的情况,时间复杂度是 0(N)
如果这个树比较平衡,例如 AVL/红黑树,是可以达到 logN
二叉搜索树虽然可以范围查询了,但是数据库也没有使用它。
原因:
二叉意味着当元素个数多了的时候,树的高度会比较高。
树的高度就决定了查询的时候,元素的比较次数就会比较多,而数据库比较都是要读硬盘的。
比较的次数越多,查询的速度也会越慢。
显然不适合数据库。
3. N叉搜索树
每个节点上有多个值,同时有多个分叉。此时树的高度就降低了。
其中一种典型实现,叫做 B树
3.1 B树
下面图片演示 B树。
比较次数虽然没怎么减少(一个结点上可能需要比较多次了),
但是读写硬盘的次数减少了。(每个结点都是在硬盘上的)
B树已经可以比二叉搜索树更适合做数据库索引了,但是还不是很完美。
对于这里又引入了,B+树,这是对 B树的进一步改进。
而 B+树 是为了索引这个场景量身定做的数据结构。
3.2 B+树
图片演示。
特点:
-
B+树也是一个 N叉搜索树,每个节点上可能包含 N个Key,N个Key划分出的区间。
最后一个Key就相当于是最大值了。 -
父元素的 Key 会在子元素中重复出现,并且是以最大的姿态出现的。
这样的重复出现导致叶子结点就包含了所有数据的全集,
非叶子结点中的所有值都会在叶子结点中体现出来。 -
会把叶子结点用类似的于链表的方式收尾相连。
优点:
- 作为一个 N叉搜索树,高度降低下来比较的时候,硬盘 IO 次数就比较少了。(同B树)
- 更适合进行范围查询。
- 所有的查询都是要落在叶子节点上的,无论查询哪个元素,中间比较的次数差不多,查询操作比较均衡。
对于B树来说,可能是有的值查的快,有的查的慢,可能就不均衡了。(在根节点或者深度不深的位置都查的快)
对于B+树来说,都是一样的速度。 - 由于所有的 key 都会在叶子结点中体现,因此非叶子结点不必存表的真实记录(不必存数据行)
只要把所有的数据行给放到叶子结点上即可,非叶子结点只需要存索引列的值(比如存个id)