erlang-mnesia数据库操作

2018-06-20  本文已影响0人  zhang_yongfeng

Mnesia是一个分布式数据库管理系统,适合于电信和其它需要持续运行和具备软实时特性的Erlang应用,越来越受关注和使用,但是目前Mnesia资料却不多,很多都只有官方的用户指南。下面的内容将着重说明 Mnesia 数据库如何实现SQL查询,实现select / insert / update / where / order by / join / limit / delete等SQL操作。

示例文件如下:

-module(mnesia_text).
-export([init/0,
    create_m_y_account/0,
    create_m_y_info/0,
    delete_m/0,
    select/0,
    select_qlc/0,
    quary/0,
    quary_qlc/0,
    write/0,
    write_y_info/0,
    where_qlc/0,
    where/0,
    where_qlc_key/0,
    where_qlc_no_key/0,
    order_by/0,
    order_by_two/0,
    join/0
    ]).

-compile([export_all]).

-include_lib("stdlib/include/qlc.hrl").

%% 账号表结构   
-record( y_account,{ id, account, password }).  
  
%% 资料表结构    
-record( y_info, { id, nickname, birthday, sex }). 

init() ->
    %% 在本机节点上初始化数据库 
    mnesia:create_schema([node()]),
    %% 启动数据库
    mnesia:start().

%1、Create Table / Delete Table 操作
%%===============================================  
%%  create table y_account ( id int, account varchar(50),  
%%   password varchar(50),  primary key(id)) ;  
%%===============================================  
create_m_y_account() ->
    mnesia:create_table( y_account,[{attributes, record_info(fields, y_account)} , {type,set}, {disc_copies, [node()]} ]). 

create_m_y_info() ->
    mnesia:create_table( y_info,[{attributes, record_info(fields, y_info)} , {type,set}, {disc_copies, [node()]} ]). 

%%===============================================  
%%  drop table y_account;  
%%=============================================== 
delete_m() ->
    mnesia:delete_table(y_account) .  

%2、Select 查询
select() ->
%% 2.1使用 mnesia:select  
F = fun() ->  
    MatchHead = #y_account{ _ = '_' },  
    Guard = [],  
    Result = ['$_'],  
    mnesia:select(y_account, [{MatchHead, Guard, Result}])  
end,  
mnesia:transaction(F).  

%% 2.2使用 qlc 
%%===============================================  
%%  select * from y_account  
%%===============================================  
select_qlc() -> 
F = fun() ->  
    Q = qlc:q([E || E <- mnesia:table(y_account)]),  
    qlc:e(Q)  
end,  
mnesia:transaction(F). 

% 2.3查询部分字段的记录
%%===============================================  
%%  select id,account from y_account  
%%===============================================  
quary() ->
F = fun() ->  
    MatchHead = #y_account{id = '$1', account = '$2', _ = '_' },  
    Guard = [],  
    Result = ['$$'],  
    mnesia:select(y_account, [{MatchHead, Guard, Result}])  
end,  
mnesia:transaction(F).  

quary_qlc() ->
%% 使用 qlc  
F = fun() ->  
    Q = qlc:q([[E#y_account.id, E#y_account.account] || E <- mnesia:table(y_account)]),  
    qlc:e(Q)  
end,  
mnesia:transaction(F).


%3、Insert / Update 操作
%%===============================================  
%%    insert into y_account (id,account,password) values(5,"xiaohong","123")  
%%     on duplicate key update account="xiaohong",password="123";  
%%===============================================  
%mnesia是根据主键去更新记录的,如果主键不存在则插入

write()->
%% 使用 mnesia:write  
F = fun() ->  
    Acc = #y_account{id = 5, account="xiaohong", password="123"},  
    mnesia:write(Acc)  
end,  
mnesia:transaction(F).  

write_y_info()->
%% 使用 mnesia:write   id, nickname, birthday, sex 
F = fun() ->  
    Acc = #y_info{id = 5, nickname="aaa", birthday="20180101"},  
    mnesia:write(Acc)  
end,  
mnesia:transaction(F).  

%4、Where 查询
%%===============================================  
%%    select account from y_account where id>5  
%%===============================================  
where() ->
%% 使用 mnesia:select  
F = fun() ->  
    MatchHead = #y_account{id = '$1', account = '$2', _ = '_' },  
    Guard = [{'>', '$1', 5}],  
    Result = ['$2'],  
    mnesia:select(y_account, [{MatchHead, Guard, Result}])  
end,  
mnesia:transaction(F).

where_qlc() ->
F = fun() ->  
    Q = qlc:q([E#y_account.account || E <- mnesia:table(y_account), E#y_account.id>5]),  
    qlc:e(Q)  
end,  
mnesia:transaction(F). 
%%===============================================  
%%   select * from y_account where account='xiaomin'  
%%===============================================  
where_qlc_key() ->
%如果查找主键 key=X 的记录,还可以这样子查询:
F = fun() ->  
    mnesia:read({y_account,5})  
end,  
mnesia:transaction(F). 

%%===============================================  
%%   select * from y_account where account='xiaomin'  
%%===============================================  
where_qlc_no_key() ->
%如果查找非主键 field=X 的记录,可以如下查询:
F = fun() ->  
    MatchHead = #y_account{ id = '_', account = "xiaomin", password = '_' },  
    Guard = [],  
    Result = ['$_'],  
    mnesia:select(y_account, [{MatchHead, Guard, Result}])  
end,  
mnesia:transaction(F). 

%5、Order By 查询
%%===============================================  
%%   select * from y_account order by id asc  
%%=============================================== 
order_by() ->
%% 使用 qlc  
F = fun() ->  
    Q = qlc:q([E || E <- mnesia:table(y_account)]),  
    qlc:e(qlc:keysort(2, Q, [{order, ascending}]))  
end,  
mnesia:transaction(F).  

order_by_two()->
%% 使用 qlc 的第二种写法  
F = fun() ->    
    Q = qlc:q([E || E <- mnesia:table(y_account)]),   
    Order = fun(A, B) ->  
        B#y_account.id > A#y_account.id  
    end,  
    qlc:e(qlc:sort(Q, [{order, Order}]))  
end,    
mnesia:transaction(F). 


%6、Join 关联表查询
%%===============================================  
%%   select y_info.* from y_account join y_info on (y_account.id = y_info.id)  
%%      where y_account.account = 'xiaomin'  
%%===============================================  
join() ->
%% 使用 qlc  
F = fun() ->  
    Q = qlc:q([Y || X <- mnesia:table(y_account),  
        X#y_account.account =:= "xiaomin",  
        Y <- mnesia:table(y_info),  
        X#y_account.id =:= Y#y_info.id  
    ]),  
    qlc:e(Q)  
end,  
mnesia:transaction(F).  


%7、limit查询
%%===============================================  
%%   select * from y_account limit 2  
%%=============================================== 
limit() ->
F = fun() ->  
    MatchHead = #y_account{ _ = '_' },   
    mnesia:select(y_account, [{MatchHead, [], ['$_']}], 2, none)  
end,  
mnesia:transaction(F).  

limit_qlc() ->
F = fun() ->  
    Q = qlc:q([E || E <- mnesia:table(y_account)]),  
    QC = qlc:cursor(Q),  
    qlc:next_answers(QC, 2)  
end,  
mnesia:transaction(F).


%8、Select count(*) 查询
%%===============================================  
%%   select count(*) from y_account  
%%===============================================  

select_count() ->
%% 使用 mnesia:table_info  
F = fun() ->  
    mnesia:table_info(y_account, size)  
end,  
mnesia:transaction(F). 



%9、Delete 查询
%%===============================================  
%%   delete from y_account where id=5  
%%===============================================  
delete_data()->
%% 使用 mnesia:delete  
F = fun() ->  
    mnesia:delete({y_account, 5})  
end,  
mnesia:transaction(F). 
➜  erlang erl
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false] 

Eshell V5.9.3.1  (abort with ^G)
1> c(mnesia_text).
{ok,mnesia_text}
2> mnesia_text:init().
ok
3> mnesia_text:create_m_y_account().
{aborted,{already_exists,y_account}}
4> mnesia_text:create_m_y_info(().  
* 1: syntax error before: ')'
4> mnesia_text:create_m_y_info(). 
{aborted,{already_exists,y_info}}
5> mnesia_text:delete_m().       
{atomic,ok}
6> mnesia_text:create_m_y_account().
{atomic,ok}
7> mnesia_text:create_m_y_account().
{aborted,{already_exists,y_account}}
8> mnesia_text:select().            
{atomic,[]}
9> mnesia_text:quary(). 
{atomic,[]}
10> mnesia_text:write().
{atomic,ok}
11> c(mnesia_text).                  
{ok,mnesia_text}
12> mnesia_text:write().
{aborted,{{badmatch,{y_account,2,"xiaohong2","13"}},
          [{mnesia_text,'-write/0-fun-0-',0,
                        [{file,"mnesia_text.erl"},{line,107}]},
           {mnesia_tm,apply_fun,3,[{file,"mnesia_tm.erl"},{line,829}]},
           {mnesia_tm,execute_transaction,5,
                      [{file,"mnesia_tm.erl"},{line,809}]},
           {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,576}]},
           {shell,exprs,7,[{file,"shell.erl"},{line,668}]},
           {shell,eval_exprs,7,[{file,"shell.erl"},{line,623}]},
           {shell,eval_loop,3,[{file,"shell.erl"},{line,608}]}]}}
13> c(mnesia_text).     
{ok,mnesia_text}
14> mnesia_text:write().
{atomic,ok}
15> mnesia_text:quary().
{atomic,[[6,"xiaohong6"],
         [1,"xiaohong1"],
         [2,"xiaohong2"],
         [5,"xiaohong"]]}
16> mnesia_text:select().
{atomic,[{y_account,6,"xiaohong6","2"},
         {y_account,1,"xiaohong1","11"},
         {y_account,2,"xiaohong2","13"},
         {y_account,5,"xiaohong","3"}]}
17> mnesia_text:select_qlc().
{atomic,[{y_account,6,"xiaohong6","2"},
         {y_account,1,"xiaohong1","11"},
         {y_account,2,"xiaohong2","13"},
         {y_account,5,"xiaohong","3"}]}
18> mnesia_text:quary_qlc(). 
{atomic,[[6,"xiaohong6"],
         [1,"xiaohong1"],
         [2,"xiaohong2"],
         [5,"xiaohong"]]}
19> c(mnesia_text).          
{ok,mnesia_text}
20> mnesia_text:write_y_info(). 
{atomic,ok}
21> mnesia_text:where().
{atomic,["xiaohong6"]}
22> mnesia_text:where_qlc().
{atomic,["xiaohong6"]}
23> mnesia_text:where_qlc_key().
{atomic,[{y_account,5,"xiaohong","3"}]}
24> mnesia_text:where_qlc_no_key().
{atomic,[]}
25> mnesia_text:order_by().        
{atomic,[{y_account,1,"xiaohong1","11"},
         {y_account,2,"xiaohong2","13"},
         {y_account,5,"xiaohong","3"},
         {y_account,6,"xiaohong6","2"}]}
26> c(mnesia_text).        
{ok,mnesia_text}
27> mnesia_text:order_by(3).
{atomic,[{y_account,5,"xiaohong","3"},
         {y_account,1,"xiaohong1","11"},
         {y_account,2,"xiaohong2","13"},
         {y_account,6,"xiaohong6","2"}]}
28> mnesia_text:order_by_two().
{atomic,[{y_account,1,"xiaohong1","11"},
         {y_account,2,"xiaohong2","13"},
         {y_account,5,"xiaohong","3"},
         {y_account,6,"xiaohong6","2"}]}
29> c(mnesia_text).
{ok,mnesia_text}
30> mnesia_text:join().
{atomic,[{y_info,5,"bbb","20181001",undefined}]}
31> mnesia_text:limit().
{atomic,{[{y_account,2,"xiaohong2","13"},
          {y_account,5,"xiaohong","3"}],
         {mnesia_select,y_account,
                        {tid,68,<0.31.0>},
                        nonode@nohost,disc_copies,
                        {y_account,196,2,<<>>,[],0},
                        [],undefined,undefined,
                        [{{y_account,'_','_','_'},[],['$_']}]}}}
32> mnesia_text:limit_qlc().
{atomic,[{y_account,6,"xiaohong6","2"},
         {y_account,1,"xiaohong1","11"}]}
33> mnesia_text:limit_qlc().
{atomic,[{y_account,6,"xiaohong6","2"},
         {y_account,1,"xiaohong1","11"}]}
34> 
34> 
34> 
34> mnesia_text:select_count().
{atomic,4}
35> mnesia_text:delete_data(). 
{atomic,ok}
36> mnesia_text:quary().
{atomic,[[6,"xiaohong6"],[1,"xiaohong1"],[2,"xiaohong2"]]}
37> mnesia_text:select().
{atomic,[{y_account,6,"xiaohong6","2"},
         {y_account,1,"xiaohong1","11"},
         {y_account,2,"xiaohong2","13"}]}
38> 

转:https://blog.csdn.net/mycwq/article/details/12506085

上一篇下一篇

猜你喜欢

热点阅读