常见的索引方式

如果没有索引,对于无序的数据,我们查找数据就只能依靠遍历,算法时间复杂度为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)。现实中的例子是常见的关系型数据库中的索引实现。


更多文章
  • 为什么我选择放弃运营微信公众号?
  • ArchLinux 怎么降级 package ?
  • Vim打开很慢,怎么找出最慢的插件?怎么解决?
  • Web后端工程师进阶指南(2018)
  • How to implement fork syscall in Golang?
  • macOS ansible 遇到 rsync: --chown=www-data: unknown option
  • 关于运营的思考-运营要怎么做?
  • Python中实现单例模式的n种方式和原理
  • Golang defer中修改返回值
  • Python dataclass 源码阅读与分析
  • gRPC-gateway 源码阅读与分析
  • 如何阅读源代码
  • 我心目中的配置中心应该怎么做?
  • 设计一个HTTP网关
  • 设计一个分布式块存储