Erlang大量數據的存儲機制:ETS和DETS


1. ETS和DETS簡介
ETS(Erlang Term Storage )和DETS(Dist  ETS)是Erlang用於高效存儲大量Erlang數據條目的系統模塊。
ETS與DETS的比較:
相同:ETS和DETS都提供大型的“鍵-值”搜索表。
 
不同:
ETS駐留在內存,DETS駐留在硬盤。
ETS存儲是臨時的,DETS中的數據存儲是持久的。
ETS非常高效,在ETS中,無論你存儲多少數據,查詢速度都與之無關(特定情況成對數關系),前提是擁有足夠大的內存。
DETS相對效率要低很多,但比ETS更加節省內存。
ETS表和DETS表可以被多個進程共享,可以通過這兩個模塊實現進程間高效的數據交換。
ETS不是由Erlang本身來實現的,而是由底層運行時系統來實現的。相比一般的Erlang對象,ETS有很多不同。如,ETS不會被垃圾回收。
ETS或DETS,本質就是一系列Erlang元組。
 
2. 表的基本操作
1. 創建新表或打開一個已存在的表:ets:new() 或 dets:open_file()
2. 將一個或多個元組插入表:insert(TableName,X) 。 X是一個元組或元組的列表。
3. 在表中查找元組:lookup(TableName,Key)     返回匹配Key的元組列表
4. 釋放表:dets:close(TableId)  或ets:delete(TableId)
 
3. 表的類型:(4種)
set    ordered set    bag    duplicate bag
類型為set的表,要求所有元組的鍵值各不相同;
ordered set表,按鍵值大小排序。
類型為bag的表,允許多個元組有相同的鍵值,但不允許有相同的元組。
類型為duplicate bag的表,允許有多個相同的元組。
 
4. ETS舉例:ets_test.erl
-module(ets_test).
-export([start/0]).
 
start() ->
    lists:foreach(fun test_ets/1,
                        [set,ordered_set,bag,duplicate_bag]).     
test_ets(Mode) ->
    TableId = ets:new(test_ets,[public,named_table,Mode]),
    ets:insert(TableId,{a,1}),
    ets:insert(TableId,{b,2}),
    ets:insert(TableId,{a,1}),
    ets:insert(TableId,{a,3}),
    %%因建立ets表時,使用了named_table模式,所以使用ets表時可直接使用ets表的Name
    List = ets:tab2list(test_ets),      
    io:format("~-13w =>~p~n",[Mode,List]),
    ets:delete(test_ets).
運行結果:
1> ets_test:start().
set           =>[{b,2},{a,3}]            注:set每個鍵值只允許出現一次,所以{a,1}最終被{a,3}覆蓋。
ordered_set   =>[{a,3},{b,2}]    
bag           =>[{b,2},{a,1},{a,3}]
duplicate_bag =>[{b,2},{a,1},{a,1},{a,3}]
 
5. ETS的效率考慮
1. 在內部,ETS表是用散列來表示的(除了ordered set是用平衡二叉樹來表示的)
所以set有點浪費空間,ordered set有點浪費時間。set表插入數據所耗費時間是常量,而order set插入所耗時間與表的大小成對數關系。
bag比duplicate bag的使用代價要高,因為每次插入都要比較鍵值。
2. ETS表與正常的進程存儲空間分離,不會進行垃圾回收。
3. ETS表隸屬於創建他的進程,當這個進程死掉或者調用ets:delete,這個表就被刪掉。
4. 在進程之間發送大量二進制數據的消息,或者向ETS表中插入包含二進制數據的元組,代價都很低。
    因此,盡可能地用二進制數據表示字符串或大塊的無類型數據,是一種高效的編程方式。
 
6. ETS表的創建:
ets:new(Name,[Option])
Name是表的名字,是一個原子atom。
OPtion是選項列表,取值如下:
set | ordered_set | bag | duplicate_bag
private | protected | public 
named_table  表示可使用Name來操作表
{Keypos,K}
打開一個ETS表時不帶任何選項,則默認選項是[ets,proteced,{keypos,1}]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM