本文最后更新于:June 30, 2023 pm
ETS 表可以用来高效存储海量的erlang数据,ETS提供大型的键-值查询表,
1.四种不同的类型
集合(set)
相同的key-value元组只能出现一次。
包(bag)
每种key-value元组组合只能出现一次,但是同一个key可以出现多次。
重复包(duplicate bag)
允许重复的元组。
有序集合(ordered set)
相同的key-value元组只能出现一次,但是可以按key的顺序访问各个元组。
访问有序集合(ordered set)类型中的元素需要消耗表长度的对数级别的时间(oLog n),访问其余类型的元素只需要消耗常量级别的时间。
2.表权限
public
允许任何进程访问(读写)。
private
只有拥有该表的进程才能访问。
protected
任何进程都可以读,只有拥有该表的进程才能写入。
3.其它参数
{keypos, N}
创建表的时候可以通过 {keypos, N} 指定键取自那个位置,对存储记录record非常的有用。
named_table
如果存在此选项,则以表的名称注册该表,然后在后续的操作使用该表名称而不是表的标识符。要获取指定标的标识符,可以使用 whereis/1。
{write_concurrency, boolean()}
默认为false。这种情况下,对表的写入修改的操作获得独占访问,阻塞对同一表的任何并发访问。如果设置为true,则表将优化为并发写访问。
{read_concurrency, boolean()}
默认为false。如果设置为true,则该表将优化为并发读访问。
compressed
压缩,如果存在此选项,那么将以更紧凑的格式存储表数据,以消耗更少的内存。但是,这会使表操作变慢。特别是需要查找整个对象(如match,select)这种操作,速度会慢很多,关键元素不会被压缩。
4. 匹配
ETS的查询方式遵循模式匹配,下面用例子说明:
表结构 :
#trap_client_info{id , client_id ,auth ,transport ,socket ,ip }
匹配:
ets:match(trap_connection_table,{'_',{trap_client_info,'$1','$2', '$3', '$4','$5','$6'}}).
结果:
[[1,<<"4d45d94142276ad38364049c56d8ed43">>,
{127,0,0,1},
true,esockd_transport,#Port<0.48>]]
ets:match(trap_connection_table,{'_',{trap_client_info,'$1','$2', '$3', '$4','$5','_'}}).
结果:
[[1,<<"4d45d94142276ad38364049c56d8ed43">>,
{127,0,0,1},
true,esockd_transport]]
通过上面的两个匹配语句,我们发现规律:
- 如果要匹配指定的字段,我们可以用’$N’原子来实现
- 如果过滤字段,我们用’_’原子来实现。
想一下SQL的写法:select * from trap_connection_table;
对应:
ets:match(trap_connection_table,{'_',{trap_client_info,'$1','$2', '$3', '$4','$5','$6'}}).
select id,client_id from trap_connection_table;
对应:
ets:match(trap_connection_table,{'_',{trap_client_info,'$1','$2', '_', '_','_','_'}}).
注意:$N会根据N进行排序,数字越大顺序越后。’_’表示我们忽略不要的字段。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!