2

我正在尝试正确使用外键来维护数据完整性。我不是一个真正的数据库专家,所以我想知道是否有一些我不知道的一般设计原则。这是我正在尝试做的一个例子:

假设您要构建具有类型(汽车、卡车等)、品牌和型号的车辆数据库。用户必须至少输入 Type,但 Make 和 Model 是可选的(如果给出了 Model,那么 Make 是必需的)。我的第一个想法是这样设置数据库:

Type:
-id (PK)
-description

Make:
-id (PK)
-type_id (FK references Type:id)
-description

Model:
-id (PK)
-make_id (FK references Make:id)
-description

Vechicle:
-id (PK)
-type_id (FK references Type:id)
-make_id (FK references Make:id)
-model_id (FK references Model:id)

您将如何设置车辆的 FK 以确保类型、品牌和型号都匹配?例如,您将如何防止车辆出现(类型:摩托车、制造商:福特、型号:思域)?其中每一个都是有效的 FK,但它们不维护通过其他表的 FK 显示的关系。

另外,因为不需要 Model,我不能只存储 model_id FK 并从它向后工作。

我完全不依赖于数据库设计,所以我愿意改变表的设置方式。有任何想法吗?

PS - 如果有人感兴趣,我正在使用 mysql,但这更多是关于数据库的一般问题。

编辑(澄清):

车辆表中需要 -type_id 和 make_id ,除非在 model_id 为空的情况下有某种方法可以找出它们;

- 需要维护 type_id、make_id 和 model_id 之间的关系。

4

5 回答 5

2

像这样:

类型:

  • 身份证(PK)
  • 描述

制作:

  • 身份证(PK)
  • type_id(FK 引用类型:id,不为空)
  • 描述

模型:

  • 身份证(PK)
  • make_id(FK 引用 Make:id,不为空)
  • 描述

车辆:

  • 身份证(PK)
  • model_id(FK 参考型号:id)

基本上也不要重复参考车辆的品牌和类型。如果你这样做,你会遇到问题。您可以从车辆型号(如果已定义)中获取品牌和类型。型号必须有品牌。Make 必须有类型。

想一想:如果车辆有给定的型号,但车辆和型号都有品牌,那么这些值可能不同。由于信息冗余,这种不一致可能会发展。您通常希望避免这种情况。

如果您需要确定车辆的品牌和类型,SQL 开始如下所示:

SELECT v.id, v.model_id, m.make_id, k.type_id
FROM vehicle v
LEFT JOIN model m ON v.model_id = m.id
JOIN make k ON m.make_id = k.id
JOIN type t ON k.type_id = t.id

等等。

于 2009-11-13T23:41:23.640 回答
2

您正在寻找的是一个 CHECK 约束。不幸的是 MySQL 目前不支持这个。您可以使用触发器模拟此类功能,但您需要创建一个 INSERT 和一个 UPDATE 触发器才能使其工作。

但是,正如其他答案所表明的那样,您真正应该存储的只是车辆模型。在您的应用程序中,如果可用,您应该深入了解该类型。

于 2009-11-13T23:45:32.383 回答
1

这是一种方法:

- 一个品牌(福特、通用、本田)可以有多个车型,一个车型只属于一个品牌。
-模型属于某种类型(汽车、卡车自行车)。
-车辆是特定型号的。一辆只能是一种型号;一个模型可以有很多辆车。

模型表包含所有模型共有的列;而汽车、卡车和摩托车都有各自特定的列。

在对数据库建模时,考虑数据、实体和关系;不要从 UI 开始——中间有一个业务层来解决问题。可以使用 MySQL,您可以在应用程序层上强制检查和外键约束。

车辆模型_01

于 2009-11-14T15:53:31.437 回答
0

您的设计适合数据完整性,您的应用程序将负责维护车辆必须由特定类型的品牌和特定品牌的型号组成。

如果您想在数据库中维护车辆类型/品牌/型号的完整性,您可以向您的车辆表添加一个检查约束,以确保车辆的品牌类型 ID 等于提供的类型 ID。如果模型 ID 不为空,请确保它的制造 ID 与提供的制造 ID 相同。

于 2009-11-13T23:40:04.547 回答
-1

我看到您已经接受了一个答案,但是另一种处理您的实际结构问题并且不使用触发器或检查约束的替代方法是在 Make 和 Model 表中创建虚拟条目,并描述为“n/a”等, Type 和 Make 中的每个条目分别对应一个,然后去掉 Vehicle 中的冗余列。

这样,如果您只知道车辆的类型,您会在 Make 中找到引用适当类型的虚拟条目,然后在 Model 中找到引用该 Make 的虚拟条目,然后从新行中引用该模型车辆。

当然,主要的缺点是额外的内务管理来创建虚拟行,或者在添加类型或制造时提前,或者在添加缺少数据的车辆时按需添加。

于 2009-12-09T20:10:19.330 回答