Mục tiêu:Bạn muốn lưu trữ thuộc tính liên quan đến một thực thể nhất định.
Tôi không đề xuất một bảng riêng biệt cho các giá trị thuộc tính như chúng tôi có thể đã làm trong nhiều năm trôi qua. Đặt một jsonb
trường ngay trên bảng thích hợp và gọi nó là Attributes
. Thêm GIN
lập chỉ mục cho nó để bạn có thể truy vấn các giá trị một cách nhanh chóng. Hoặc sử dụng các kỹ thuật khác được mô tả trong.
Đọc phần này: https://dba.stackexchange.com/a/174421/7762
Câu hỏi lớn nhất ở đây là nếu bạn có ý định xác định trước các giá trị thuộc tính. Nếu bạn làm vậy, có một cách cực kỳ hiệu quả để lưu trữ chúng. Nếu không, thì tôi đề xuất một đối tượng JSON chuẩn.
Nếu bạn có thể xác định trước tên thuộc tính VÀ giá trị của mình:
Điều này mang lại cho bạn khả năng kiểm soát, tốc độ cao nhất và vẫn mang lại sự linh hoạt.
Tạo bảng Attributes
có các trường sau:
-
AttributeID int4 unsigned not null primary key
-
ParentAttributeID int4 unsigned null
-
Name varchar(64) not null
-
Deleted
bool không null mặc định sai - Thêm chỉ mục trên
ParentAttributeID
- Thêm trình kích hoạt để ngăn
AttributeID
khỏi thay đổi - Thêm quy tắc về xóa, thay vào đó đặt Đã xóa =Đúng
Sau đó, trong bất kỳ bảng nào bạn muốn thuộc tính, hãy thêm trường này:
-
AttributeSet" int[] not null default
- Thêm chỉ mục GIN trên trường mảng đó
- Đồng thời bật
intarray
tiện ích mở rộng từ https://www.postgresql.org/docs/current/static /intarray.html
Điều này đã đạt được những gì?
Bạn đã tạo một cây thuộc tính. Nó có thể trông như thế này:
ID Parent Name
----------------------------
100 NULL Color
101 100 Blue
102 100 Red
103 100 Green
110 NULL Size
111 110 Large
112 110 Medium
113 110 Small
Giả sử bạn có một bảng được gọi là Items
và trên đó bạn đã thêm AttributeSet
:
ItemID: 1234
Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]
Khi được dịch, điều này có nghĩa là nó có Color=Green
và thuộc tính Size=Medium
thuộc tính. 103
và 112
đã đủ để lưu trữ điều đó, nhưng đôi khi thật tuyệt khi có thể nói "Cho tôi xem tất cả các mặt hàng có bất kỳ Kích thước nào được xác định", đó là lý do tại sao 110 được bao gồm.
Bạn có thể làm cho điều này nhanh như chớp và cực kỳ linh hoạt.
SELECT
"ItemID", "Name"
FROM
"Items"
WHERE "AttributeMap" @> ARRAY[103,112]
Sẽ trả lại tất cả các mục có Size=Medium
và Color=Green
Hoặc bạn có thể sử dụng các toán tử khác trên https://www.postgresql .org / docs / 10 / static / functions-array.html để đưa ra một số truy vấn tuyệt vời.
Khi bạn không biết các giá trị thuộc tính nhưng đó là một tập hợp nhỏ:
Điều này mang lại cho bạn tốc độ, khả năng kiểm soát và thậm chí còn linh hoạt hơn. Bạn có thể gắn cờ các thuộc tính mới để xem xét nếu cần.
Bạn có thể sử dụng kỹ thuật trên và chỉ cần thêm động các giá trị vào Attributes
bảng nếu chúng không tồn tại.
Khi bạn không biết các giá trị thuộc tính và các giá trị đa dạng
Điều này mang lại cho bạn sự linh hoạt nhất nhưng với chi phí kiểm soát.
Trong trường hợp này, chỉ cần thêm cái này vào bất kỳ bảng nào:
-
AttributeMap jsonb not null default '{}'::jsonb
- Thêm chỉ mục GIN vào trường đó
Viết mã để xác thực các giá trị so với Attributes
của bạn bàn. Có một chỉ báo ở đó nếu nó là một giá trị đơn lẻ hoặc nhiều giá trị ...
Lưu trữ như thế này trong AttributeMap
lĩnh vực:
{
"Color": "Green",
"Size": "Medium",
"Categories": ["Sports", "Leisure"]
}
Lưu ý rằng Danh mục là một đa thuộc tính. Trong Attributes
của bạn bảng bạn phải có một trường IsMulti bool not null
điều này sẽ cho phép bạn biết cách truy vấn nó.