如何保留数据一致性,包括事务和PK和FK

时间:2016-06-16 13:09:53

标签: sql transactions primary-key

如何在事务期间保持主键和外键之间的数据一致性

1 个答案:

答案 0 :(得分:0)

将外键添加到某个表时,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

值,则返回

然后断言检查,如果Expr1007Pass1008不为null,则返回0并继续执行

什么是Expr1007为null,嵌套循环将返回null,因此我们可以继续执行

这是约束保持完好的方式

当我们使用唯一关键字创建主键时,SQL会在内部添加uniquifier以使其唯一并检查是否插入了重复项

<强>参考文献:
https://www.simple-talk.com/sql/learn-sql-server/showplan-operator-of-the-week---assert/