从头实现数据库-10

Date Unknown

二级索引

在本章中,我们将向数据库添加额外的索引(也称为二级索引)。查询将不再局限于主键。
 

索引定义

在表定义中添加了索引和索引前缀字段。与表本身一样,每个索引在KV存储中都分配了一个键前缀。
要通过索引找到行,索引必须包含主键的副本。我们将通过将主键列附加到索引中来实现这一点;这也使索引键唯一,这是B树查找代码的假设。
在创建新表之前,会检查索引并附加主键。
创建新表时分配多个键前缀。
 
 

维护索引

在更新行后,我们需要从索引中删除旧行。B树接口被修改为返回更新前的值。
 
下面是添加或删除索引中记录的函数。在这里,我们遇到了一个问题:更新具有二级索引的表涉及KV 存储中的多个键,这应该以原子方式进行。我们将在以后的章节中解决这个问题。
 
 
更新或删除行后维护索引:

使用二级索引

选择索引

我们还将使用索引的前缀执行范围查询。例如,我们可以在包含前缀【a】的索引【a, b, c】上执行x < a AND a < y。选择索引只是通过输入前缀匹配列。主键在二级索引之前考虑。

编码索引前缀

如果输入键使用索引的前缀而不是完整的索引,我们可能需要编码额外的列。例如,对于带有索引【a,b】的查询v1 < a,我们不能使用【v1】 < key作为底层B树查询,因为任何键【v1,v2】都满足【v1】 < 【v1,v2】,而违反v1 < a。
相反,在这种情况下,我们可以使用【v1,MAX】 < key,其中MAX是列b的最大可能值。以下是编码带有额外列的部分查询键的函数。
对于 int64 类型,最大值编码为所有 0xff 字节。问题是字符串没有最大值。我们可以做的就是使用"\xff" 作为 "伪最大字符串值" 的编码,并将正常字符串编码更改为不以 "\xff" 开头。
如果一个字符串的第一字节是"\xff"或"\xfe",那么它就会被"\xfe"字节转义。因此,所有字符串编码都小于"\xff"。

通过索引检索行

索引键包含所有主键列,因此我们可以找到完整的行。Scanner类型现在知道选择了哪个索引。

将所有部件组合在一起

修改后的 dbScan 函数使用二级索引。现在还可以通过索引前缀进行范围查询。它还可以扫描整个表,而不需要任何键(如果没有列,则选择主键)。
我们实现了关系数据库的一些主要功能:表、范围查询和二级索引。我们可以开始向数据库添加更多功能和查询语言。然而,还有一些主要方面仍然缺失:事务和并发性,这些将在以后的章节中进行探索。

Copyright © 2025 later

logo