【问题标题】:How can Datomic users cope without composite indexes?Datomic 用户在没有复合索引的情况下如何应对?
【发布时间】:2014-08-25 00:48:16
【问题描述】:

在 Datomic 中,您如何有效地执行查询,例如“查找所有居住在华盛顿的 50 岁以上的人”(城市和年龄可能会有所不同)?在关系数据库和大多数 NoSQL 数据库中,您为此目的使用复合索引;据我所知,Datomic 不支持这样的东西。

我构建了几个中型网络应用程序,如果不是针对复合索引,没有一个应用程序会运行得足够快。 Datomic 用户如何处理这个问题?还是他们只是在玩小到不会受此影响的数据集?我错过了什么吗?

【问题讨论】:

  • 这里有同样的问题。你找到解决问题的方法了吗?谢谢。
  • 我只是在玩 Datomic,所以我没有实际问题 :) 但是,我想知道它的局限性是什么以及我是否可以在某些实际应用中使用它项目。
  • 我想到的一个非常丑陋的方法是创建特殊的“索引”属性,其中连接了多个其他属性(因此,在上面给出的示例中,它的值例如 'washington-1983 -01-10')。现在您可以查询“washington-startdate”和“washington-enddate”范围内的实体。它有效,但它闻起来很香。

标签: indexing composite-key datomic


【解决方案1】:

由于 Datomic 中数据(datoms)的结构,这个问题及其解决方案在 Datomic 中并不相同。有两个性能特征/策略可能会为此添加一些阴影:

(1) 当您在 Datomic 中获取数据时,您会从索引树中获取整个叶段(而不是单个项) - 段可能由数千个 datom 组成。然后它会自动缓存,这样您就不必通过网络来获取更多的 datoms。

如果您查询的是单个人(即单个实体)的年龄和居住地,很可能查询的 EAVT 或 AEVT 索引导航可能已经缓存了您需要的所有内容。您已经有效地缓存了 datom、如何导航到它以及相关的 datom(按索引中的位置)。

(2) Partitions 可以提供手动方式来指定参考位置。分区会影响实体 ID 的值(它以高位编码)并确保相关实体彼此靠近排序。因此,对于上述问题的替代实现,如果您需要来自 city 和 person 实体的信息,您可以将它们包含在同一个分区中。

【讨论】:

    【解决方案2】:

    我编写了一个库来处理这个问题:https://github.com/arohner/datomic-compound-index

    【讨论】:

      【解决方案3】:

      2019-06-28 更新: 由于 0.9.5927(Datomic On-Prem)/480-8770(Datomic Cloud),Datomic 支持 Tuples 作为新的属性类型,它允许您有复合索引。

      【讨论】:

      • 虽然元组真的很酷,但这能解决问题吗?假设我想在两列上构建复合索引:整数和日期。如果没有元组,我可以对诸如 left_padded_number-YYYY-MM-DD 字符串之类的值进行编码,并从此类字段的字典索引中受益。当然,对于元组,我不必费心解析字符串(太棒了!),但我仍然必须以一种非常奇怪的方式组织我的数据才能获得索引功能..?还是我弄错了?
      • @TomasKulich 我还没有使用元组,但我认为复合元组是您正在寻找的:docs.datomic.com/cloud/schema/…
      • 啊,我明白了,这太棒了!这似乎正是复合索引语义!从文档的简短浏览来看,即使是范围查询也应该可以正常工作。
      猜你喜欢
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      相关资源
      最近更新 更多