我想知道在jsonb上构建EAV的正确方法是什么。
我有Attribute
- >标准EAV中的Values
表格。
CREATE TABLE attribute_values
(
id INTEGER,
attribute_id INTEGER,
value VARCHAR(255)
);
CREATE TABLE attributes
(
id INTEGER,
name VARCHAR(255)
);
值将保存在attributes
Entity
字段中
CREATE TABLE entity
(
id INTEGER,
title TEXT,
attributes JSONB
);
创建表Attribute
以控制其类型的重复属性,并更好地确定其属性是什么。例如,要避免:{weight: 100}
和{Weight: 100}
或{weigh: 100}
。 Values
用于处理唯一值并包含可用的值列表,如颜色(绿色,红色,白色等)。值可以预加载并用于faseted搜索。
我看到了几个选项:
1。商店格式如
[{"attribute_id":1, "value":5},{"attribute_id":1, value:"text"}]
其中value_id
为custom value
喜欢文字或id
来自Values
表。但我无法理解如何在此格式上构建索引,例如,如果Attribute 10
将integer
2。仅保留Attribute
表(用于控制属性name
)并存储数据,如:
{"price": 105, "weight": 100, "color": "white"}
。这种方法更适合索引
CREATE INDEX entity_index ON entity (((attributes ->> 'price')::int));
但我在翻译文本属性和控制唯一值时会遇到问题。另外,我无法在选项1
中添加其他键:{"attribute_id":1, "value":5, "values": []}
使用唯一控件(对于唯一属性)存储额外字段以及有机会编制索引的最佳方法是什么。
答案 0 :(得分:6)
我不建议使用单独的属性值表,就像我们在过去几年中所做的那样。将jsonb
字段放在相应的表格中并将其命名为Attributes
。向其添加GIN
索引,以便您可以快速查询值。或者使用其中描述的其他技术。
阅读本文:https://dba.stackexchange.com/a/174421/7762
这里最大的问题是你打算预先定义属性值。如果你这样做,有一种非常有效的方式来存储它们。如果没有,那么我建议使用标准的JSON对象。
这为您提供了最大程度的控制,速度和灵活性。
创建一个包含以下字段的表Attribute
:
AttributeID int4 unsigned not null primary key
ParentAttributeID int4 unsigned null
Name varchar(64) not null
Deleted
bool not null默认为false ParentAttributeID
AttributeID
更改然后在您要归属的任何表格中,添加以下字段:
AttributeSet" int[] not null default
intarray
扩展程序
这取得了什么成果?
您已创建属性树。它可能看起来像这样:
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
假设您有一个名为Items
的表格,并且您已添加AttributeSet
:
ItemID: 1234
Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]
翻译时,这意味着它具有Color=Green
属性和Size=Medium
属性。 103
和112
足以存储该内容,但有时可以说“#34;向我显示所有已定义任何尺寸的项目"”,#39} ;为什么要包括110。
你可以使这种闪电变得更加灵活。
SELECT
"ItemID", "Name"
FROM
"Items"
WHERE "AttributeMap" @> ARRAY[103,112]
将返回包含Size=Medium
和Color=Green
或者您可以使用https://www.postgresql.org/docs/10/static/functions-array.html上的其他运算符来提供一些很棒的查询。
这为您提供最快的速度,控制力,并且更加灵活。如果需要,您可以标记新属性以供审核。
您可以使用上述技术,只有在Attribute
表格不存在时才动态添加值。
这为您提供了最大的灵活性,但却以控制为代价。
在这种情况下,只需将其添加到任何表格中:
AttributeMap jsonb not null default '{}'::jsonb
编写代码以根据Attribute
表验证值。如果是单值或多值,请在那里有一个指标...
在AttributeMap
字段中存储如下:
{
"Color": "Green",
"Size": "Medium",
"Categories": ["Sports", "Leisure"]
}
请注意,Categories是一个多属性。在您Attribute
表格中,您应该有一个IsMulti bool not null
字段,以便您了解如何查询该字段。