Indexing 使EAVT索引优于EATV的用例是什么?

Indexing 使EAVT索引优于EATV的用例是什么?,indexing,datomic,Indexing,Datomic,据我所知,Datomic没有的EATV非常适合as查询。另一方面,我没有看到EAVT的用例 这类似于行/主键访问。从:EAVT索引提供了对给定实体的所有内容的有效访问。从概念上讲,这与SQL数据库中的行访问样式非常相似,不同之处在于实体可以拥有任意属性,而不限于预定义的一组列 Datomic的不可变时间/历史方面是一个激励性的用例,但一般来说,它仍然围绕典型的数据库操作进行优化,例如查找实体的属性及其值 更新: Datomic将数据存储在索引树中的段中。因此,您可以使用树导航到特定E的段,然后检

据我所知,Datomic没有的EATV非常适合as查询。另一方面,我没有看到EAVT的用例

这类似于行/主键访问。从:EAVT索引提供了对给定实体的所有内容的有效访问。从概念上讲,这与SQL数据库中的行访问样式非常相似,不同之处在于实体可以拥有任意属性,而不限于预定义的一组列

Datomic的不可变时间/历史方面是一个激励性的用例,但一般来说,它仍然围绕典型的数据库操作进行优化,例如查找实体的属性及其值

更新:


Datomic将数据存储在索引树中的段中。因此,您可以使用树导航到特定E的段,然后检索段中关于该E的数据,即EAVT数据。从您的评论中,我相信您认为这是在每一步导航更多类似于b树的结构,这是不正确的。导航到E后,您将访问已排序数据的叶段。

这类似于行/主键访问。从:EAVT索引提供了对给定实体的所有内容的有效访问。从概念上讲,这与SQL数据库中的行访问样式非常相似,不同之处在于实体可以拥有任意属性,而不限于预定义的一组列

Datomic的不可变时间/历史方面是一个激励性的用例,但一般来说,它仍然围绕典型的数据库操作进行优化,例如查找实体的属性及其值

更新:


Datomic将数据存储在索引树中的段中。因此,您可以使用树导航到特定E的段,然后检索段中关于该E的数据,即EAVT数据。从您的评论中,我相信您认为这是在每一步导航更多类似于b树的结构,这是不正确的。导航到E后,您将访问已排序数据的叶段。

您不会在特定时间点查找单个值。您正在查找一组在特定时间点T之前的值。历史是基于每个值而不是基于属性的

例如,断言X,收回X,然后再次断言X。这是3个不同交易的3个不同事实。您需要计算X被添加,然后被删除,然后可能在某个点再次添加

您可以使用SQL执行此操作:

create table Datoms (
  E bigint not null,
  A bigint not null,
  V varbinary(1536) not null,
  T bigint not null,
  Op bit not null --assert/retract
)

select E, A, V
from Datoms
where E = 1 and T <= 42
group by E, A, V
having 0 < sum(case Op when 1 then +1 else -1 end)
datom的第五个组件Op告诉您该值是断言为1还是收回为0。通过将该值相加为+1/-1,我们得到1或0

两次断言同一个值没有任何作用,并且总是在断言新值之前收回旧值。最后一部分是算法很好地解决这个问题的先决条件


使用EAVT索引,这是一个非常高效的查询,而且非常优雅。您可以像这样用150行SQL构建一个基本的类似Datomic的系统。对于您想要的EAVT索引的任何排列,都会重复相同的模式。

您不是在特定时间点寻找单个值。您正在查找一组在特定时间点T之前的值。历史是基于每个值而不是基于属性的

例如,断言X,收回X,然后再次断言X。这是3个不同交易的3个不同事实。您需要计算X被添加,然后被删除,然后可能在某个点再次添加

您可以使用SQL执行此操作:

create table Datoms (
  E bigint not null,
  A bigint not null,
  V varbinary(1536) not null,
  T bigint not null,
  Op bit not null --assert/retract
)

select E, A, V
from Datoms
where E = 1 and T <= 42
group by E, A, V
having 0 < sum(case Op when 1 then +1 else -1 end)
datom的第五个组件Op告诉您该值是断言为1还是收回为0。通过将该值相加为+1/-1,我们得到1或0

两次断言同一个值没有任何作用,并且总是在断言新值之前收回旧值。最后一部分是算法很好地解决这个问题的先决条件


使用EAVT索引,这是一个非常高效的查询,而且非常优雅。您可以像这样用150行SQL构建一个基本的类似Datomic的系统。对于您想要的EAVT索引的任何排列,都会重复相同的模式。

但我不知道如何从EAVT中查找实体的属性值。我的意思是,EA的部分很明显,但为什么最后要VT呢?据我所知,VT的意思是,你在一个B-树中有一个给定属性的所有过去的值,只有在选择一个具体的值时,你才能发现,这个值是在什么时候设置的,你甚至不知道这个属性是否存在新的值!。虽然,这篇博文指出,对于大多数查询来说,这可能不是什么大不了的事,但对于as-of查询来说,这是一件大不了的事!我已经更新了上面的答案。VT不是b树,索引本身是包含所有数据的覆盖索引。您只能导航索引树以获取包含有关实体-y的所有数据的叶段
但是实体E上的A是曾经做过的。这是正确的吗?我使用lgdb_大小作为访问B树索引的上限,并且仅当您通过历史数据库时。Datomic将在其live index中明确显示最新值。live index只对E和A的某些组合进行了当前断言。因此,live index的访问时间将随着时间的推移而保持不变,但历史数据库(这只是访问数据库的一种不同方式)将不得不进行更多的计算。尽管,Datomic建立在这样一个假设之上,即个别事实的变化很少发生。你不会一直回去更新东西。如果你这样做了,那么Datomic是这个工作的错误工具。它不会编写繁重的工作负载。作者有意识地决定不这样做。@TomasKulich顺便说一句,这里有记录,谢谢你的解释!我不知道实时索引。这很有道理——查询过去不需要那么快。