Erlang ETS #

一、ETS概述 #

ETS(Erlang Term Storage)是Erlang内置的内存键值存储。

1.1 特点 #

  • 内存存储
  • 高性能
  • 支持多种表类型
  • 进程间共享数据

二、创建表 #

2.1 基本创建 #

erlang
-module(ets_create).
-export([demo/0]).

demo() ->
    Table = ets:new(my_table, []),
    io:format("Table: ~p~n", [Table]),
    ets:delete(Table).

2.2 表选项 #

选项 说明
set 键值对,键唯一
ordered_set 有序键值对
bag 允许重复键
duplicate_bag 允许完全重复
public 任何进程可读写
protected 所有者可写,其他可读
private 仅所有者可读写
named_table 使用原子名访问
{keypos, Pos} 键位置

2.3 命名表 #

erlang
-module(named_table).
-export([demo/0]).

demo() ->
    ets:new(users, [named_table, public, set]),
    ets:insert(users, {1, "Alice"}),
    io:format("Users: ~p~n", [ets:tab2list(users)]),
    ets:delete(users).

三、数据操作 #

3.1 插入数据 #

erlang
-module(ets_insert).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, {key1, value1}),
    ets:insert(Table, [{key2, value2}, {key3, value3}]),
    io:format("Data: ~p~n", [ets:tab2list(Table)]),
    ets:delete(Table).

3.2 查询数据 #

erlang
-module(ets_lookup).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, [{a, 1}, {b, 2}, {c, 3}]),
    
    Value = ets:lookup(Table, a),
    All = ets:tab2list(Table),
    
    io:format("Lookup a: ~p~n", [Value]),
    io:format("All: ~p~n", [All]),
    ets:delete(Table).

3.3 删除数据 #

erlang
-module(ets_delete).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, [{a, 1}, {b, 2}]),
    
    ets:delete(Table, a),
    ets:delete_all_objects(Table),
    
    ets:delete(Table).

3.4 更新数据 #

erlang
-module(ets_update).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, {counter, 0}),
    
    ets:update_counter(Table, counter, 1),
    ets:update_counter(Table, counter, {2, 10}),
    
    io:format("Counter: ~p~n", [ets:lookup(Table, counter)]),
    ets:delete(Table).

四、表类型 #

4.1 set #

erlang
Table = ets:new(set_table, [set]).
ets:insert(Table, {key, value1}).
ets:insert(Table, {key, value2}).

键唯一,后插入的覆盖前面的。

4.2 ordered_set #

erlang
Table = ets:new(ordered_table, [ordered_set]).
ets:insert(Table, [{3, c}, {1, a}, {2, b}]).

按键排序。

4.3 bag #

erlang
Table = ets:new(bag_table, [bag]).
ets:insert(Table, [{key, 1}, {key, 2}]).

允许相同键不同值。

4.4 duplicate_bag #

erlang
Table = ets:new(dup_bag_table, [duplicate_bag]).
ets:insert(Table, [{key, 1}, {key, 1}]).

允许完全重复。

五、匹配操作 #

5.1 match #

erlang
-module(ets_match).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, [{a, 1}, {b, 2}, {c, 3}]),
    
    All = ets:match(Table, {'$1', '$2'}),
    Keys = ets:match(Table, {'$1', '_'}),
    
    io:format("All: ~p~n", [All]),
    io:format("Keys: ~p~n", [Keys]),
    ets:delete(Table).

5.2 match_object #

erlang
-module(ets_match_object).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, [{a, 1}, {b, 2}, {c, 3}]),
    
    Objects = ets:match_object(Table, {'_', 2}),
    io:format("Objects: ~p~n", [Objects]),
    ets:delete(Table).

5.3 select #

erlang
-module(ets_select).
-export([demo/0]).

demo() ->
    Table = ets:new(test, []),
    ets:insert(Table, [{a, 1}, {b, 2}, {c, 3}]),
    
    MatchSpec = [{
        {'$1', '$2'},
        [{'>', '$2', 1}],
        ['$1']
    }],
    Result = ets:select(Table, MatchSpec),
    io:format("Result: ~p~n", [Result]),
    ets:delete(Table).

六、实际应用 #

6.1 缓存 #

erlang
-module(cache_ets).
-export([start/0, get/1, put/2, delete/1]).

start() ->
    ets:new(cache, [named_table, public, set]).

get(Key) ->
    case ets:lookup(cache, Key) of
        [] -> undefined;
        [{Key, Value}] -> Value
    end.

put(Key, Value) ->
    ets:insert(cache, {Key, Value}).

delete(Key) ->
    ets:delete(cache, Key).

6.2 计数器 #

erlang
-module(counter_ets).
-export([start/0, increment/1, decrement/1, value/1]).

start() ->
    ets:new(counters, [named_table, public, set]).

increment(Name) ->
    ets:update_counter(counters, Name, 1).

decrement(Name) ->
    ets:update_counter(counters, Name, -1).

value(Name) ->
    case ets:lookup(counters, Name) of
        [] -> 0;
        [{Name, Value}] -> Value
    end.

七、最佳实践 #

7.1 表所有权 #

erlang
-module(table_owner).
-export([start/0]).

start() ->
    spawn(fun() ->
        Table = ets:new(my_table, []),
        loop(Table)
    end).

loop(Table) ->
    receive
        stop -> ets:delete(Table);
        _ -> loop(Table)
    end.

7.2 使用heir选项 #

erlang
-module(heir_table).
-export([start/0]).

start() ->
    Owner = self(),
    Table = ets:new(my_table, [{heir, Owner, inherited}]),
    Table.

八、总结 #

本章学习了:

  • ETS概述
  • 创建表
  • 数据操作
  • 表类型
  • 匹配操作
  • 实际应用
  • 最佳实践
最后更新:2026-03-27