Включение и выключение ограничений внешнего ключа

У нас есть длительный процесс ETL, который передает данные из входных файлов через ряд таблиц.

Я рассматриваю маловероятную возможность добавления реляционной целостности к нашим таблицам, но я не хочу, чтобы наш процесс ETL умирал, когда он сталкивается с нарушением. Я также хочу, чтобы записи, нарушающие ссылочную целостность, по-прежнему загружались. Однако, в конце концов, я хочу быть в курсе всех нарушений ссылочной целостности.

Метод 1: я мог бы оставить ссылочную целостность отключенной и написать процедуру SQL, которая запускает кучу хранимых процедур для выявления записей, нарушающих реляционную целостность, но мне очень нравится идея, что целостность отношений находится в самих таблицах, потому что я чувствую, что это документирует база данных в лучшем месте - БД.

Способ 2: вместо того, чтобы писать набор пользовательских запросов для выявления нарушителей, я думаю, что мы должны удалить всю целостность ссылок в начале нашего процесса, а затем добавить ее в конце. Там, где мы получаем исключения, мы знаем, что есть нарушения. Мне вроде как нравится этот подход, но в отличие от метода 1, где SQL может быть написан для таргетинга только на записи, только что добавленные для потенциальных нарушителей, добавление целостности ссылок, вероятно, приведет к повторной проверке всей таблицы — таблицы, которая постоянно растет. Когда целостность ссылок снова включена, потребитель данных может быть уверен, что данные «хорошие», без выполнения запросов «на лету». Мне нравится это...

Есть ли третий подход? Я вижу, что T-SQL поддерживает такие команды, как

NOCHECK CONSTRAINT  
ON UPDATE  NO ACTION  
ON INSERT  NO ACTION

но я не уверен, как они действительно предназначены для использования. Например,

ИЗМЕНИТЬ ТАБЛИЦУ dbo.TableName NOCHECK CONSTRAINT FK01

Смысл этого в том, чтобы отключить контрольную проверку, когда у вас есть надежный источник? Я предполагаю, что если он выключен, а затем включен таким образом, настройка chg применяется только к будущим операциям.

Какой наилучший подход вы бы использовали, чтобы позволить процессу завершиться до конца и при этом выявить все нарушения реляционной целостности или потенциальные нарушения реляционной целостности?


person Chad    schedule 02.11.2011    source источник
comment
У нас аналогичная ситуация, существующие задачи, на которые клиенты полагаются изо дня в день, что может привести к неверным данным, но не влияет на их бизнес. Я выбрал ваш вариант 1, потому что мы можем запускать пользовательские процедуры проверки на месте и видеть, какие данные уже недействительны, поэтому мы знаем, что нам нужно исправить (данные и программы), прежде чем мы сможем включить ограничения целостности, которые мы хотим добавить.   -  person WileCau    schedule 01.05.2013


Ответы (2)


1. Я обнаружил, что имя NO ACTION немного вводит в заблуждение, поскольку оно означает, что DML завершится ошибкой, если нарушит ограничение. Некоторые RDMS, в частности mysql, имеют лучшее ключевое слово - RESTRICT, которое является более описательным.
2. Вы можете временно отключить/включить все ограничения с помощью ALTER TABLE ... NOCHECK/CHECK CONSTRAINT ALL

person a1ex07    schedule 02.11.2011

Лично я бы никогда не отключил ограничения FK. Это начало скользкого спуска в ад. Они там по причине.

Я бы разделил ваш ETL на пакеты по N строк и обернул каждую в транзакцию. Если транзакция не удалась из-за нарушения FK, зарегистрируйте ее и сделайте все, что вам нужно для восстановления. Никогда не оставляйте плохие данные.

person Deleted    schedule 02.11.2011