我对表格设计有疑问。我有一个解决方案应该在我看来有效,但不是。
考虑具有两个实体“主题”和“过程”,两者都具有某些属性。每个“主题”可以与多个“过程”相关联。根据选择的“过程”,存在不同数量的实体“过程 - 属性”。换句话说,当用户将“过程”与“主题”相关联时,他应该只能编辑与其特定关联的“属性”。
最终我希望用户能够做三件事:
所以表设计应该是这样的:
只要存在与每个“过程”相关联的“属性”,这显然有效。所以我的错误不是直接将“主题”链接到“过程”,而是我不能直接得到表格设计。
感谢任何帮助。
答案 0 :(得分:1)
如果您已经有了想法,想要存储在架构中的内容,那么创建架构的好策略是:
在您的情况下,在步骤1中,您应该有类似
的内容 ______ ___________ _______ _____ ____________
| Subj. |____/ associated \_______| Proc. |___/ has \__| Proc.prop. |
|_______| \____________/ |_______| \_____/ |____________|
如果您有不同类型的流程,您可以考虑流程实体的专业化。如果你真的想为每个过程选择具体的过程属性,你应该将具有 - 基数关系m:n。
在ER图中,即使您有另一种关系,也无法进行有效性检查(您的第3项)。在SQL模式中,您可以使用检查约束来强制执行此操作,或者在插入新进程之前让应用程序处理有效性。
答案 1 :(得分:1)
在我看来,你试图实现一种EAV(Entity-Attribue-Value)设计。
你的表似乎没问题,但这种设计固有地需要复杂的SQL。
有不同的方法可以做到这一点,但基于你上面的故事,我会用这样的东西。
Subject --< Process --< RelationshipProcessProperty >-- Property
您的财产将如下所示:
"Property"
PK PropertyId
Name
您的RelationshipProcessProperty可能如下所示:
"RelationshiipProcessProperty"
PK RelationshipProcessProperty
FK Process
FK Property
Value
你的SQL是复杂的地方。像这样做一个“通用”设计有一定的意义,因为你在同一个表中寻找多个值。
; with Property1 as(
SELECT
proc.Id as ProcessId,
prop.Name,
rrp.Value
FROM Subject s
LEFT JOIN Process proc
ON s.SubjectId = proc.SubjectId
LEFT JOIN RelationshipProcessProperty rpp
on proc.ProcessId = rpp.ProcessId
LEFT JOIN Property prop
on rpp.PropertyId = prop.PropertyId
WHERE
s.Name = "Subject1"
AND
proc.Name = "Process1"
AND
prop.Name = "Property1"
)
, Property2 as(
SELECT
proc.Id as ProcessId,
prop.Name,
rrp.Value
FROM Subject s
LEFT JOIN Process proc
ON s.SubjectId = proc.SubjectId
LEFT JOIN RelationshipProcessProperty rpp
on proc.ProcessId = rpp.ProcessId
LEFT JOIN Property prop
on rpp.PropertyId = prop.PropertyId
WHERE
s.Name = "Subject1"
AND
proc.Name = "Process1"
AND
prop.Name = "Property2"
)
SELECT
p1.Name,
p1.Value,
p2.Name,
p2.Value
FROM
Property1 p1
LEFT JOIN Property2 p2
on p1.ProcessId = p2.ProcessId
您可以使用此方法获取同一进程的多个属性。
要为指定的流程指定属性,您需要创建流程类型表:
"ProcessType"
PK ProcessType
Type
这确实意味着您需要在流程表中添加一个外键,以将其链接到它的类型。然后,您可以使用定义所有可用类型的关系表将ProcessType表链接到Property表。
"EligibleProcessProperties"
PK EligibleprocessPropertiesId
FK ProcessType
Fk Property
然后,要查找该流程类型的所有可用属性,您将获得一个相对简单的查询
SELECT
p.Name
FROM
ProcessType pt
LEFT JOIN EligibleProcessProperties epp
on pt.ProcessTypeId = epp.ProcessTypeId
LEFT JOIN Property p
on epp.PropertyId = p.PropertyId
WHERE
pt.Type = "Type1"
我认为这是你正在寻找的那种东西(虽然我可以完全脱离)。如果这是你正在寻找的,那么有一个非常好的帖子here可以提供一些好点。
此外,我几乎100%有更好的方法来做我的长';''查询 - 但这就是我所知道的。希望其他人可以提供更好的。关键是,使用此设计,您将以某种方式需要子查询。