经常在书中,我看到当多对多关系被转换为数据库模式时,JoinTable会获得一个复合键,该键由多对多关系中涉及的表的主键组成。 我试着完全避免复合键。所以我通常甚至为JoinTable创建一个代理键,并允许数据库通过触发器或数据库用于递增主键的任何功能来填充它。这似乎是一种更简单的方法。
我能想到的唯一问题是,JoinTable中存在重复外键对的可能性。但是,在JoinTable中插入行之前,可以通过简单查询来避免这种情况。
由于书籍总是使用复合键方法,我想知道,如果我使用简单的一列代理键用于JoinTable,是否有任何负面影响?
答案 0 :(得分:1)
在我看来,使用单个主键是一个坏主意。
首先,正如您所说,单个主键不能确保数据库中的单一性。当然,您可以在运行时使用简单查询来检查这一点,但这样做成本很高,如果您只忘记一次执行检查查询,则可能会使数据库处于不一致状态。
另外,我认为在这种情况下,使用主键的附加列是没有必要的。您不需要通过唯一主键来标识关系,因为该关系已由两个唯一键定义:两个表的主键。在这种情况下,您将拥有不必要的数据,这会增加数据模型的复杂性,并且您可能永远不会使用。
答案 1 :(得分:1)
我尽量避免使用复合键。
咦?为什么?我的意思是,为什么完全避免它们?这背后的原因是什么?
所以我通常甚至为JoinTable创建一个代理键,并允许数据库通过触发器或数据库用于递增主键的任何功能来填充它。这似乎是一种更简单的方法。
没有冒犯,但我们对简单性没有相同的定义。我真的不知道哪个更简单。
我能想到的唯一问题是,JoinTable中存在重复外键对的可能性。但是,在JoinTable中插入行之前,可以通过简单查询来避免这种情况。
首先,不要使用SELECT来检查唯一性(你可以有一个竞争条件,没有锁定整个表的SELECT也不能保证任何东西),使用UNIQUE约束,这就是UNIQUE的用途。
让我们想象一下SELECT可能会有一秒钟,你真的觉得那么简单吗?一般来说,如果可能的话,人们会尽量避免攻击数据库。他们还避免做额外的工作。
由于书籍总是使用复合键方法,我想知道,如果我使用简单的一列代理键用于JoinTable,是否有任何负面影响?
所以你的意思是这样的:
A A_B B
------- ------------------ --------
ID (PK) ID (PK), ID (PK)
A_ID (FK),
B_ID (FK),
UNIQUE(A_ID, B_ID)
当然,你可以这样做(如果你使用某种类型的触发器或标识列,你甚至可以用JPA映射它)。但我没有看到这一点:
总而言之,我认为没有任何优势。