Erlang/Elixir native storage - Erlang Term Storage

2015-07-30, Thursday
elixir

先來一段聳動的開頭….

ETS stands for Erlang Term Storage.
It's a means of storing large quantities of data in an Erlang Runtime System with the ability to access it in constant-time.

wow 自帶資料庫的程式語言耶…

ETS (Erlang Term Storage) 是 Erlang提供的一個 native build in 的databese 格式.
雖然現在也有許多NoSql的資料庫可以使用,但是Native可以提供我們不少的好處
(在分散式的架構下.), 本篇Blog我將針對Elixr中使用ETS做簡單的介紹.

#開啟Elixir shell
iex

#產生一個ets table. 裡面儲存的是bag struct的資料
user = :ets.new(:user, [:bag, :named_table])

#三筆使用者資料
user3 = {"Mike", M , 2000, %{ :phone => "02 123-456-789"}}
user2 = {"Sally", "F" , 1990}
user1 = {"Masato", "M" , 1985}

#insert them into ets table
:ets.insert(:user, user1)
:ets.insert(:user, user2)
:ets.insert(:user, user3)

#給我一筆資料, 預設只會回覆第一個欄位
:ets.first(:user) #=> Mike

通常ets會將第一個欄位作為key, 使用者可以透過key快速的找尋你要的資料

:ets.lookup(:user, "Masato") #=> [{"Masato", "M", 1985}]

But!我們有時候想找的東西更複雜耶!

:ets.match_object(:user, {:_, :_, 1985}) #=> [{"Masato", "M", 1985}]
:ets.match_object(:user, {:_, :_, 2000}) #=> []
:ets.match_object(:user, {:_, :_, 2000, :_}) #=> [{"Mike", "M", 2000, %{phone: "02 123-456-789"}}]

Good! 完全發揮pattern的專長效果.But! 我還想更複雜耶

query_rule = [{
                { :_, :_, :"$1", :_ },
                [{:andalso, { :'>=', :"$1", 1988 }}],
                [:"$_"]
              }]
:ets.select(:user, query_rule) #=> [{"Mike", "M", 2000, %{phone: "02 123-456-789"}}]

以上都是in memorry database的操作.如果想讓資料放置在disk

  # new table
  dets_file = "cars.dets"
  {:ok, user} = :dets.open_file(:user, [file: :dets_file, type: :bag])

  # remove table
  :dets.close(:user)
  File.rm(dets_file)

大致上其他操作都和ets相同.

小結

有時候運算資料的時候,想找的地方存,但是不想要在開啟其他database的時候,
ets是個不錯的選擇!而且可以在分散式 elixir node中使用! 缺點是可以參考的資料少了一點.

可能有興趣的文章: