Mnesia:包表类型是如何实现的?

时间:2013-09-30 09:53:40

标签: erlang mnesia

我有一个带有整数键的表(timestamp)包含应该从数据库中删除特定记录的时间。还有一个清理查询,它从此表记录中获取的到期时间少于现在并删除它们。

Erlang文档说,有四种类型的表类型:setordered_setbagduplicate_bag

  • set是使用哈希表实现的,因此读取时间复杂度为O(1)。
  • ordered_set是使用树实现的,因此读取需要O(log(n))时间复杂度,但它最好与后续间隔一起使用。
  • 我找不到有关bag实施的信息。

ordered_set似乎很理想,但我不能使用它,因为两个记录可以具有相同的时间戳。所以问题是:

如何实现bag表并且查询后续间隔是否合适?如果没有,我如何获得“ordered_bag”功能?

2 个答案:

答案 0 :(得分:4)

Mnesia的bag是使用ETSDETS实现的,因此其他表格类型[1]也是如此。此外,Mnesia不支持duplicate_bag表 - 您可以从ducumentation [2]中看到它。因此,我们可以得出结论:Mnesia中的bag被实现为哈希表,并且具有恒定的查找时间,因为ETSDETS bag被实现为哈希表[3]。 [4]还说setbag在Mnesia中实现为哈希表。

  1. Learn You Some Erlang
  2. Erlang -- mnesia:create_table/2
  3. Erlang Programming by Fransecso Cesarini and Simon Thompson, Ch.10
  4. Erlang and OTP in Action by Martin Logan, Eric Merritt, and Richard Carlsson, Ch.9
  5. 关于问题的其余部分:

    不,bag不适合查询后续间隔。获得间隔 从bag表中你必须完全遍历它。我看到两个可能的决定 这一点。

    首先,您可以使用其他ordered_set表来保持订单,如 @niahoo建议。因此,您将能够有效地查询属于某个时间间隔的所有时间戳,并且 然后从bag表中删除相应的条目,这也是有效的,因为 到目前为止,你会知道所有的钥匙。

    第二次,您可以使用ordered_set {timestamp, [values]}。这将需要额外的手动作业插入 并删除单个条目,但它将使您无法创建其他表 如果您只需要按timestamp分组查询它们。

答案 1 :(得分:0)

我认为您应该首先考虑一下您必须对数据库执行的最频繁和时间关键的请求,以选择正确的组织和主键,我认为(但可能是错误的)它不是时间戳,也不是清理功能。

如果我是正确的,您可以使用dirty_first()然后使用dirty_next()函数遍历表,以使扰动尽可能短(我认为脏函数是可以的,因为时间戳没有风险在操作期间修改。无论如何,如果你没有清理一个条目,你将在下一次迭代中完成。)

最后,如果清理时间非常关键,但时间戳不是应用程序最重要的密钥,则可以使用最佳密钥将数据存储在一个集合中,并在单独的有序集合表中将时间戳(主键)存储为相关键列表。