1

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

编辑:添加了一个图表,希望它更容易理解。

我有一个设置系统,其中许多设置特定于一个部门或分类。因此,例如,“每队人数”之类的设置可能在 Division 1 A 级与 Division 3 A 级不同。“最低分数”在 Division 1 A 级可能与 Division 1 A 级不同C. 显然也有一些设置与我觉得应该在同一个表中的划分或分类无关。

所以我可以做到这一点的一种方法是将 div/类 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,label,description)中为相关项目提供一整套几乎重复的记录——所有这些都只是为了创建一个独特的设置记录。

那么当他们说他们想要男性和女性的不同设置时会发生什么?我是否只是在设置表中添加一个额外的字段并将“男性”和“女性”字符串硬编码到记录中,除了特定于性别的设置之外的所有地方都为空?或者在事情的另一端,创建一个只有 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)

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

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

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

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

4

1 回答 1

0

这篇文章有点老了,但我仍然会为未来的读者回答:

简单的答案:使用方法 1

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

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

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

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

例子:

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

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

于 2017-11-14T16:33:04.210 回答