zoukankan      html  css  js  c++  java
  • erlang mnesia 数据库实现SQL查询

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

    示例中表结构的定义:

    [plain] view plaincopy
     
    1. %% 账号表结构   
    2. -record( y_account,{ id, account, password }).  
    3.   
    4. %% 资料表结构    
    5. -record( y_info, { id, nickname, birthday, sex }).   

    1、Create Table / Delete Table 操作

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%  create table y_account ( id int, account varchar(50),  
    3. %%   password varchar(50),  primary key(id)) ;  
    4. %%===============================================  
    5.   
    6. %% 使用 mnesia:create_table  
    7. mnesia:create_table( y_account,[{attributes, record_info(fields, y_account)} ,  
    8.   {type,set}, {disc_copies, [node()]} ]).  
    9.   
    10. %%===============================================  
    11. %%  drop table y_account;  
    12. %%===============================================  
    13.   
    14. %% 使用 mnesia:delete_table  
    15. mnesia:delete_table(y_account) .  

    注:参数意义可以看文档,{type,set} 表示id作为主键,不允许id重复,如果改为 {type,bag},id可以重复,但整条记录不能重复

    2、Select 查询

    查询全部记录

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%  select * from y_account  
    3. %%===============================================  
    4.   
    5. %% 使用 mnesia:select  
    6. F = fun() ->  
    7.     MatchHead = #y_account{ _ = '_' },  
    8.     Guard = [],  
    9.     Result = ['$_'],  
    10.     mnesia:select(y_account, [{MatchHead, Guard, Result}])  
    11. end,  
    12. mnesia:transaction(F).  
    13.   
    14. %% 使用 qlc  
    15. F = fun() ->  
    16.     Q = qlc:q([E || E <- mnesia:table(y_account)]),  
    17.     qlc:e(Q)  
    18. end,  
    19. mnesia:transaction(F).  

    查询部分字段的记录

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%  select id,account from y_account  
    3. %%===============================================  
    4.   
    5. %% 使用 mnesia:select  
    6. F = fun() ->  
    7.     MatchHead = #y_account{id = '$1', account = '$2', _ = '_' },  
    8.     Guard = [],  
    9.     Result = ['$$'],  
    10.     mnesia:select(y_account, [{MatchHead, Guard, Result}])  
    11. end,  
    12. mnesia:transaction(F).  
    13.   
    14. %% 使用 qlc  
    15. F = fun() ->  
    16.     Q = qlc:q([[E#y_account.id, E#y_account.account] || E <- mnesia:table(y_account)]),  
    17.     qlc:e(Q)  
    18. end,  
    19. mnesia:transaction(F).  

    3、Insert / Update 操作

    mnesia是根据主键去更新记录的,如果主键不存在则插入

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%    insert into y_account (id,account,password) values(5,"xiaohong","123")  
    3. %%     on duplicate key update account="xiaohong",password="123";  
    4. %%===============================================  
    5.   
    6. %% 使用 mnesia:write  
    7. F = fun() ->  
    8.     Acc = #y_account{id = 5, account="xiaohong", password="123"},  
    9.     mnesia:write(Acc)  
    10. end,  
    11. mnesia:transaction(F).  

    4、Where 查询

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%    select account from y_account where id>5  
    3. %%===============================================  
    4.   
    5. %% 使用 mnesia:select  
    6. F = fun() ->  
    7.     MatchHead = #y_account{id = '$1', account = '$2', _ = '_' },  
    8.     Guard = [{'>', '$1', 5}],  
    9.     Result = ['$2'],  
    10.     mnesia:select(y_account, [{MatchHead, Guard, Result}])  
    11. end,  
    12. mnesia:transaction(F).  
    13.   
    14. %% 使用 qlc  
    15. F = fun() ->  
    16.     Q = qlc:q([E#y_account.account || E <- mnesia:table(y_account), E#y_account.id>5]),  
    17.     qlc:e(Q)  
    18. end,  
    19. mnesia:transaction(F).  

    如果查找主键 key=X 的记录,还可以这样子查询:

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   select * from y_account where id=5  
    3. %%===============================================  
    4.   
    5. F = fun() ->  
    6.     mnesia:read({y_account,5})  
    7. end,  
    8. mnesia:transaction(F).  

    如果查找非主键 field=X 的记录,可以如下查询:

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   select * from y_account where account='xiaomin'  
    3. %%===============================================  
    4.   
    5. F = fun() ->  
    6.     MatchHead = #y_account{ id = '_', account = "xiaomin", password = '_' },  
    7.     Guard = [],  
    8.     Result = ['$_'],  
    9.     mnesia:select(y_account, [{MatchHead, Guard, Result}])  
    10. end,  
    11. mnesia:transaction(F).  

    5、Order By 查询

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   select * from y_account order by id asc  
    3. %%===============================================  
    4.   
    5. %% 使用 qlc  
    6. F = fun() ->  
    7.     Q = qlc:q([E || E <- mnesia:table(y_account)]),  
    8.     qlc:e(qlc:keysort(2, Q, [{order, ascending}]))  
    9. end,  
    10. mnesia:transaction(F).  
    11.   
    12. %% 使用 qlc 的第二种写法  
    13. F = fun() ->    
    14.     Q = qlc:q([E || E <- mnesia:table(y_account)]),   
    15.     Order = fun(A, B) ->  
    16.         B#y_account.id > A#y_account.id  
    17.     end,  
    18.     qlc:e(qlc:sort(Q, [{order, Order}]))  
    19. end,    
    20. mnesia:transaction(F).  

    6、Join 关联表查询

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   select y_info.* from y_account join y_info on (y_account.id = y_info.id)  
    3. %%      where y_account.account = 'xiaomin'  
    4. %%===============================================  
    5.   
    6. %% 使用 qlc  
    7. F = fun() ->  
    8.     Q = qlc:q([Y || X <- mnesia:table(y_account),  
    9.         X#y_account.account =:= "xiaomin",  
    10.         Y <- mnesia:table(y_info),  
    11.         X#y_account.id =:= Y#y_info.id  
    12.     ]),  
    13.     qlc:e(Q)  
    14. end,  
    15. mnesia:transaction(F).  

    7、Limit 查询

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   select * from y_account limit 2  
    3. %%===============================================  
    4.   
    5. %% 使用 mnesia:select  
    6. F = fun() ->  
    7.     MatchHead = #y_account{ _ = '_' },   
    8.     mnesia:select(y_account, [{MatchHead, [], ['$_']}], 2, none)  
    9. end,  
    10. mnesia:transaction(F).  
    11.   
    12. %% 使用 qlc  
    13. F = fun() ->  
    14.     Q = qlc:q([E || E <- mnesia:table(y_account)]),  
    15.     QC = qlc:cursor(Q),  
    16.     qlc:next_answers(QC, 2)  
    17. end,  
    18. mnesia:transaction(F).  

    8、Select count(*) 查询

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   select count(*) from y_account  
    3. %%===============================================  
    4.   
    5. %% 使用 mnesia:table_info  
    6. F = fun() ->  
    7.     mnesia:table_info(y_account, size)  
    8. end,  
    9. mnesia:transaction(F).  

    9、Delete 查询

    [plain] view plaincopy
     
    1. %%===============================================  
    2. %%   delete from y_account where id=5  
    3. %%===============================================  
    4.   
    5. %% 使用 mnesia:delete  
    6. F = fun() ->  
    7.     mnesia:delete({y_account, 5})  
    8. end,  
    9. mnesia:transaction(F).  


    注:使用qlc模块查询,需要在文件顶部声明“-include_lib("stdlib/include/qlc.hrl").”,否则编译时会产生“Warning: qlc:q/1 called, but "qlc.hrl" not included”的警告。

    更新说明:

    2013/11/20 补充了 mnesia:select 方式的 limit 查询

  • 相关阅读:
    HDU4628+状态压缩DP
    Javascript 去掉字符串前后空格的五种方法
    Javascript 数组之判断取值和数组取值
    ASP.NET MVC 出现错误 “The view 'XXX' or its master was not found or no view engine support”
    ASP.NET MVC 页面调整并传递参数
    ASP.NET MV3 部署网站 报"Could not load file or assembly ' System.Web.Helpers “ 错的解决方法
    ASP.NET MVC 控制器向View传值的三种方法
    CSharp 如何通过拼接XML调用存储过程来查询数据
    SQLServer : EXEC和sp_executesql的区别
    关于SQLServer2005的学习笔记—异常捕获及处理
  • 原文地址:https://www.cnblogs.com/xuan52rock/p/4601810.html
Copyright © 2011-2022 走看看