何时在单个表中使用多个外键与使用关联表?

时间:2017-04-05 21:01:19

标签: database foreign-keys associative-table

我试图了解何时将多个外键包含到表中以及何时使用关联表。

修改:添加了a diagram,希望更容易理解。

我有一个设置系统,许多设置特定于分区或分类。因此,例如,每个团队的编号类似于#34;"在第1组,A组可能与第3组,A组不同。并且"最低分数"在第1部分,A级可能与第1部分C级不同。显然,也存在与我认为应该在同一个表中的分区或分类无关的设置。

所以我可以这样做的一种方法就是将div / class ID作为FK放在设置表中。然后,任何不依赖于其中一个(或任何一个)的设置对于这些ID都将为空。

divisions
----------
id (int)
label (varchar)
description (varchar)

classification
--------------
id (int)
label (varchar)
description (varchar)

settings
---------
id (int)
division_id (int) (FK)
class_id (int) (FK)
key (varchar)
value (varchar)

由于只有一个分区,分类和设置键的组合,这应该有效,对吧?但那"感觉"错误的某种方式 - 几乎就像在竞争对手的桌子上把不同的事件放在一起竞争。我也不能保证他们不会想出一些他们希望稍后应用设置的其他类别/类型。所以这让我想做类似的事情:

divisions
----------
id (int)
label (varchar)
description (varchar)

classifications
--------------
id (int)
label (varchar)
description (varchar)

settings
---------
id (int)
key (varchar)
value (varchar)

settings_to_divisions
-------------------------
setting_id (int)
division_id (int)

settings_to_classifications
------------------------------
setting_id (int)
class_id (int)

我认为这会让他们在提出一些新类别时更容易增长(只需创建'类别'以及' settings_to_categories'表格)。但是,我可能在设置表([id]," min_score",5)中有一整套几乎重复的记录,以及多个几乎相同的表(id,标签,描述)相关项目 - 所有这些只是为了创建一个唯一的设置记录。

那么当他们说男人和女人想要不同的设置时会发生什么?我是否只需在设置表中添加一个额外的字段,并对“男性”进行硬编码。和女性'字符串到记录中,除了性别特定的设置外,其他地方都是空的?或者在另一方面,创建一个单独的性别'只有2条记录的表,并在用户表中使用它?突然间,我来了:

divisions
---------
id (int)
label (varchar)
description (varchar)

classifications
---------------
id (int)
label (varchar)
description (varchar)

categories
----------
id (int)
label (varchar)
description (varchar)

type
----
id (int)
label (varchar)
description (varchar)

gender
------
id (int)
label (varchar)
description (varchar)

settings
---------
id (int)
key (varchar)
value (varchar)

settings_to_divisions
---------------------
setting_id (int)
division_id (int)

settings_to_classifications
---------------------------
setting_id (int)
class_id (int)

settings_to_categories
----------------------
setting_id (int)
category_id (int)

settings_to_type
----------------
setting_id (int)
type_id (int)

settings_to_gender
------------------
setting_id (int)
gender_id (int)

它开始感觉到...... 过度正常化。虽然也许只是我。

我只是试图巧妙地设计这个,以便即使某些设置适用于所有第3分区的玩家,当他们告诉我他们需要更多类别时,应用程序应该对第3分部A级的行为有所不同,类别绿色,流氓,男性玩家与女性玩家,我不必过多地重新设计我的数据库或应用程序,以便轻松获取/设置任何不同的设置。

我确定这不是一个新概念。这必须是一个公认的设计模式,但是很难尝试搜索方法和方法来处理可能有3种(或5种或8种)不同方式关联单个数据库实体的情况

我目前倾向于关联表方法(显着规范化),但我并不是真正的DBA。我做出一个愚蠢的设计决定吗?这种方法的负面影响/挑战是什么?一种不同的方法会更好吗?

1 个答案:

答案 0 :(得分:0)

这篇文章有点陈旧但我仍会回答未来的读者:

简单的答案:使用方法1

在分区/分类之间需要表格的唯一原因是将单个设置与多个分区/分类记录相关联。

我可以根据您不想要的经验告诉您。虽然使用相同的设置反复听起来像是一个很好的节省时间和空间的机制,但您将来会后悔。第二个您需要为与单个设置关联的子集记录创建新设置,或者更糟糕的是,您需要更改设置表,强制绝大多数记录将单个分区/分类记录与单个记录关联设置 - 你会恨你的生活。

其次,创建设置为文本字符串的设置表非常灵活,但效率不高。如果您对单个分区/分类有多个设置,则应用程序必须遍历执行if记录的结果。

当然,另一种方法是为每个设置创建一个列。由于新设置需要部署,这也可能是一个痛点。但是,如果大量设置为布尔值,则可以使用BIT值实现显着的性能提升。

示例:

如果您有6个BIT字段,则数据库引擎只需要比较一个字节 数据/记录,以找到所需的值 - 与搜索必须比较多个记录上的多个字节的文本相比。

最后,如果将来设置数量显着增加,则可能会使用文本字符串影响性能。