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