在SQL Server的同一列上使用多个外键


10

SQL Server允许我在列上创建多个外键,并且每次使用不同的名称时,我都可以创建另一个引用同一对象的键。基本上所有键都定义相同的关系。我想知道在同一列中定义多个外键并引用另一个表中的同一列的用途。SQL Server允许我们做这样的事情有什么好处?

在此处输入图片说明

Answers:


12

具有仅因名称而异的冗余约束没有任何好处。同样,只有名称不同的冗余索引也没有好处。两者都增加了没有价值的开销。

SQL Server数据库引擎不会阻止您这样做。好的约束命名约定约束命名约定(例如FK_ReferencingTable_ReferencedTable)可以帮助防止此类错误。


17

SQL Server允许您做很多愚蠢的事情。

您甚至可以在引用其自身的列上创建外键-尽管事实上这绝不会违反,因为每一行都将满足其自身的约束。

在相同关系上创建两个外键的能力可能会有用的一种极端情况是,用于验证外键的索引是在创建时确定的。如果稍后出现更好(即更窄)的索引,则这将允许在更好的索引上绑定新的外键约束,然后原始约束将被丢弃而没有任何间隙且没有活动约束。

(如下例所示)

CREATE TABLE T1(
    T1_Id INT PRIMARY KEY CLUSTERED  NOT NULL,
    Filler CHAR(4000) NULL,
) 

INSERT INTO T1 VALUES (1, '');

CREATE TABLE T2(
    T2_Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    T1_Id INT NOT NULL CONSTRAINT FK REFERENCES T1 (T1_Id), 
    Filler CHAR(4000) NULL,
)


ALTER TABLE T1 ADD CONSTRAINT
    UQ_T1 UNIQUE NONCLUSTERED(T1_Id) 


/*Execution Plan uses clustered index*/ 
INSERT INTO T2 VALUES (1,1) 

ALTER TABLE T2  WITH CHECK ADD  CONSTRAINT FK2 FOREIGN KEY(T1_Id)
REFERENCES T1 (T1_Id)    

ALTER TABLE T2 DROP CONSTRAINT FK

/*Now Execution Plan now uses non clustered index*/    
INSERT INTO T2 VALUES (1,1)    

DROP TABLE  T2, T1;

除了过渡期外,同时存在两个约束条件时,最后要根据两个索引对所有插入进行验证。


可以使用事务来确保相同的无间隙约束更新吗?由于较少的锁定,这种非事务方法是否更好?
Binki

13

具有相同的外键约束是没有用的,即在同一列上并引用相同的表和列。

就像两次检查相同或两次以上。


-不同意。主表可能需要两个单独的检查。见下文实施例发送器和接收器是完全不同的- stackoverflow.com/questions/40400483/...
TREX

@trex您正在谈论一些不同的东西。这里的问题指出:“我想知道在同一个列上定义多个外键并在另一张表中引用同一列的用途是什么。”
ypercubeᵀᴹ

@ypercubeᵀᴹ-明白了。感谢您的澄清
trex

6

同样的原因,您可以在同一列上创建50个索引,添加第二个日志文件,将最大服务器内存设置为20MB ...大多数人不会做这些事情,但是偶尔有合理的理由要做,所以没有有利于在引擎中创建开销,以添加对仅不明智建议的检查。


2

听起来像是蓝绿色的东西。

当您开始从蓝色切换到绿色时,您需要临时创建事物的额外副本。

我们要做的是暂时创建一个额外的外键有什么CHECK WITH NOCHECKON UPDATE CASCADE ON DELETE SET NULL; 这是一个有效的外键,但是在创建键时不检查现有行。

稍后,在清理了所有应匹配的行之后,我们将创建没有任何命令选项的新外键(默认是CHECK WITH CHECK您通常需要的外键),并删除临时外键。

请注意,如果您只是删除并重新创建了外键,则一些垃圾行可能会被您滑走。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.