标准 SQL 不支持此模型 - 这个问题是 BetName 不是键,并且(当前)不考虑候选键的一部分。
解决此问题的一种方法是保持关系原样并确保引用完整性是向 PlaysIn 添加一列 BetName ,然后使用 PlayIn FK(BetId, BetName) ,因此在Candidate Key上存在 FK而不仅仅是Surrogate PK。接下来,添加 PlaysIn UX(BetName, PlayerId) 以强制使用唯一名称/玩家。基本上,它通过代理和适当的复合键来约束关系。这有点令人讨厌,因为没有用于 RI 的“重复数据”(在 Compound PK 之外)。
TABLE Bet
PK BetID
BetName
TABLE PlaysIn
BetID
PlayerID
BetName -- must set
PK (BetID, PlayerID)
FK Bet(BetID, BetName)
UX (PlayerID, BetName)
我推荐的另一种方法虽然确实会改变关系,但将 PlayerId从PlaysIn 中移出并保留在 Bet 中。然后 PlaysIn -> 投注 -> 玩家。UX 也可以升级为 PK 并且 BetID 可以删除,使其与上述类似。
TABLE Player
PK PlayerID
PlayerName
TABLE Bet
-- Note: If PlaysIn needs PlayerID as well, use PK(PlayerId, BetName)
-- and adjust the FK in PlaysIn
PK BetID
PlayerID
BetName
UX (PlayerID, BetName)
TABLE PlaysIn
PK PlayID -- If you're gonna use Surrogates, be consistent
BetID
FK (BetID) -- Access to Player via Bet
-- other things for a "Play"
当然,TRIGGERS 可以“全部完成”,但不直接在关系中表示。代码在插入/更新上也可以很细致——如果你信任 DAL。
根据第二种方法,我会考虑更改模型。