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