Erlang Mnesia Уникальные ключи кроме ключа примарий

Я хочу создать следующую таблицу в Mnesia:

-record(cuser, {
id,
login_id,
email,
....}).

где login_id и email уникальны в бизнес-логике.

Как я могу реализовать это в Mnesia?

Заранее спасибо.

2 ответа

Решение

Самый простой способ - выполнить все тесты за одну транзакцию mnesia. следующий код делает это.

Имейте в виду, что этот код не проверяет, существует ли 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 - это система хранения ключ-значение, которая только гарантирует, что ключ уникален.

Единственный способ, которым я могу придумать, - это использовать кортеж для сохранения {id, login_id} в качестве первичного ключа.

К сожалению, это может гарантировать только то, что один из них уникален. Тем не менее, по крайней мере, вы можете запросить элемент с {id, login_id},

Например:

-record(cuser, {
    uid, %uid = {id, login_id}
    email,
    ....}).
Другие вопросы по тегам