简体   繁体   English

数据库设计两个表vs联接表,哪个更好

[英]database design two tables vs join table, which is better

I have two tables matches and tournaments with below structure, 我有以下结构的两桌matchestournaments

MATCH
    MATCH_ID
    PLAYER_ID_1
    PLAYER_ID_2
    RESULT
    TOURNAMENT_ID

and

TOURNAMENT
    TOURNAMENT_ID
    NAME
    OTHER_DETAILS

with one tournament will have multiple matches 一场比赛将有多场比赛

and a match may or may not have tournament id 一场比赛可能有也可能没有比赛ID

use Cases: 用例:

  • retrieve all matches 检索所有匹配项
  • retrieve all matches by tournaments 检索所有比赛的比赛

Is it good to have tournament id in match table? match表中拥有tournament id是否很好? Or should I create a separate joining table for tournament and match mapping? 还是应该为tournamentmatch映射创建单独的联接表? Which will have good performance when the volume increases? 音量增加时哪个将具有良好的性能?

TOURNAMENT_ID has a 1:M relationship to MATCH. TOURNAMENT_ID与MATCH具有1:M的关系。 It seems to be a straightforward foreign key. 这似乎是一个简单的外键。 The standard way of implementing foreign keys - even optional foreign keys - is a column on the child table with a foreign key constraint. 实现外键(甚至是可选外键)的标准方法是子表上具有外键约束的列。 This would support both your use cases. 这将支持您的两个用例。

A separate table would normally be a head scratcher. 一张单独的桌子通常是一个头部刮擦器。 I say "normally" because there are schools of thought which abominate NULL columns in databases; 我之所以说“正常”,是因为有一些流派废除了数据库中的NULL列。 either for practical reasons - NULLs can do weird things to our code and need wrangling - and academic reasons - NULL is contrary to Relational Algebra. 出于实际原因-NULL可能会对我们的代码造成奇怪的事情,并且需要进行争执-从学术上来说-NULL与关系代数相反。 So, if you have a data model which forbids the use of nulls you will need a TOURNAMENT_MATCH table to hold Matches which are part of a Tournament. 因此,如果您有一个禁止使用空值的数据模型,则需要一个TOURNAMENT_MATCH表来保存比赛中的比赛。 It also would be likely to perform slightly worse than a foreign key column on MATCH, but unless you have a vast amount of data you won't notice the difference. 它的性能也可能比MATCH上的外键列稍差,但是除非您拥有大量数据,否则您不会注意到其中的区别。

There is a use case for join tables (also known as junction or intersection tables) and that is implementing many-to-many relationships. 有一个联接表(也称为联结表或交叉表)用例,它实现了多对多关系。 Suppose we add a third table to the mix, PLAYER. 假设我们向混音中添加了第三张桌子PLAYER。 A Player can participate in many Tournaments and a Tournament has many Players. 一个玩家可以参加许多锦标赛,而一个锦标赛中有许多玩家。 Classic M:N relationship. 经典的M:N关系。 So we can resolve it with a join table REGISTERED_PLAYER. 因此,我们可以使用注册表Registered_PLAYER来解决该问题。 which as a compound key of (TOURNAMENT_ID,PLAYER_ID) and the appropriate foreign keys to TOURNAMENT and PLAYER. 作为(TOURNAMENT_ID,PLAYER_ID)的复合键以及TOURNAMENT和PLAYER的适当外键。


For the sake of completeness I will mention Link tables from Data Vault modelling. 为了完整起见,我将提到Data Vault建模中的链接表。 This is an interesting modelling technique for Data Warehouses, where - gross simplification alert - tables are defined as Hubs (business and technical keys) and Satellites (immutable attribute records). 这是用于数据仓库的一种有趣的建模技术,其中-总体简化警报-表被定义为集线器(业务和技术密钥)和卫星(不可变的属性记录)。 This approach allows for the capture of data changes over time. 这种方法可以捕获随时间变化的数据。 Foreign key relationships between Hubs are implemented through Link tables, to support changing relationships over time. 集线器之间的外键关系通过链接表实现,以支持随时间变化的关系。

There are several benefits to Data Vault for wrangling large amounts of data in a time-sensitive fashion but an easy-to-understand physical data model isn't one of them. Data Vault以对时间敏感的方式处理大量数据有许多好处,但简单易懂的物理数据模型并不是其中之一。 Anyway, find out more . 无论如何, 了解更多

The simple rule: for one-to-many mapping always prefer a foreign key association to a join table association. 一个简单的规则:对于一对多映射,始终倾向于使用外键关联而不是联接表关联。

It is hard to control a join table using a standard @OneToMany Hibernate mapping — you can't just delete rows from a join table, or add an additional row. 使用标准的@OneToMany Hibernate映射很难控制@OneToMany表-您不能只是从@OneToMany表中删除行或添加其他行。 You will need to use list on the Tournament side to do things like that. 您将需要使用Tournament一侧的列表来执行类似操作。 Another option is to use an additional entity for a join table. 另一种选择是对联接表使用其他实体。

Note: Match can has a tournaments list too, but looks like Tournament is the owner of the association. 注意: Match也可以有一个锦标赛列表,但看起来Tournament是该协会的所有者。

A few opinions have been offered in other answers, here is mine. 其他答案提供了一些意见,这是我的。

You do NOT want a separate join table, you would only need that if a Match can be in multiple Tournaments. 您不希望有单独的联接表,仅在匹配项可以包含多个锦标赛的情况下才需要。 In your example, just use a foreign key. 在您的示例中,只需使用外键即可。

The only other suggestion is that if the Match is not part of a Tournament then it is not actually "unknown" which is the meaning of NULL, it is actually something else like "Individual Match". 唯一的其他建议是,如果“比赛”不是锦标赛的一部分,那么它实际上并不是“未知”(NULL的含义),实际上是“个人比赛”之类的东西。 So consider adding a row to your Tournament table, maybe using a known key like 0 or -1, and using that for matches that are not part of a tournament. 因此,考虑在锦标赛表中添加一行,也许使用已知的键(例如0或-1),并将其用于不属于锦标赛的比赛。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM