在 PostgreSQL 中处理继承和非继承值
Handling inherited and not inherited values in PostgreSQL
我正在尝试绘制数据库模式并在继承方面苦苦挣扎。让我举个例子:
我有表 List
和 Item
:
Table List{
id varchar [not null, pk]
parent_list_id varchar [ref: - List.id]
}
Table Item{
id varchar [not null, pk]
list_id varchar [ref: > List.id]
}
Table Rule{
id varchar [not null, pk]
list_id varchar [ref: > List.id]
item_id varchar [ref: > Item.id]
}
可以有多个列表,它们从上层 List
继承它们的 Rule
。一个 List
可以有多个 Item
和多个 Rule
,并且属于一个列表的所有列表和项目都应该从父列表继承它们的规则。子列表和项目也可以设置自己的规则,如果是列表,规则将继承到它们的子列表。
一个例子:
- List_A
- Rule_A(专门设置为List_A)
- Rule_B(专门设置为 List_A)
- List_B
- Rule_A(继承)
- Rule_B(继承)
- Rule_C(专门设置为 List_B)
- Item_A
- Rule_A(继承)
- Rule_B(继承)
- Rule_C(继承)
- Rule_D(专门设置为Item_A)
现在,这应该不是什么大问题,但我还需要能够将规则设置为活动或非活动。我考虑过为我的模型 Rule
设置一个布尔值 active
,但我认为这种方法存在问题。如果我想将 Rule_A
和 Rule_B
设置为对 Item_A
无效(它们在 List_A
和 List_B
下仍然有效),这是一个问题,因为我的规则会有一个 list_id
引用 List_A
。如果有人对如何处理这种继承有一些建议,我将非常感激,我有点卡在这里。
这里是用实体-关系术语解释你的描述:
- 单个项目(或列表)可以有多个与之相关的规则。
- 一个规则可以有多个与之相关的项目(或列表)。
- (继承方面超出了这个模型,imo,并且基本上是“创建副本时预填充规则 - 项目关系”,如果这有意义的话)。
这是一个经典的many-to-many案例。处理这种与联结 tables 的关系的最明显方法。那些很酷的是,您可以在联结 table 中有一些额外的字段来保存一些额外的属性。例如 enabled boolean
:
Table List {
id varchar [not null, pk]
parent_list_id varchar [ref: - List.id]
}
Table Item {
id varchar [not null, pk]
list_id varchar [ref: > List.id]
}
Table Rule {
id varchar [not null, pk]
}
Table rule_to_list {
-- composite PK (list_id, rule_id)
list_id varchar [ref: > List.id]
rule_id varchar [ref: > Rule.id]
enabled boolean
}
Table rule_to_item {
-- composite PK (item_id, rule_id)
item_id varchar [ref: > Item.id]
rule_id varchar [ref: > Rule.id]
enabled boolean
}
使用此架构,您将能够轻松地 enable/disable 关于特定 list/item 的单独规则,甚至可以在需要时完全删除它们。
您唯一需要执行的是将 parent item/list 规则复制到联结 tables,但这很容易。或者你可以使用隐式的“所有 items/lists 从它们的 parent 继承规则,除非有覆盖”(即 parent 列表启用了规则 A,并且 child 列表有 A在结点 table) 中明确禁用,并在计算 item/list.
的规则列表时向上遍历层次结构
我正在尝试绘制数据库模式并在继承方面苦苦挣扎。让我举个例子:
我有表 List
和 Item
:
Table List{
id varchar [not null, pk]
parent_list_id varchar [ref: - List.id]
}
Table Item{
id varchar [not null, pk]
list_id varchar [ref: > List.id]
}
Table Rule{
id varchar [not null, pk]
list_id varchar [ref: > List.id]
item_id varchar [ref: > Item.id]
}
可以有多个列表,它们从上层 List
继承它们的 Rule
。一个 List
可以有多个 Item
和多个 Rule
,并且属于一个列表的所有列表和项目都应该从父列表继承它们的规则。子列表和项目也可以设置自己的规则,如果是列表,规则将继承到它们的子列表。
一个例子:
- List_A
- Rule_A(专门设置为List_A)
- Rule_B(专门设置为 List_A)
- List_B
- Rule_A(继承)
- Rule_B(继承)
- Rule_C(专门设置为 List_B)
- Item_A
- Rule_A(继承)
- Rule_B(继承)
- Rule_C(继承)
- Rule_D(专门设置为Item_A)
现在,这应该不是什么大问题,但我还需要能够将规则设置为活动或非活动。我考虑过为我的模型 Rule
设置一个布尔值 active
,但我认为这种方法存在问题。如果我想将 Rule_A
和 Rule_B
设置为对 Item_A
无效(它们在 List_A
和 List_B
下仍然有效),这是一个问题,因为我的规则会有一个 list_id
引用 List_A
。如果有人对如何处理这种继承有一些建议,我将非常感激,我有点卡在这里。
这里是用实体-关系术语解释你的描述:
- 单个项目(或列表)可以有多个与之相关的规则。
- 一个规则可以有多个与之相关的项目(或列表)。
- (继承方面超出了这个模型,imo,并且基本上是“创建副本时预填充规则 - 项目关系”,如果这有意义的话)。
这是一个经典的many-to-many案例。处理这种与联结 tables 的关系的最明显方法。那些很酷的是,您可以在联结 table 中有一些额外的字段来保存一些额外的属性。例如 enabled boolean
:
Table List {
id varchar [not null, pk]
parent_list_id varchar [ref: - List.id]
}
Table Item {
id varchar [not null, pk]
list_id varchar [ref: > List.id]
}
Table Rule {
id varchar [not null, pk]
}
Table rule_to_list {
-- composite PK (list_id, rule_id)
list_id varchar [ref: > List.id]
rule_id varchar [ref: > Rule.id]
enabled boolean
}
Table rule_to_item {
-- composite PK (item_id, rule_id)
item_id varchar [ref: > Item.id]
rule_id varchar [ref: > Rule.id]
enabled boolean
}
使用此架构,您将能够轻松地 enable/disable 关于特定 list/item 的单独规则,甚至可以在需要时完全删除它们。
您唯一需要执行的是将 parent item/list 规则复制到联结 tables,但这很容易。或者你可以使用隐式的“所有 items/lists 从它们的 parent 继承规则,除非有覆盖”(即 parent 列表启用了规则 A,并且 child 列表有 A在结点 table) 中明确禁用,并在计算 item/list.
的规则列表时向上遍历层次结构