Database design 具有两个外键的表指向另一个表的同一列
我想知道,从设计的角度来看,一个表有两个外键,每个外键指向另一个表的同一字段,这是可能的还是理想的。表Database design 具有两个外键的表指向另一个表的同一列,database-design,Database Design,我想知道,从设计的角度来看,一个表有两个外键,每个外键指向另一个表的同一字段,这是可能的还是理想的。表Case有两个字段,引用表Client的主键(每个案例有两个客户端) 如果一个咨询案例中只有两方的限制真的适用于所有案例,那么没有理由采取不同的做法。 如果您最终可以得到一个一到两个以上的关系,那么您应该将该关系设置为一个单独的表,例如rel\u cases\u clients:(ID,FK\u Case,FK\u Client)。关于数据规范化,它也有点好 一般来说,表中有许多外键根本没有问题
Case
有两个字段,引用表Client
的主键(每个案例有两个客户端)
如果一个咨询案例中只有两方的限制真的适用于所有案例,那么没有理由采取不同的做法。 如果您最终可以得到一个一到两个以上的关系,那么您应该将该关系设置为一个单独的表,例如
rel\u cases\u clients:(ID,FK\u Case,FK\u Client)
。关于数据规范化,它也有点好
一般来说,表中有许多外键根本没有问题,高度规范化的设计通常都充满了外键。但是请记住,这种关系通常意味着在查询中需要做更多的工作。(
JOIN
)是的,完全可能有两个FK分别指向另一个表的同一字段。我想说这是不寻常的,可能是一个没有正常化的设计的症状。考虑
每个案件都有两个当事人
client table:
------------------
PK:client_id
first_name
last_name
case table:
------------------
PK:case_id
party1 (client_id)
party2 (client_id)
我怀疑这是一种过度简化。在这种情况下,这两个客户的角色不同吗?即使一个完全成熟的案例只有两个客户,也许你只能一个接一个地了解他们?(因此,您首先要记录案例
,然后添加第1部分
,然后再次添加第2部分
)双方是否可能是同一客户
正如@AndreasT所暗示的,更常见的设计是:
client table: -- as you have
case table:
----------------
PK: case_id
other stuff about the case, start date, etc
party-case-role
----------------
PK: { case_id(FK case table)
{ party(FK client table client_id)
{ role
其中角色
可能是第1方、第2方、证人、咨询专家、监护人、看护人等
(取决于您的案例)
这种类型的数据结构有时被称为“ppr”-人-方角色,在与您打交道的客户/客户/供应商/代理之间存在许多交叉链接的行业中很常见,例如在保险或法律案件中
对于返回party1
的查询,party2
与案例详细信息关联(根据您的评论请求)(未测试)
如果一个
案例
有两个客户
,那么您会如何表示?你遇到了什么问题?2个外键没有问题,假设每个链接到的记录都扮演不同的角色(如果实体同时扮演两个角色,它们甚至可能都是相同的记录)。@david我的db知识大部分是自学的,所以我不确定这种设计是否比为每一方提供单独的表更好。@scott hunter这就像客户表有一个“john”(id=1)和“jane”(id=2),案例表有一个案例条目,party1为“john”,party2为“jane”。应该提供帮助来改进问题,而不是关闭它。谢谢。是的,他们的角色将是截然不同的(就像母亲和父亲一样)。是的,案例通常是在一个客户与我们联系或被介绍给我们时启动的,因此通常一开始只使用一方的信息创建案例。如果我要写一个select语句,根据您的表结构显示案例id、第一方名称、第二方名称,我必须合并(union)两个select语句,每个语句都有关于该方角色的where条件?
SELECT case.*, p1.first_name, p1.last_name, p2.first_name, p2.last_name
FROM case
INNER JOIN (SELECT * FROM party-case-role WHERE role = 'party1' AS ppr1)
ON case.case_id = ppr1.case_id
INNER JOIN client AS p1 ON ppr1.party = p1.client_id
INNER JOIN (SELECT * from party-case-role WHERE role = 'party2' AS ppr2)
ON case.case_id = ppr2.case_id
INNER JOIN client AS p2 ON ppr2.party = p2.client_id