如何解决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 举报,一经查实,本站将立刻删除。