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}]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)