【发布时间】:2011-12-25 20:23:43
【问题描述】:
我使用mnesia为用户存储数据,记录是一个结构类似的包
{ username, field1, filed2, timestamp }
为了不让数据库爆炸,我想限制属于某个用户的记录数,比如说,如果一个用户的记录数达到500,那么时间戳最旧的记录是在插入新记录之前删除。
有没有有效的方法来做到这一点?
提前致谢。
【问题讨论】:
我使用mnesia为用户存储数据,记录是一个结构类似的包
{ username, field1, filed2, timestamp }
为了不让数据库爆炸,我想限制属于某个用户的记录数,比如说,如果一个用户的记录数达到500,那么时间戳最旧的记录是在插入新记录之前删除。
有没有有效的方法来做到这一点?
提前致谢。
【问题讨论】:
我提供了两种可能性。一种适合您的设计,另一种是在您的记录定义中引入小的变化。看看哪一个最适合您的需求。下面的第一个正在您的设计中工作。
-记录(用户,{用户名,字段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(),我们将如何对其进行索引
【讨论】:
另一种方法可能是让您的记录成为
{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 列表中,您将...忽略。
您在密钥上进行恒定时间查找以进行某些列表操作,但根据您的应用程序可能是一个很好的权衡。您还可以去掉时间戳字段和相关代码来维护该字段。
【讨论】: