2

我正在使用 SQL 2005 实现具有车辆表、车辆发动机和车辆齿轮表的数据库设计。

每个表都有一个 ID,它是一个 SQL 标识号,每个引擎和齿轮都与车辆 ID 有关系。因此,在我创建车辆之前,我必须创建引擎和齿轮。

创建引擎和齿轮时如何知道车辆识别号?由于发动机和齿轮表的外键约束,尚未创建车辆行?

我是否应该实施一个自动触发器,在创建车辆时为连接到车辆的发动机和齿轮创建一个空行?但是我又怎么知道车辆ID呢?

4

10 回答 10

4

无论哪种方式,都无需在您没有数据的任何表中创建行。例如,拥有与车辆不匹配的发动机排是很好的。您可以在找到时添加缺少的内容。

我想我理解设计。每辆车可以有一个发动机和一个变速器。但是您可以在找到车辆之前记录变速器或发动机。

它们确实是独立的实体,因此请这样对待它们。您可能很容易得到与车辆永远不匹配的发动机和变速箱。

另一个更有趣的问题是,您是否可能最终得到与发动机匹配的变速器,但没有车辆。人们经常看到发动机和电车用螺栓固定在一起,却看不到任何车辆。它们也经常一起出售。

事实上,您可以想象这三个中的任何一个单独存在,或者与其他实体中的一个或两个匹配。

触发器在这里没有任何作用。如果使用,触发器应该被限制为关于模式结构的细粒度的参照完整性规则——而不是像这样的业务规则。没有强制性约束 - 每个外键都是可选的(可为空的)。并且有几种不同的方法来设置 FK 字段。

于 2008-12-11T10:09:28.053 回答
1

您在表之间具有外键关系这一事实并不意味着您必须按特定顺序创建数据。通常,人们会期望首先创建 Vehicle 记录,然后再为其分配引擎和齿轮,但情况并非如此。

如果在您的场景中,引擎或齿轮可能在分配给车辆之前记录在数据库中,那么您需要使引用车辆 ID 的 FK 列允许为空。一旦创建了车辆行,就可以将这些链接到车辆 ID。

或者,您可以创建您的车辆记录,然后在创建时为其分配发动机和齿轮记录。

于 2008-12-11T10:38:35.607 回答
1

你确定你的桌子设计正确吗?我真的不明白你们实体之间有什么样的关系。例如:您是否尝试在 Vehicle 和 Engine 之间创建一对多或多对一的关系?

一种选择可能是(如果它满足您的需求):

车辆:(ID、EngineID、GearID、...)

引擎(ID、其他引擎数据)

齿轮(ID,其他齿轮数据)

于 2008-12-11T09:55:54.227 回答
0

感谢所有的答案。

实际上我的意思是:车辆:(ID,其他车辆数据,...)发动机(ID,车辆ID,其他发动机数据)齿轮(ID,车辆ID,其他齿轮数据)

所以每辆车都可以有多个引擎和齿轮……(是的,我知道在现实世界中,一个引擎可以安装多辆汽车,但这不是我的目标)

我不知道在 SQL 2005 中默认设置为 YES 的强制外键约束。

所以将其设置为 NO 并知道它的工作正常。

再次感谢,

暗里。

于 2008-12-11T14:41:53.010 回答
0

每辆车只有一个发动机和一个齿轮吗?如果是这样,那么为什么它们在不同的表中?

如果您必须将它们放在两个表中,您可以创建一个 INSTEAD OF INSERT 触发器,如下所述:http: //msdn.microsoft.com/en-us/library/ms175089.aspx

于 2008-12-11T09:54:52.343 回答
0

如果您必须有两个单独的表,您可以将它们加入一个视图,然后更新/插入到视图中......

CREATE VIEW VehicleComplete AS SELECT * FROM Vehicle INNER JOIN VehicleEngine USING(VehicleID)

UPDATE VehicleComplete SET Rego = 'ABC 123', EngineModel = '380' WHERE VehicleID = 1
于 2008-12-11T10:04:58.000 回答
0

我不得不说,我个人认为这种情况没有意义,真的。

为了使齿轮或发动机存在,您需要车辆。您的业​​务规则/域模型应该真正强制执行,然后外键关系只是验证这种情况的一种方式。

或者,最好将发动机-车辆关系视为多对多。为此,您需要一个附加表来链接车辆和发动机。这意味着您可以有外键约束,但这也意味着一个引擎可以链接到许多汽车,反之亦然。这更真实地模拟了现实世界,在许多汽车模型中使用相同的引擎,并且汽车可能有多种引擎可供选择。

于 2008-12-11T10:10:51.280 回答
0

这类事情可以通过任何持久性框架来解决。在典型的 O/R 映射器场景中,您只需创建所需的实体(例如间接地),然后 O/R 映射器以正确的顺序保存它们并自动同步 FK/PK 字段。

如果您正在与这些问题作斗争,那么您真的会在已经为您解决的事情上浪费时间(因此也浪费金钱),并且您不能将这些时间花在为客户解决问题上。因此,请帮您自己和您的客户一个忙,至少看看那里的一些持久性框架。

(免责声明:我是 o/r 映射器框架的主要开发人员)

于 2008-12-11T10:15:51.037 回答
0

但是我又怎么知道车辆ID呢?

插入触发器中有一个名为INSERTED的表。您将在此处找到车辆 ID。

于 2008-12-11T10:18:01.233 回答
-1

如果你真的不能在不同的时刻创建每个实体,你应该在事务中创建它们,明确显示创建每个实体的必要步骤。

很多时候更容易实现的触发器解决方案将是最难维护的,因为它“隐藏”在 curtins 重要的业务规则后面。

好吧....在任何一种情况下,你都应该看看你的问题定义,因为这类问题通常是由糟糕的业务领域定义引起的。

底线:您拥有的每个触发器都会为下一个项目迭代带来另一个麻烦。

于 2008-12-11T10:38:19.960 回答