常见的索引方式

如果没有索引,对于无序的数据,我们查找数据就只能依靠遍历,算法时间复杂度为O(N);对于有序的数据,可以使用二分查找, 时间复杂度为O(lgN),但是此处的有序还有一个要求,就是数据是空间连续的,即如果是使用链表保存,即便是有序也无法使用 二分查找。

现实世界中,数据的出现总是无序的,对于无序的数据,常有这么几个数据结构来构建索引:

  • Hash table: https://en.wikipedia.org/wiki/Hash_table 哈希表,教科书上有,太经典了,不说了。其优点是查找速度非常快,缺点是无序,因此无法借助哈希表进行范围查找。现实 中的例子是:Redis中的KV。

  • LSM Tree: https://en.wikipedia.org/wiki/Log-structured_merge-tree 对于机械硬盘来说,随机读写非常耗时,但是顺序读写非常的快。LSM Tree就特别适合处理这种情况。首先,在内存中会维护一个 表(比如哈希表,或者跳跃表)来实现KV,每次写入之前,都会先追加到硬盘上的一个Append Only的日志文件。然后周期性的合并 老的Append Only的文件。Append Only的日志文件每达到一定大小之后,就写入到一个新的文件,老的文件会进行合并&排序。此后 查找起来就很快了,先从内存中的数据查找,没找到就从日志文件里从新到旧查找,因为文件都是有序的,所以可以使用二分查找。

  • B-Tree: https://en.wikipedia.org/wiki/B-tree B-Tree,通过控制树的高度,当节点保存的数据很多时,每下降一层,就可以过滤掉很多数据。当保证节点所保存的数据是有序的 这个特性时,B-Tree就可以进行范围查找了。查找时间复杂度为O(lgN)。现实中的例子是常见的关系型数据库中的索引实现。


更多文章
  • 读《为什么学生不喜欢上学》
  • OpenAI Prompt Engineering 摘录和总结
  • 读《打造真正的新产品》
  • 2023年终总结
  • VueJS 总结
  • Linux 自动挂载 alist 提供的webdav
  • FreeBSD 使用 vm-bhyve 安装Debian虚拟机
  • FreeBSD 和 Linux 网卡聚合实现提速
  • GPT 帮我搞定了时区转换问题
  • 长任务系统如何处理?
  • macOS/Linux 编译 InputLeap
  • 使用开源软KVM - synergy-core
  • 解决 macOS 终端hostname一直变化问题
  • KVM 共享 Intel 集成显卡
  • PromQL 备忘