基于jsonb寻找合适的EAV结构
Looking for a right EAV structure based on jsonb
我想知道在 jsonb 上构建 EAV 的正确方法是什么。
我有 Attribute
-> Values
tables 就像在标准 EAV 中一样。
CREATE TABLE attribute_values
(
id INTEGER,
attribute_id INTEGER,
value VARCHAR(255)
);
CREATE TABLE attributes
(
id INTEGER,
name VARCHAR(255)
);
值将保存在 Entity
的 attributes
字段中
CREATE TABLE entity
(
id INTEGER,
title TEXT,
attributes JSONB
);
创建表 Attribute
是为了控制重复属性及其类型,并更好地确定它是什么属性。例如要避免:{weight: 100}
和 {Weight: 100}
或 {weigh: 100}
。 Values
用于处理唯一值并包含可用的值列表,例如颜色(绿色、红色、白色等)。可以预加载值并用于固定搜索。
我看到几个选项:
1. 存储格式如
[{"attribute_id":1, "value":5},{"attribute_id":1, value:"text"}]
其中 value_id
将 custom value
类似于文本或 id
来自 Values
table。但是我不明白如何在这种格式上建立索引,例如 if Attribute 10
will integer
2.只保留Attribute
table(用于控制属性name
)并存储数据如:
{"price": 105, "weight": 100, "color": "white"}
。这种方法更适合索引
CREATE INDEX entity_index ON entity (((attributes ->> 'price')::int));
但我在翻译文本 属性 和控制唯一值时遇到问题。我也不能像选项 1
那样添加额外的键:{"attribute_id":1, "value":5, "values": []}
存储具有唯一控制(对于唯一属性)和索引机会的额外字段的最佳方法是什么。
Objective:您想存储与给定实体相关的属性。
我不建议像过去几年那样为属性值单独 table。在适当的 table 上放置一个 jsonb
字段并将其命名为 Attributes
。为其添加一个 GIN
索引,以便您可以快速查询值。或者使用其中描述的其他技术。
读这个:https://dba.stackexchange.com/a/174421/7762
这里最大的问题是您是否打算 pre-define 属性值。如果这样做,有一种非常有效的方法来存储它们。如果没有,那么我推荐一个标准的 JSON 对象。
如果可以 pre-define 您的属性名称和值:
这为您提供了最大的控制力和速度,并且仍然提供了灵活性。
创建一个 table Attribute
,其中包含以下字段:
AttributeID int4 unsigned not null primary key
ParentAttributeID int4 unsigned null
Name varchar(64) not null
Deleted
bool not null default false
- 在
ParentAttributeID
上添加索引
- 添加触发器以防止
AttributeID
更改
- 添加删除规则而不是设置 Deleted=True
然后在任何你想要属性的table中,添加这个字段:
AttributeSet" int[] not null default
- 在该数组字段上添加 GIN 索引
- 同时启用 https://www.postgresql.org/docs/current/static/intarray.html
的 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
的 table 并在其上添加了 AttributeSet
:
ItemID: 1234
Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]
翻译后,这意味着它具有 Color=Green
属性和 Size=Medium
属性。 103
和 112
足以存储它,但有时能够说“显示所有定义了任何尺寸的项目”是很好的,这就是为什么包含 110。
你可以让这个闪电般的快速和超灵活。
SELECT
"ItemID", "Name"
FROM
"Items"
WHERE "AttributeMap" @> ARRAY[103,112]
将 return 所有具有 Size=Medium
和 Color=Green
的项目
或者您可以使用 https://www.postgresql.org/docs/10/static/functions-array.html 上的其他运算符来提出一些很棒的查询。
当您不知道属性值但它是一个小集合时:
这给你最大的速度、控制力,甚至更灵活。如果需要,您可以标记新属性以供审核。
您可以使用上述技术,如果 Attribute
table 不存在,只需动态添加值即可。
当您不知道属性值且值多种多样时
这为您提供了最大的灵活性,但以控制为代价。
在这种情况下,只需将其添加到任何 table:
AttributeMap jsonb not null default '{}'::jsonb
- 向该字段添加 GIN 索引
编写代码以根据您的 Attribute
table 验证这些值。如果它是单个或 multi-value...
则在那里有一个指标
在 AttributeMap
字段中这样存储:
{
"Color": "Green",
"Size": "Medium",
"Categories": ["Sports", "Leisure"]
}
请注意类别是 multi-attribute。在您的 Attribute
table 中,您应该有一个 IsMulti bool not null
字段,这将使您知道如何查询它。
我想知道在 jsonb 上构建 EAV 的正确方法是什么。
我有 Attribute
-> Values
tables 就像在标准 EAV 中一样。
CREATE TABLE attribute_values
(
id INTEGER,
attribute_id INTEGER,
value VARCHAR(255)
);
CREATE TABLE attributes
(
id INTEGER,
name VARCHAR(255)
);
值将保存在 Entity
attributes
字段中
CREATE TABLE entity
(
id INTEGER,
title TEXT,
attributes JSONB
);
创建表 Attribute
是为了控制重复属性及其类型,并更好地确定它是什么属性。例如要避免:{weight: 100}
和 {Weight: 100}
或 {weigh: 100}
。 Values
用于处理唯一值并包含可用的值列表,例如颜色(绿色、红色、白色等)。可以预加载值并用于固定搜索。
我看到几个选项:
1. 存储格式如
[{"attribute_id":1, "value":5},{"attribute_id":1, value:"text"}]
其中 value_id
将 custom value
类似于文本或 id
来自 Values
table。但是我不明白如何在这种格式上建立索引,例如 if Attribute 10
will integer
2.只保留Attribute
table(用于控制属性name
)并存储数据如:
{"price": 105, "weight": 100, "color": "white"}
。这种方法更适合索引
CREATE INDEX entity_index ON entity (((attributes ->> 'price')::int));
但我在翻译文本 属性 和控制唯一值时遇到问题。我也不能像选项 1
那样添加额外的键:{"attribute_id":1, "value":5, "values": []}
存储具有唯一控制(对于唯一属性)和索引机会的额外字段的最佳方法是什么。
Objective:您想存储与给定实体相关的属性。
我不建议像过去几年那样为属性值单独 table。在适当的 table 上放置一个 jsonb
字段并将其命名为 Attributes
。为其添加一个 GIN
索引,以便您可以快速查询值。或者使用其中描述的其他技术。
读这个:https://dba.stackexchange.com/a/174421/7762
这里最大的问题是您是否打算 pre-define 属性值。如果这样做,有一种非常有效的方法来存储它们。如果没有,那么我推荐一个标准的 JSON 对象。
如果可以 pre-define 您的属性名称和值:
这为您提供了最大的控制力和速度,并且仍然提供了灵活性。
创建一个 table Attribute
,其中包含以下字段:
AttributeID int4 unsigned not null primary key
ParentAttributeID int4 unsigned null
Name varchar(64) not null
Deleted
bool not null default false- 在
ParentAttributeID
上添加索引
- 添加触发器以防止
AttributeID
更改 - 添加删除规则而不是设置 Deleted=True
然后在任何你想要属性的table中,添加这个字段:
AttributeSet" int[] not null default
- 在该数组字段上添加 GIN 索引
- 同时启用 https://www.postgresql.org/docs/current/static/intarray.html 的
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
的 table 并在其上添加了 AttributeSet
:
ItemID: 1234
Name: Tee Shirt
AttributeSet: [100, 103, 110, 112]
翻译后,这意味着它具有 Color=Green
属性和 Size=Medium
属性。 103
和 112
足以存储它,但有时能够说“显示所有定义了任何尺寸的项目”是很好的,这就是为什么包含 110。
你可以让这个闪电般的快速和超灵活。
SELECT
"ItemID", "Name"
FROM
"Items"
WHERE "AttributeMap" @> ARRAY[103,112]
将 return 所有具有 Size=Medium
和 Color=Green
或者您可以使用 https://www.postgresql.org/docs/10/static/functions-array.html 上的其他运算符来提出一些很棒的查询。
当您不知道属性值但它是一个小集合时:
这给你最大的速度、控制力,甚至更灵活。如果需要,您可以标记新属性以供审核。
您可以使用上述技术,如果 Attribute
table 不存在,只需动态添加值即可。
当您不知道属性值且值多种多样时
这为您提供了最大的灵活性,但以控制为代价。
在这种情况下,只需将其添加到任何 table:
AttributeMap jsonb not null default '{}'::jsonb
- 向该字段添加 GIN 索引
编写代码以根据您的 Attribute
table 验证这些值。如果它是单个或 multi-value...
在 AttributeMap
字段中这样存储:
{
"Color": "Green",
"Size": "Medium",
"Categories": ["Sports", "Leisure"]
}
请注意类别是 multi-attribute。在您的 Attribute
table 中,您应该有一个 IsMulti bool not null
字段,这将使您知道如何查询它。