微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

B+树如何处理AND、OR、IN和equals的组合?

如何解决B+树如何处理AND、OR、IN和equals的组合?

这4种查询是如何利用索引的?扫描结果如何?

WHERE status = "foo"

WHERE id IN (1,2,3)

WHERE id IN (1,3) AND status = "foo"

WHERE id IN (1,3) OR status = "foo"

在第一种情况下,我认为这是一个 B+树,关键是状态。很容易。但是等等,它需要为每个状态存储多个项目,所以它可能有每个状态的记录数组(一般来说)。

但是对于第二个查询,您似乎只会将索引用于 id,并且一次从 B+tree 中获取每个键一个 id,因此它会执行 {{每个 tree.get(id) 为 1}}。但这似乎已经不太理想了。它实际上是如何完成的?

再进一步结合两种查询类型,您现在只能使用其中一个索引(比如 id 索引,而不是 id 索引)。然后获取与这些 ID 匹配的记录子集,并遍历它们并检查状态。

现在我们开始显得效率低下。

与 OR 查询相同。

一般或理想情况下,这些通常如何在数据库中实现?

我之所以这么问是因为我想用 JavaScript 为浏览器实现一个基本版本。基本上,最好的方法是在一个表上有多个(可能是多列的)索引。所以我可以在这个“表”中存储一条记录,它被存储在每个索引中,然后在查询时它从“最佳”索引中获取。我不太确定这是如何在高级别(高级别但在数据结构/算法实现方面非常深入)开始的。

这是我基本上开始使用的模板:

status

所以基本上,为每个表创建多个索引。当您插入一条记录时,它会获取每个索引的键并将其插入到 class Index { constructor(fields = ['id']) { this.fields = fields this.tree = new Tree } insert(record) { this.tree.insert(this.getKey(record),block) } remove(record) { this.tree.remove(this.getKey(record)) } check(record) { return this.tree.check(this.getKey(record)) } getKey(record) { return this.fields.map(field => record[field]).join('') } } class Table { constructor() { this.index = [] } insert(record) { this.index.forEach(index => index.insert(record)) } select(query) { // query processing } remove(id) { } } (充当键/值存储的 B+树)中。从那里我不知道如何正确使用索引,或者我是否在正确的轨道上。我会问一个理想的关​​系数据库如何实现这一点,但这可能会因为过于笼统而被否决:/但这正是我真正想要构建的。

我以 this B+tree 为例。

解决方法

您似乎并没有受到可以拥有的索引的限制,所以让我们假设您在 (id) 上有一个索引,在 (status,id) 上有一个索引。我还将假设 id 是主键或具有唯一性约束,就像 ID 通常所做的那样:

WHERE status = "foo"

从(status,id)索引中有效地读出与状态匹配的项目范围。

WHERE id IN (1,2,3)

假设 id 是一个整数类型,从 (id) 索引中读出 id >=1 和

WHERE id IN (1,3) AND status = "foo"

这匹配 (status,id) 索引中的连续范围。

WHERE id IN (1,3) OR status = "foo"

(1,3) 范围是从 (id) 索引中选择的,而 "foo" 范围是从 (status,id) 索引中选择的。然后合并结果。由于这两个范围具有相同顺序的不同行,因此可以像合并排序中的合并操作一样有效地合并它们。


如果你想用你自己的索引类做同样的事情,你需要支持多列索引,并且你需要能够为索引中的行获取迭代器,从给定的密​​钥。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。