2016-12-07 8 views
4

Я загрузки данных в таблицу следующим образом:Удалить против Откат стратегии - ETL нагрузки

DECLARE @srcRc INT; 
DECLARE @dstRc INT; 

SET @srcRc = (SELECT COUNT(*) FROM A) 

INSERT INTO t 
     (Col1 
     ,Col2 
     ,Col3 
     ) 
     SELECT A.Col1 
       ,A.Col2 
       ,B.Col3 
     FROM A 
       JOIN B 
        ON A.Id = B.Id; 

SET @dstRc = @@ROWCOUNT 

Теперь я сравниваю переменные @srcRc и @dstRc. ROWCOUNT должны быть одинаковыми. Если это не так, вставленные строки нужно удалить.

Вопрос 1. Какова была бы лучшая стратегия отката вставленных строк?

У меня есть пара идей:

1) Выполнить загрузку в транзакции и отката, если ROWCOUNT не совпадает.
2) Добавьте столбец столбца (бит) в таблицу назначения с именем toBeDeleted, запустите загрузку и если строка не совпадает, обновите столбец toBeDeleted с значением 1, чтобы указать его как кандидата для удаления. Затем удалите в пакетном режиме (while-loop).
Или не удаляйте их, но всегда исключайте удаленные кандидаты из запроса при работе с таблицей t.
3) Прежде чем вставлять строки, сначала сравните номер строки. Если это не соответствует, не запускайте загрузку.

DECLARE @srcRc INT; 
DECLARE @dstRc INT; 
SET @srcRc = (SELECT COUNT(1) FROM A); 
SET @dstRc = (SELECT COUNT(1) FROM A JOIN B ON A.Id = B.Id); 

Q2: Что было бы лучшим решением для большего количества строк, скажем, 10-100 mil.?
Q3: Есть ли какая-нибудь лучшая стратегия для подобного случая?

ответ

0

OK, Предполагая:

Вы должны откат к работе на более позднем этапе, когда содержание таблиц А и В может быть изменен

Там могут быть и другие строки в T, которые вы не» t хотите удалить как часть отката.

Затем вы должны держать список строк, вставленные, как вы не в состоянии надежно восстанавливать этот список из А и В, и вы не можете просто удалить все от T

Вы можете сделать это двумя способами

  • Измените свой импорт так, чтобы он сначала вставлял строки в таблицу импорта, сохраняя таблицу импорта, пока вы не уверены, что вам это больше не нужно.

  • Добавить дополнительный столбец для T [importId], в которую вы поставите однозначно идентифицирующий значение

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

Другим вариантом было бы сгенерировать список импортированных данных отдельно и сделать транзакционную sql объемной вставкой со всеми данными, жестко закодированными в sql.

Это хорошо подходит для небольших списков, исходных данных настройки и т. П.


Edit:

из ваших комментариев это звучит, как вы не хотите, откат за себе. Но лучший способ применить бизнес-логику вокруг процесса импорта.

В этом случае ваш третий ответ является лучшим. Не делайте импорт, если знаете, что исходные данные неверны.

+0

Мне нужно откат только «текущей» нагрузки, а не истории. Поэтому я обычно загружаю день ото дня. Сегодня я загружаю дату N, завтра N + 1. Таким образом, проверяется только текущая строка строки. И если rowcount не соответствует, все из текущей нагрузки нужно удалить, а не только некоторые из строк. – DNac

+0

проблема с этими сценариями - это не откат, если вы не отмените все, что бы вы ни делали. Все, что полагается на простой подсчет строк, может пойти не так. например, вы дублируете строку x и пропустите строку y. ваш счетчик строк будет соответствовать – Ewan

+0

Это правда, но этого случая никогда не было, и я считаю, что это очень редко. – DNac