Mnesia 和 ETS 都是 Erlang 提供的表管理工具,用于存储和检索数据,但它们之间有一些重要的区别和共同点。
共同点
都是Erlang提供的表存储机制:ETS 和 Mnesia 都允许你在内存中创建表,并且可以用来存储键值对或者更复杂的数据结构。
支持模式匹配:两者都支持 Erlang 的模式匹配特性,使得你可以通过模式来查找表中的元素。
提供了API:都有相应的 API 可以用来插入、删除、查找数据。
区别
事务支持:Mnesia 支持事务,而 ETS 不支持。这意味着在 Mnesia 中,你可以执行一系列的操作作为一个整体,要么全部成功,要么全部失败。
分布式支持:Mnesia 是一个分布式数据库系统,可以在多个节点上复制数据,而 ETS 只存在于单个节点上。
持久化选项:Mnesia 提供了持久化存储的选择,如 disc_copies 或 disc_only_copies,而 ETS 数据默认只存在于内存中,进程退出后数据就会丢失。
性能:对于简单的键值查询,ETS 性能优于 Mnesia。这是因为 ETS 的开销较低,而 Mnesia 由于其分布式特性和事务支持,会有更多的开销。
应用场景:Mnesia 更适合于需要分布式存储和事务支持的应用场景,而 ETS 则更适合于简单的、不需要持久化的数据存储需求。
并发控制:Mnesia 在锁机制和并发控制方面比 ETS 更加完善,特别是在分布式环境中
下面是测试代码,将存储在mnesia数据库中的数据读取进ets中
-module(test_mnesia).
-include_lib("stdlib/include/qlc.hrl").-record(goods, {name, money, num}).
%% API
-export([create_ets/0,check/1,test/1,insert/3, select/0, select/1, delete/1,start/0, do_this_once/0]).
start() ->mnesia:start().%%mnesia增删查实现,替换这一块还没具体研究,好像可以替换某个键相同的记录
insert(Name, Money, Num) ->Row = #goods{name = Name, money = Money, num = Num},io:format("insert ~p~n", [Row]),F = fun() ->mnesia:write(Row)end,mnesia:transaction(F).delete(Item) ->Oid = {shop, Item},io:format("delete ~p~n", [Oid]),F = fun() ->mnesia:delete(Oid)end,mnesia:transaction(F).select() ->do(qlc:q([X || X <- mnesia:table(goods)])).
select(Num) ->do(qlc:q([X || X <- mnesia:table(goods), X#goods.num =< Num])).do(Q) ->F = fun() ->qlc:e(Q)end,{atomic, Val} = mnesia:transaction(F),Val.create_ets() -> %%创建ets表ets:new(ets_goods,[named_table, public]).
test(TableId) ->List = select(), %%找出数据库中的数据Fun = fun(Record) ->ets:insert(TableId, Record)end,lists:foreach(Fun,List). %%遍历存放进ets表中
check(TableId) -> %%查看ets中存储数据ets:tab2list(TableId).do_this_once() ->mnesia:create_schema([node()]),mnesia:start(),mnesia:create_table(goods, [{attributes, record_info(fields, goods)}]),mnesia:stop().
以下是测试截图
我插入了两个数据,但是ets中只装了一个,暂时不清楚是什么bug