使用外键向数据库添加新项时,是否应该使用SQL触发器在其他表中创建相关行?

时间:2008-12-11 09:19:55

标签: sql database-design triggers foreign-keys constraints

我正在实施一个数据库设计,其中包含一个带有SQL 2005的车辆工作台,车辆引擎和车辆齿轮表。

每个表都有一个ID为SQL标识号的ID,每个引擎和齿轮都与车辆ID有关系。 因此,在创造车辆之前,我必须创造一个发动机和齿轮。

创建发动机和齿轮时,我怎么知道车辆识别号码?由于发动机和齿轮表的外键约束,车辆行尚未创建?

我是否应该实施自动触发器,在创建车辆时为发动机和与车辆相连的齿轮创建空行?但我怎么能知道车辆ID?

10 个答案:

答案 0 :(得分:4)

无论哪个,都不需要在没有数据的任何表中创建行。例如,可以使用与车辆无法匹配的发动机排。您可以在找到时添加遗漏的内容。

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

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

另一个更有趣的问题是,你是否可能最终得到与发动机相匹配的变速器,但没有车辆。人们常常看到发动机和电动机连接在一起,看不到车辆。它们通常也会一起出售。

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

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

答案 1 :(得分:1)

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

如果在您的方案中,在分配给车辆之前可以将发动机或齿轮记录在数据库中,那么您将需要使引用车辆ID的FK列允许空值。一旦车辆行被创建,这些就可以链接到车辆ID。

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

答案 2 :(得分:1)

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

一个选项可能是(如果它符合您的需求):

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

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

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

答案 3 :(得分:0)

感谢所有答案。

其实我的意思是: 车辆:(身份证,其他车辆数据......) 引擎(ID,VehicleID,其他引擎数据) 齿轮(ID,VehicleID,其他齿轮数据)

所以每辆车都可以有多个发动机和齿轮......(是的,我知道在现实世界中,发动机可以安装多辆车,但这不是我的目标)

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

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

再次感谢,

欧米。

答案 4 :(得分:0)

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

如果必须在两个表中使用它们,则可以按照此处所述创建INSTEAD OF INSERT触发器:http://msdn.microsoft.com/en-us/library/ms175089.aspx

答案 5 :(得分:0)

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

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

UPDATE VehicleComplete SET Rego = 'ABC 123', EngineModel = '380' WHERE VehicleID = 1

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:0)

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

如果你正在与这些问题作斗争,你真的会浪费时间(因而也就是金钱)而不是已经为你解决的问题而且你不能把时间花在客户的问题上。所以你自己和你的客户一定要帮忙,至少要看看那里的一些持久性框架。

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

答案 8 :(得分:0)

  

但我怎么能知道这辆车   ID?

有一个名为INSERTED的表,可在插入触发器中使用。你会在那里找到车辆ID。

答案 9 :(得分:-1)

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

触发解决方案,实施起来要好很多倍,是最难维护的,因为它“隐藏”了特定重要业务规则的背后。

嗯....在任何一种情况下,你真的应该看看你的问题定义,因为这类问题通常来自糟糕的业务领域定义。

底线:您的每次触发都会成为下一次项目迭代的另一个问题。

豫ICP备18024241号-1