2011-11-02 60 views
2

我们有一个很长的ETL过程,它将来自输入文件的数据通过一系列表格进行流动。打开和关闭外键约束

我认为向我们的表添加关系完整性的可能性不大,但我不希望我们的ETL过程在遇到违规时死掉。我也想要违反参照完整性的记录仍然被加载。然而,最后,我想知道所有违反参照完整性的行为。

方法1: 我可以将参照完整性关闭并编写一个运行一堆存储过程的SQL过程来识别违反关系完整性的记录,但我真的很喜欢关系完整性在表上本身的想法,因为我觉得这会将数据库记录在最佳位置 - 数据库。

方法2: 我认为我们应该在流程开始时删除所有ref完整性,然后在最后添加它,而不是编写一组自定义查询来标识违规者。如果我们得到例外,我们知道存在违规行为。我喜欢这种方法,但是可以像方法1那样编写一个SQL来只针对潜在的违规者添加的记录,增加ref完整性可能会重新检查整个表 - 这个表不断增长。当ref完整性被重新打开时,数据的使用者可以确信数据是“好的”,而不需要再进行即时查询。我喜欢那个......

有没有第三种方法? 我看到T-SQL支持像

NOCHECK CONSTRAINT 
ON UPDATE NO ACTION 
ON INSERT NO ACTION 

命令,但我不知道他们是如何真正意图使用。例如,

ALTER TABLE dbo.TableName NOCHECK约束FK01

是这个意图关闭constrationmt检查,当你有一个可靠的消息来源?我假设如果它关闭,然后以这种方式打开,设置chg仅适用于未来的操作。

你会用什么最好的方法来让一个进程完成到最后,并且仍然能够识别出所有的关系完整性或者可能的关系完整性违规?

+0

我们有类似的情况,现有的客户依靠一天到一天这可能会导致无效的数据,但并不影响他们的业务任务。我选择了1,因为我们可以在现场运行自定义验证程序,并查看哪些数据已经失效,因此我们知道需要修复哪些数据(程序和数据),然后才能启用我们要添加的完整性约束。 – WileCau

回答

1

1.我发现NO ACTION名称有点误导,因为这意味着如果违反约束条件,DML将会失败。一些RDMS,尤其是mysql,有一个更好的关键字 - RESTRICT这更具描述性。
2.您可以暂时禁用/启用所有的约束与ALTER TABLE ... NOCHECK/CHECK CONSTRAINT ALL

0

我个人从不关闭FK限制。这是一个滑入地狱的开始。他们在那里是有原因的。

我会把你的ETL分成N行批量包装每个交易。如果由于违反FK而导致交易失败,请记录它并执行任何您的恢复要求。切勿将不良数据保留在内。