存储任意类型的值

时间:2017-05-13 16:32:07

标签: clojure datomic

我想存储任意键值对。例如,

{:foo "bar" ; string
 :n 12 ; long
 :p 1.2 ; float
}

在datomic中,我希望将其存储为:

[{:kv/key "foo"
  :kv/value "bar"}
 {:kv/key "n"
  :kv/value 12}
 {:kv/key "p"
  :kv/value 1.2}]

问题是:kv/value在datomic中只能有一种类型。解决方案是将:kv/value拆分为:kv/value-string:kv/value-long:kv/value-float等。它有自己的问题,例如确保一次只使用一个值属性。建议?

2 个答案:

答案 0 :(得分:0)

如果您可以提供有关特定用例的更多详细信息,那么可能更容易找出最佳答案。在这一点上,为什么你可能想要一个有时可能是字符串的属性,有时候是一个int等等,这有点神秘。

从你到目前为止所说的,你唯一真正的答案是拥有不同的属性,如value-string等。这就像在SQL DB中,每个表列只有1种类型,需要不同用于存储字符串,整数等的列

正如您的问题所示,任何工具(例如数据库)都是按照某些假设设计的。在这种情况下,数据库假设每个"列" (Datomic中的属性)始终属于同一类型。数据库还假设您(通常)希望在每个记录/实体的所有列/ attrs中都有数据。

在你的问题中,你与这两个假设都是矛盾的。虽然您仍然可以使用DB来存储信息,但您必须编写自定义函数以确保一次只使用1个属性(value-string,value-int等)。您可能需要自定义插入函数,如" insert-str-val"," insert-int-val"等,以及自定义读取函数" read-str-val& #34;等等。拥有一个可以接受任何记录/实体的验证功能并验证完全只有一个"类型"也许是一个好主意。在任何时候都在使用。

答案 1 :(得分:0)

您可以通过使:kv/key成为:db.unique/identity属性来模拟具有异构值的键值存储,并使:kv/value使用字节类型或字符串类型并对值进行编码您喜欢的格式(例如:db.types/bytes的fressian / nippy,:db.types/string的edn / json)。在这种情况下,我建议您为:db/indexfalse设置为:kv/value

注意:

  1. 您将具有有限的查询能力,因为这些值不会被编入索引,并且需要针对每个查询进行反序列化。
  2. 如果要运行读取或写入值的事务函数(例如数据迁移),则还应使Transactor可以使用编码/解码库。
  3. 如果值很大(例如,超过20kb),请不要将它们存储在Datomic中;使用AWS S3等补充存储服务并存储URL。