PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tìm kiếm cấu trúc EAV phù hợp dựa trên jsonb

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:

Đ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. 103112 đã đủ để 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=MediumColor=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ó.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách hoạt động của hàm Sign () trong PostgreSQL

  2. SQL:làm thế nào để chọn hàng có nhiều giá trị nhất?

  3. vấn đề với mã hóa khi nhập json vào Postgres

  4. Array of Enum trong Postgres với SQLAlchemy

  5. Lỗi cú pháp PostgreSQL tại hoặc gần 'union'