如何在事务期间保持主密钥和外键之间的数据一致性
发布于 2016-06-16 14:34:43
将外键添加到某些表时,SQL将使用特定运算符来验证连续性。
演示:
表创建脚本:
create table pktest
(
pk int not null primary key
)
create table FKtest
(
fk int
CONSTRAINT fkconstarint FOREIGN KEY (fk)
REFERENCES pktest(pk)
)
-现在将一些数据插入主键表中
insert into pktest
select 2
现在将一些有效数据插入外键表中
insert into fktest
select 2
让我们看一下执行计划,使用showplan_text在
> |--Assert(WHERE:(CASE WHEN NOT [Pass1008] AND [Expr1007] IS NULL THEN (0) ELSE NULL END))
|--Nested Loops(Left Semi Join, PASSTHRU:([test].[dbo].[FKtest].[fk] IS NULL), OUTER REFERENCES:([test].[dbo].[FKtest].[fk]), DEFINE:([Expr1007] = [PROBE VALUE]))
|--Table Insert(OBJECT:([test].[dbo].[FKtest]), SET:([test].[dbo].[FKtest].[fk] = [@1]))
|--Clustered Index Seek(OBJECT:([test].[dbo].[pktest].[PK__pktest__0425A276]), SEEK:([test].[dbo].[pktest].[pk]=[test].[dbo].[FKtest].[fk]) ORDERED FORWARD)
解码上述计划:
1.查找fktest并将插入值作为Expr1007
返回。
2.然后使用Expr1007
探讨pktest,如果值为Pass1008
,则返回
然后断言检查,如果Expr1007
或Pass1008
不是null,则返回0
并继续执行
什么是Expr1007
为null,嵌套循环将返回null,因此我们可以继续执行
这就是约束保持原样的方式。
当我们创建带有out唯一关键字的主键时,SQL内部添加了uniquifier以使其惟一,并检查是否插入了重复。
参考资料:
https://www.simple-talk.com/sql/learn-sql-server/showplan-operator-of-the-week---assert/
https://stackoverflow.com/questions/37860280
复制相似问题