特点
1.ETS常驻内存,存储键值表,可以被多个进程共享。
2. 当ETS表被丢弃或控制它的erlang进程终止,ETS表中的数据就会被清除。
3. ETS表中保存元组,元组中默认第一个元素是元组的键,通过键向表里插入和提取元组。
4. ETS表分为异键表(各个元组中的键是唯一的)、有序异键表(键唯一并且元组被排序)、同键表(键可以不唯一)和副本同键表(键不唯一并且有相同的元组)
基本操作
- 创建新表或打开现有表
spec ets:new(Name, [Opt]) -> TableId
Opt选项:默认情况下[Opt]为[set, prtected, {keypos, 1}]。
- 类型: set, ordered_set, bag, duplicate_bag
- private(私有表,只有创建表的进程能读取写入)、public(公共表,任何进程都可以读取写入,用户必须确保读取和写入互不冲突)、protected(受保护的表,任何进程都可以读取,只有创建表的进程才能写入)
- named_table,设置了此选项,Name可用于后续表的操作
- {keypos, K},设置元组中键的位置。
Modes = [set, ordered_set, bag, duplicate_bag].
lists:foreach(func(Mode) ->
TableId = ets:new(test, [named_table, Mode, private])
end, Modes).
- 向表中插入一个或多个元组
ets:insert(TableId, [{a, 1}, {b, 2}]).
ets:insert(TableId, {c, 3}).
- 在表里查找某个元组
lookup(TableId, Key),查询匹配Key的元组列表 - 删除表
ets:delete(TableId)
ETS表的效率
- 异键表与有序异键表
异键表使用散列表表示,插入时间恒定,有空间开销;
有序异键表用平衡二叉树表示,插入时间为logN。 - 同键表和副本同键表
使用散列表表示,同键表在每次插入时需要与ETS表中所有相同键的元组比较是否相等,比副本同键表更低效。 - 存储
ETS表保存在单独的存储区域,与正常的内存进程无关,被创建它的进程所有,当进程挂了或者使用ets:delete,表被删除。
插入元组时,将数据从进程栈复制到ETS表,查询表时,将找到的元组复制到进程栈。
二进制存储在自己的堆外存储区域,可以被多个进程和ETS共享,在进程间传递二进制数据非常高效,向ETS插入包含二进制的元组也非常高效。