Erlang Mnesia:行李台类型是如何实现的?

Erlang Mnesia:行李台类型是如何实现的?,erlang,mnesia,Erlang,Mnesia,我有一个带有整数键(timestamp)的表,其中包含从数据库中删除特定记录的时间。还有一个清理查询,它从该表中获取过期时间小于现在的记录并将其删除 Erlang文档指出,有四种类型的表类型:set、ordered\u-set、bag、和duplicate\u-bag set是使用哈希表实现的,因此读取需要O(1)个时间复杂度 ordered_set是使用树实现的,因此读取需要O(log(n))时间复杂度,但它更适合于后续的时间间隔 我没有找到有关bag实现的信息 ordered\u set

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

Erlang文档指出,有四种类型的表类型:
set
ordered\u-set
bag
、和
duplicate\u-bag

  • set
    是使用哈希表实现的,因此读取需要O(1)个时间复杂度
  • ordered_set
    是使用树实现的,因此读取需要O(log(n))时间复杂度,但它更适合于后续的时间间隔
  • 我没有找到有关
    bag
    实现的信息
ordered\u set
似乎很理想,但我不能使用它,因为两条记录可以具有相同的时间戳。因此,问题是:


bag
表是如何实现的,查询后续间隔是否良好?如果没有,我如何获得“
ordered_bag
”功能?

Mnesia的
bag
使用
ETS
DETS
,以及其他表格类型[1]来实现。此外,Mnesia不支持
replicate_bag
表格-您可以从ducumentation[2]中看到它。因此,我们可以得出结论,Mnesia中的
bag
实现为哈希表,并且具有恒定的查找时间,因为
ETS
DETS
bag实现为哈希表[3]。[4] 还表示
set
bag
在Mnesia中作为哈希表实现

  • 关于问题的其余部分:

    否,
    bag
    不适合查询后续间隔。休息 从
    bag
    表中,您必须完全遍历它。我认为有两个可能的决定可以改变 那个

    首先,您可以使用附加的
    ordered\u set
    表来保持顺序,如下所示: @尼亚胡建议。因此,您将能够高效地查询某个时间间隔内的所有时间戳,并且 然后从您的
    行李
    表中删除相应的条目,这也会很有效,因为 至此,您将知道所有键

    ,您可以使用
    {timestamp,[values]}
    。这将需要额外的手动插入作业 和删除单个条目,但这样可以避免创建其他表
    如果您只需要查询按时间戳分组的请求,我认为您应该首先考虑您必须对数据库执行的最频繁和最关键的请求,以选择正确的组织和主键,我假设(但可能是错误的)它不是时间戳,也不是清除功能

    如果我是正确的,您可以简单地使用dirty_first()和dirty_next()函数遍历表,以便尽可能短的扰动(我认为dirty函数是可以的,因为没有修改时间戳的风险。在操作过程中,无论如何,如果不清理条目,您将在下一次迭代中执行)


    最后,如果清除时间确实很关键,但时间戳不是应用程序最重要的键,则可以使用最佳键将数据存储在一个集合中,并将时间戳(主键)与相关键列表存储在一个单独的有序集合表中

    我认为排序对于与时间相关的应用程序非常重要。表操作仅在行中的特定范围内发生。在没有排序的情况下,您必须处理整个表(好的,有索引)。那么,为什么不使用像{Timestamp,ID}这样的元组键,其中ID是任意值(位于元组的第二个位置以保留时间戳顺序)。为什么一定要用时间戳作为键?为什么要用一元元组而不是单时间戳?哦,是的,我看错了你的帖子,我想你说的是键字段,而不是整个记录。请注意,最小mnesia元组大小是3@niahoo谢谢你,你说得对(但是是2,不是3)。我想我只是从ETS中插入了这个。我更新了答案。@niahoo我想您可能对最小元组大小的mnesia表中的最小属性数(即2)感到困惑。由于表中的每个记录都将表示为格式为{table_name,key,attribute_1}的元组,因此mnesia中元组的最小大小实际上是3。如果我错了,请纠正我。