我想在 mnesia 中创建下表:
-record(cuser, {
id,
login_id,
email,
....}).
其中 login_id 和 email 在业务逻辑中都是唯一的。
如何在 mnesia 中实现它?
提前致谢。
我想在 mnesia 中创建下表:
-record(cuser, {
id,
login_id,
email,
....}).
其中 login_id 和 email 在业务逻辑中都是唯一的。
如何在 mnesia 中实现它?
提前致谢。
最简单的方法是在单个 mnesia 事务中执行所有测试。下面的代码做到了。
请注意,此代码不会检查 Id 是否已存在,因此如果您尝试使用现有 id 和新登录 id 和电子邮件添加新用户,它将简单地覆盖现有记录(即 set 的行为)。
%% record declaration
-record (cuser, {id,login_id,email}),
%% create a table for test
mnesia:create_schema([node()]),
application:start(mnesia),
mnesia:create_table(cuser,[{attributes,record_info(fields,cuser)},
{index,[#cuser.login_id,#cuser.email]},
{disc_copies,[node()]},
{type,set}]),
%% write 2 record for test
Wr = fun(I,L,E) -> mnesia:write(#cuser{id=I,login_id=L,email=E}) end,
mnesia:transaction(Wr,[u1,l1,m1]),
mnesia:transaction(Wr,[u2,l2,m2]),
%% create a function for filtering
M = fun(Nl,Ne) ->
Match = ets:fun2ms(fun(#cuser{id=I,login_id=Li,email=E}) when Li =:= Nl; E =:= Ne -> {I,Li,E} end),
mnesia:select(cuser,Match)
end,
%% create a function to add a new user
Add = fun(I,Nl,Ne) ->
{atomic,R} = mnesia:transaction(M,[Nl,Ne]),
case R of
[] -> mnesia:transaction(Wr,[I,Nl,Ne]);
R -> {already_exist,R}
end
end,
%% add new user
mnesia:transaction(Add,[i3,l3,m1]), %% will return {atomic,{already_exist,[{u1,l1,m1}]}}
mnesia:transaction(Add,[i3,l3,m3]), %% will return {atomic,{atomic,ok}}
要检查 Id 是否已经存在,只需在过滤器函数中添加测试:
%% create a function for filtering
M = fun(Ni,Nl,Ne) ->
Match = ets:fun2ms(fun(#cuser{id=I,login_id=Li,email=E}) when I =:= Ni; Li =:= Nl; E =:= Ne -> {I,Li,E} end),
mnesia:select(cuser,Match)
end,
%% create a function to add a new user
Add = fun(I,Nl,Ne) ->
{atomic,R} = mnesia:transaction(M,[I,Nl,Ne]),
case R of
[] -> mnesia:transaction(Wr,[I,Nl,Ne]);
R -> {already_exist,R}
end
end,
Mneisa 是一个key-value存储系统,它只保证 key 的唯一性。
我能想出的唯一方法是使用元组保存{id, login_id}
为主键。
不幸的是,这只能保证其中一个是唯一的。但是,至少您可以使用 查询项目{id, login_id}
。
例如:
-record(cuser, {
uid, %uid = {id, login_id}
email,
....}).