【问题标题】:What is the idiomatic way of limiting the number of records under a certain key in mnesia?在mnesia中限制某个键下的记录数的惯用方法是什么?
【发布时间】:2011-12-25 20:23:43
【问题描述】:

我使用mnesia为用户存储数据,记录是一个结构类似的包

{ username, field1, filed2, timestamp }

为了不让数据库爆炸,我想限制属于某个用户的记录数,比如说,如果一个用户的记录数达到500,那么时间戳最旧的记录是在插入新记录之前删除。

有没有有效的方法来做到这一点?

提前致谢。

【问题讨论】:

    标签: erlang limit mnesia


    【解决方案1】:

    我提供了两种可能性。一种适合您的设计,另一种是在您的记录定义中引入小的变化。看看哪一个最适合您的需求。下面的第一个正在您的设计中工作。

    -记录(用户,{用户名,字段1,字段2,时间戳})。 %% 在一个 mnesia 事务中执行下面的函数 插入(#user{用户名 = U,时间戳 = _T} = 用户)-> case mnesia:read({user,U}) of [] -> mnesia:write(User); 全部在这里-> 案例长度(AllHere)== 500 的 false -> %% 还没有 500 失忆症:写(用户); 真-> %% 值已达到 500 %% 获取所有时间戳并获取 %% 最旧的记录并将其删除 %% OldRecord = get_oldest_stamp(AllHere), ok = mnesia:delete_object(记录), 记忆:写(用户) 结尾 结尾。 get_oldest_stamp(UserRecords)-> %% 你在这里做你的排序 %% 并返回记录 %% 最旧的时间戳 …… 旧唱片。

    事务中的length/1 函数不是最优的。让我们想一个更好的方法。另外,我不知道你的时间戳是什么样子的,所以我确定你有办法对它们进行排序并找出最新的时间戳,挑选出拥有这个时间戳的记录,然后返回它。我给出了这个解决方案只是为了适合您的设计。我也认为我们需要一些indexing。下一个实现对我来说似乎更好。如果我们可以更改记录定义并引入一个字段oldest,该字段采用bool(),我们将如何对其进行索引

    -记录(用户,{ 用户名, 字段1, 字段2, 时间戳, 最旧的 %% bool(),已编入索引
    })。
    insert_user(用户名,Field1,Field2)-> 用户 = #user{ 用户名 = 用户名, 字段 1 = 字段 1, 字段 2 = 字段 2, 时间戳 = {日期(),时间()}
    }。 插入(用户)。
    %% 在 mnesia 事务中执行此操作
    插入(#user{用户名 = U} = 用户)-> case mnesia:read({user,U}) of [] -> mnesia:write(User#user{oldest = true}); 全部在这里-> 案例长度(AllHere)== 500 的 假-> %% 取消设置所有现有记录的最旧字段 %% 为假 F = 乐趣(用户X)-> ok = mnesia:delete_object(UserX), ok = mnesia:write(UserX#user{oldest = false}) 结尾, [F(XX) || XX [OldestRec] = mnesia:index_read(user,true,oldest), ok = mnesia:delete_object(OldestRec), ok = mnesia:write(User#user{oldest = true}) 结尾 结尾。 上面的实现对我来说似乎更好。成功 !!

    【讨论】:

      【解决方案2】:

      另一种方法可能是让您的记录成为

      {username, value_list, timestamp} 
      

      其中 value_list 包含值列表。你的桌子现在可以是一套而不是一个袋子,你可以做这种事情

      {NewList,_ignore}=lists:Split(500, [{NewFld1,NewFld2}|Value_list]),
      %mnesia:write(Rec#{value_list=NewList}) type of code goes next
      

      无论何时插入。 NewList 最多包含 500 个元素,并且由于最旧的元素在最后,如果您有 501 个元素,最后一个将在 _ignore 列表中,您将...忽略。

      您在密钥上进行恒定时间查找以进行某些列表操作,但根据您的应用程序可能是一个很好的权衡。您还可以去掉时间戳字段和相关代码来维护该字段。

      【讨论】:

      • 这种方法很简单(我其实在生产中也有类似的东西),但是如果记录数限制很高的话效率会非常低,因为Mnesia必须读取或写入所有数据对用户执行的每项操作。
      猜你喜欢
      • 2011-03-16
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 2011-09-14
      • 2011-05-28
      • 1970-01-01
      相关资源
      最近更新 更多