语境
这个问题与 SQL 和 NoSQL 数据库系统中索引的低级实现细节有关。索引的实际结构(B+ 树、哈希、SSTable 等)是无关紧要的,因为该问题特别与存储在任何这些实现的单个节点内的键有关。
背景
在SQL(如MySQL的)和NoSQL(CouchDB的,MongoDB的,等等)数据库,如果您在列或数据的JSON文档字段建立索引,你实际上是导致数据库做的就是创建本质上所有的排序列表这些值以及与该值相关的记录所在的主数据文件中的文件偏移量。
(为简单起见,我可能会忽略特定实现的其他深奥细节)
简单的经典 SQL 示例
考虑一个标准 SQL 表,它有一个简单的 32 位 int 主键,我们将在其上创建索引,我们最终将在磁盘上得到一个整数键的索引,该索引已排序并与数据文件中的 64 位偏移量相关联,其中记录存在,例如:
id | offset
--------------
1 | 1375
2 | 1413
3 | 1786
Run Code Online (Sandbox Code Playgroud)
索引中键的磁盘表示如下所示:
[4-bytes][8-bytes] --> 12 bytes for each indexed value
Run Code Online (Sandbox Code Playgroud)
坚持使用文件系统和数据库系统优化磁盘 I/O 的标准经验法则,假设您将密钥存储在磁盘上的 4KB 块中,这意味着:
4096 bytes / 12 bytes per key = 341 keys per block
Run Code Online (Sandbox Code Playgroud)
忽略索引的整体结构(B+ 树、哈希、排序列表等),我们一次将 341 个键的块读写到内存中,然后根据需要返回到磁盘。
示例查询
使用上一节中的信息,假设有一个查询“id=2”,经典的数据库索引查找如下:
问题设置... …