Mnesia 确实支持 . 形式的序列(自动递增整数)mnesia:dirty_update_counter(Table, Key, Increment)
。要使用它,您需要一个具有两个属性 Key 和 Count 的表。尽管有这个名字,但dirty_update_counter 是原子的,即使它不在事务中运行。
Ulf Wiger 在他的rdbms 包中在 mnesia 之上提供了典型的 RDBMS 特性方面做了一些工作。他的代码提供了外键约束、参数化索引、字段值约束等。不幸的是,这段代码已经两年没有更新了,如果没有相当多的 Erlang 经验,可能很难运行。
在设计和使用 mnesia 时,您应该记住 mnesia 不是关系数据库。它是一个事务性的键/值存储,当你不规范化时更容易使用。
如果您的用户名是唯一的,您可以使用以下模式:
-record(user, {name, salt, pass_hash, email}).
-record(entry, {posted, title, body, slug, user_name}).
posted
文章上传时的 erlang:now() 时间在哪里。user_name
如果您经常需要为用户检索所有文章的列表,则可能需要二级索引。由于此数据被拆分到两个表中,因此您必须在应用程序代码中强制执行任何完整性约束(例如,不接受没有有效用户名的条目)。
mnesia 中的每个字段值都可以是任何 erlang 术语,因此,如果您对任何一个特定字段的唯一键感到茫然,您通常可以组合一些字段来为您提供一个始终唯一的值 - 可能是 {Username,发布日期,发布时间}。Mnesia 允许您通过mnesia:select(Table, MatchSpec)
. MatchSpecs 很难手动编写,因此请记住,它ets:fun2ms/1
可以为您将伪 erlang 函数转换为 matchspec。
在这个例子中,fun2ms 为我们生成了一个匹配规范,用于搜索一个博客条目表-record(entry, {key, title, slug, body}).
,其中 key 是{Username, {Year, Month, Day}, {Hour, Minute, Second}}
- 作者的用户名以及文章发布的日期和时间。TargetUsername
下面的示例检索到2008 年 12 月期间所有博客文章的标题。
ets:fun2ms(fun (#entry{key={U, {Y,M,_D}, _Time}, title=T})
when U=:=TargetUsername, Y=:=2008, M=:=12 ->
T
end).