2+ 外键在任何关联/联结表中都是坏主意吗?

zdx*_*xai 7 database-design

(第一次发帖,潜伏了很长时间。我在任何地方都找不到这个问题的答案,所以我现在从阴影中出来问专家)。

是一个带有 4 个外键(4 个表)的联结表,对于仅作为查找读取而不定期更改的表,并且包含静态数据并且只能由管理员而不是 ' 更改的表是一个好主意用户'?

我举一个简单的例子。

假设我们有四个表,每个表只有两个字段 - 一个 ID 号字段(主键)和一个“名称”(文本)字段:tblCarModelNametblCarTypetblManufacturertblColor

然后我们有一个连接表(tblCars),其设计如下:

Car_ID (PK)
CarModelName_IDFK (FK)
CarType_IDFK (FK)
Manufacturer_IDFK (FK)
Color_IDFK (FK)
Run Code Online (Sandbox Code Playgroud)

该表可能看起来像(请注意,IDFK 将是整数而不是字符串,如此处所示):

Car_ID, CarModelName_IDFK, CarType_IDFK, Manufacturer_IDFK, Color_IDFK
1,Hilux,Truck,Toyota,White
2,SLK300,Sedan,Mercedes,Blue
3,SLK500,Sedan,Mercedes,Silver
4,Prius,Coupe,Toyota,White
....
Run Code Online (Sandbox Code Playgroud)

所以表格最终看起来像一个电子表格。但我为什么要这样做呢?

  1. 使数据输入和表格维护变得容易。
  2. 由于外键引用,我仍然可以查询表中特定的“制造商”。
  3. 我可以将 Excel 中以相同方式构建的数据直接粘贴到表格中。
  4. 而且,更重要的是,在这个例子中处理了多对多关系
  5. 如果我在用户界面表单中以完全相同的方式提供此表,我知道用户何时从此列表中进行选择,例如 ID = 3,并且他们已从列表中选择了“SLK500,Sedan,Mercedes,Silver”。

这种设计理想吗?反馈表示赞赏。

无论如何,这个模型叫什么?

Joe*_*own 5

三路(或更多)交集表没有错(原则上),只要它正确描述了您的关系。

但是:您的特定表格不是第三范式 (3NF)

除非您有充分的理由不这样做,否则您通常应该标准化为 3NF。

问题是您的某些数据取决于密钥的一部分,而不是整个密钥。这意味着您的表格只是第二范式 (2NF)。

考虑一下:您的表将允许一条记录表示PriusToyota,另一条记录表示PriusChrysler。显然这不好。

您想将品牌型号的层次结构删除到单独的表中。

同样,汽车的类型取决于型号,而不取决于颜色

所以你需要做的也是将这些列分开。你真正需要的是四个表:

  • 制造商(制造商名称)

  • 型号(型号名称、FK 到类型和 FK 到制造商)

  • 类型(类型名称)

  • 汽车(FK 到模型,颜色)

这将为您提供一个没有冗余的规范化模式,并且由于插入、更新和删除异常而导致数据损坏的风险很小。

  • @zdxai - 按照我建议的方式绘制您的表格,并向我展示一个样本总体,其中可以有一个普锐斯是丰田的例子,另一个普锐斯是克莱斯勒的例子。Normal Forms 不能阻止您的数据库填充_错误_的数据,但它_可以_阻止您的数据库填充_不一致_的数据。如果你没有看到范式的好处,那么你还没有足够努力地研究它们。它们是数据库设计中排名第一的最佳实践。 (2认同)