EAV có gì hot?

Kiều Anh Vũ
CG Writing
Published in
5 min readApr 15, 2020

Giới thiệu:

EAV là viết tắt của Entity Attribute Value. Đối với những hệ cơ sở thông thường thì mỗi bảng sẽ là một attribute còn ở đây mỗi bảng của nó sẽ là một entity và bên trong entity sẽ chứa các attribute và trong mỗi attribute sẽ có value.

Mình hi vọng qua bài đọc này mình sẽ giúp các bạn hiểu hơn về cơ sở dữ liệu của mô hình EAV?

Vậy chúng ta hãy cùng nhau tìm hiểu xem EAV có nghĩa là gì?

Về cơ bản, EAV là một nguồn thiết kế schema mở cho phép bạn tạo 1 schema sinh động mà không yêu cầu bất kì sự thay đổi nào của schema đó để mô hình hóa việc thiết lập cho các thuộc tính khác nhau cho các thực thể cụ thể.

Mình muốn hướng dẫn bạn đi đến quyết định sử dụng EAV cho cơ sở dữ liệu như thế nào. Làm thế nào để hiểu EAV là gì và cách chúng ta thực hiện chúng ta sẽ vẽ 1 số bảng.

Giả sử, chúng ta cần quản lý thông tin của khách hàng và họ muốn đăng ký và mua từ cửa hàng của chúng ta.

Chúng ta cần gì để mô tả về khách hàng?

Bạn có thể có bảng customers với một số cột trong bảng để mô tả khách hàng, bao gồm: ID, name, address, phone, zipcode.

Bây giờ tiếp tục mô tả khách hàng.

Khách hàng đầu tiên, tên của khách hàng này là Hoàng Dư và ở 123 Đê La Thành, số điện thoại: 555–5555 và mã vùng là 12345.

Nếu chúng ta có một khách hàng mà muốn có 1 thỏa thuận khác với chúng ta Ví dụ chúng ta sẽ giảm giá cho họ mỗi lần họ mua hàng. Chúng ta có 1 khách hàng tên Quân Nguyễn, ở địa chỉ 234 Khâm Thiên, số điện thoại 123–1234 và mã vùng là 23456.

bảng customers

Và làm thế nào để chúng ta nói cho chương trình biết rằng Quân Nguyễn đủ điều kiện để được giảm giá mà Hoàng Dư thì không.

Thay vì thêm 1 cột discount_amount vào bảng customers như hình sau:

Trong phần này, giả sử Hoang Du và Chau Le có chung một mức giảm giá, trong trường hợp ta muốn thay đổi mức giảm giá của một nhóm đối tượng, ta cần thay đổi giá trị của tất cả những bản ghi thuộc nhóm này.

Ta có một cách khác để giải quyết vấn đề trên

Chúng ta có thể cần một bảng chứa thông tin về nhóm khách hàng CustomerGroup và một bảng chứa mức giảm giá tương ứng Discount.

Bằng cách này ta có thể có nhiều mức giảm giá cho từng loại đối tượng khách hàng. Nếu muốn thay đổi đồng loạt mức giảm giá với từng loại đối tượng khách hàng ta chỉ cần thay đổi amount ở nhóm tương ứng.

Đây là cách mà chúng ta loại bỏ một số thông tin không quan trọng ra khỏi bảng.

Giờ đây ta cần có thêm thông tin về Shipper (ví dụ tên Công ty: Grab, GoViet, Bee, Giao hàng nhanh, Giao hàng tiết kiệm,… và Ngày vận chuyển) còn với khách hàng đã đăng ký tài khoản thì ta cần có ngày sinh của khách hàng. Ta có thể thấy ở đây cột dob, cột vender_name, cột vender_shipdate chỉ có giá trị cho một số bản ghi, một số bản ghi thì không.

Điều hấp dẫn đến rồi, với EAV chúng ta có thể có một bảng Attribute để chứa các thuộc tính như dob, vender_name, vender_shipdate.

Chúng ta tạo thêm 1 bảng Value (bảng này cần có khóa ngoại attribute_id là id của bảng Attribute, entity_id từ bảng Customer và value tương ứng). Nhờ cách này mà ta không cần đến cột dob, vender_name, vender_shipdate.

Điểm mạnh của EAV là chúng ta thay đổi schema nhưng không thay đổi thông tin của 1 bảng cũ, không bị dư thừa dữ liệu, không bị trùng lặp thông tin.

Ta có thể cải tiến hơn nữa, bảng Value của chúng ta có chứa nhiều kiểu dữ liệu Datetime và NVChar, ta có thể tách ra thành 2 bảng như sau:

Tương tự với các kiểu dữ liệu khác nếu có.

Tiếp tục, giờ chúng ta muốn quản lý thêm danh sách sản phẩm có trong cửa hàng. Ta có bảng Product với các cột id, mã sản phẩm, giá sản phẩm.

Từ mã sản phẩm, chúng ta muốn có thêm tên sản phẩm, ta sẽ thêm 1 bản ghi vào bảng Attribute với lable là “product_name”, đồng thời thêm vào bảng Varchar 1 bản ghi để thể hiện tên tương ứng của sản phẩm.

Ở đây, cột entity_id không phân biệt được id của bảng Customers và id của của Product. Vậy chúng ta cần thêm 1 bảng nữa để mô tả loại thực thể. EntityType và thêm cột entity_type ở bảng Attribute. Vậy là chúng ta đã rõ được là Attribute nào thì thuộc Entity nào rồi.

Cùng nhìn lại cơ sở dữ liệu của chúng ta

--

--