Elixir - Lưu trữ dữ liệu trên RAM với ETS
elixir
35
Erlang
14
White

Dung Nguyen viết ngày 13/05/2018

Bài viết gốc trên http://bluzky.github.io

ETS là gì?

Có lẽ các bạn đã nghe qua về redis hoặc memcache, hoặc là cả hai. Còn nếu bạn chưa nghe tới bao giờ thì đó là những cơ sở dữ liệu lưu trữ trên RAM với ưu điểm là tốc độ truy xuất cực kỳ nhanh. ETS - Erlang Term Service - cũng là một CSDL lưu trữ trên RAM (in-ram DB) nhưng khác ở chỗ là ETS có sẵn khi cài Elixir/Erlang và bạn chẳng phải mất công cài đặt, cấu hình như 2 anh trên kia, nhà trồng được việc gì phải ngại.

Đặc điểm của em nó là:

  • Không cần cài đặt
  • Dữ liệu lưu trữ trên RAM và mất đi khi process kết thúc
  • Dữ liệu lưu trữ dạng key-value
  • value có thể là set, ordered_set, bag, duplicated_bag
  • Kiểu dữ liệu của value trên cùng 1 bảng là giống nhau và đuợc khai báo khi tạo bảng.

Các thao tác trong ETS

1. Tạo bảng

iex> :ets.new(:cache, [:set, :protected, :named_table])

*Syntax: * :ets.new(ten_bang, [type, access, name_table])

  • type là kiểu dữ liệu của value lưu trong bảng
    • set là kiểu dữ liệu, chú này chung thuỷ chỉ có 1 value cho 1 key và key là duy nhất, không bị trùng.
    • ordered_set thằng em nghiêm túc của set, khác thằng anh ở chỗ đuợc tự động order khi thêm data vào.
    • bag khác với set ở chỗ chú này chơi harem, cho phép nhiều value cho cùng 1 key, tuy nhiên các value không đuợc trùng nhau.
    • duplicated_bag thằng này ăn tạp giống bag nhưng cho phép value trùng nhau
  • access giới hạn khả năng truy xuất dữ liệu từ bảng, cũng khá dễ nhớ
    • public: hàng công cộng, chú process nào thích nhìn (đọc), sờ (ghi) gì anh cho hết
    • protected: các chú chỉ đuợc nhìn thôi, anh sở hữu thì anh đuợc sờ
    • private: anh giấu hết, chỉ có anh mới đuợc nhìn và sờ, các chú đi ra chỗ khác
  • named_table Cái này tuỳ chọn, bình thuờng thì sẽ trả về 1 id dùng để truy xuất vào table. Nếu thêm option này vào thì có thể dùng ten_bang để truy xuất vào table.

Đã xong phần khởi tạo, giờ phần hay ho nhất đây.

2. Insert và update dữ liệu

  • Insert dữ liệu nếu key đã có chủ thì ghi đè (đập chậu cuớp bông)
iex> :ets.insert(:cache, {"post-1", "world!", %{view: 1}})
true
  • Insert dữ liệu, nếu key đã có chủ thì bỏ qua.
iex> :ets.insert_new(:cache, {"post-1", "Lao!", %{view: 2}})
false
iex> :ets.insert_new(:cache, {"post-2", "Vietnam!", %{view: 999}})
true

Dữ liệu cho hàm insert/2insert_new/2 là 1 tuple, phần tử đầu tiên của tuple mặc định được dùng làm key.

3. Query dữ liệu

3.1 Query đơn giản: tìm kiếm dữ liệu theo key dùng hàm lookup/2

iex> :ets.lookup(:cache, "post-1")
[{"post-1", "world!", %{view: 1}}]

3.2 Query với nhiều trường dữ liệu với hàm match_object/2

iex> :ets.match_object(:cache, {:"_", "Vietnam!", :"_"})
[{"post-2", "Vietnam!", %{view: 999}}]
  • Note :"_" đánh dấu tại vị trí này sẽ không xài để match dữ liệu, truờng này chứa dữ liệu gì cũng đuợc, anh không quan tâm

3.3 Select trường dữ liệu nào sẽ trả về với match/2

iex> :ets.match_object(:cache, {:"$1", :"$2", :"_"})
[{"post-1", "world!"}, {"post-2", "Vietnam!"}]
  • Note :"$N" dùng để select kết quả trả về, N là một số nguyên dùng để xác định vị trí của dữ liệu trong kết quả.
iex> :ets.match_object(:cache, {:"$30", :"$2", :"_"})
[{"world!", "post-1"}, {"Vietnam!", "post-2"}]

3.4 Giới hạn kết quả tra về

Sử dụng hàm match/3 hoặc match_object/3 tương tự như match/2match_object/2, trong đó tham số thứ 3 là số lượng phần tử sẽ trả về.

# them 1 phan tu
iex> :ets.insert_new(:cache, {"post-3", "Vietnam!", %{view: 1000}})
true

# khong limit
iex> :ets.match_object(:cache, {:"_", "Vietnam!", :"_"})
[{"post-2", "Vietnam!", %{view: 999}}, {"post-3", "Vietnam!", %{view: 1000}}]

# co limit
iex> :ets.match_object(:cache, {:"_", "Vietnam!", :"_"}, 1)
[{"post-2", "Vietnam!", %{view: 999}}]

4. Xoá dữ liệu

Xoá theo key

iex> :ets.delete(:cache, "post-1")
true

Match dữ liệu và xoá. Cách match giống như trong query dữ liệu

iex> :ets.match_delete(:cache, {:"_", "Vietnam!", :"_"})
true

5. Xoá bảng

iex> :ets.delete(:cache)
true

Nếu không xoá thì dữ liệu sẽ tồn tại cho đến khi process kết thúc mới bị mất đi.

6. Các hàm hay xài

  • member/2 kiểm tra xem key đã tồn taị trong bảng hay chưa

  • tab2list: đọc tất cả dữ liệu của bảng vào 1 list

  • tab2file: lưu tất cả dữ liệu trên bảng vào 1 file, bạn có thể lưu dữ liệu lại truớc khi process kết thúc và có thể xài lại dữ liệu sau.

  • file2tab : đọc 1 file đuợc lưu bởi tab2file và tạo lại bảng tương ứng

  • to_dest/2: copy toàn bộ dữ liệu từ bảng ETS qua bảng DETS (lưu dữ liệu trên ổ cứng)

  • from_dest/2: copy toàn bộ dữ liệu từ bảng DETS qua bảng ETS

Tham khảo

  1. http://erlang.org/doc/man/ets.html xem nhiều trò hay
  2. http://learnyousomeerlang.com/ets
  3. Ngoài ra Erlang còn hỗ trợ DETS (disk-based term storage) lưu trên ổ cứng với API tương tự http://erlang.org/doc/man/dets.html
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Dung Nguyen

4 bài viết.
2 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
4 0
1. Tìm hiểu về FSM (Link) Máy trạng thái hữu hạn là một mô hình toán học biểu diễn trạng thái của hệ, trong đó số trạng thái là hữu hạn. Từ mỗi t...
Dung Nguyen viết 7 tháng trước
4 0
White
3 4
Bài viết này đuợc lấy từ blog cá nhân http://bluzky.github.io/ Trong quá trình tìm hiểu về lập trình chat bot sử dụng các API của Facebook Messen...
Dung Nguyen viết 7 tháng trước
3 4
White
1 0
Xem bài viết gốc trên (Link) Bài viết này sẽ hướng dẫn các bạn sử dụng ETS như là bộ nhớ cache để tăng tốc các ứng dụng web Phoenix Dành cho ...
Dung Nguyen viết 7 tháng trước
1 0
Bài viết liên quan
White
9 6
Chưa xem phần 2? Xem (Link) Trong bài viết này tôi giới thiệu cho các bạn về khái niệm function arity, một cách gọi mĩ miều của số lượng argument ...
Lơi Rệ viết hơn 3 năm trước
9 6
White
6 0
Bạn đang viết application với Elixir? Bạn sắp release sản phẩm hay đơn giản thỉnh thoảng bạn không biết tại sao service A lại lăn đùng ra chết hay ...
Trần Việt Thắng viết 2 tháng trước
6 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
4 bài viết.
2 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!