#etl #data-warehouse #cdc
#etl #хранилище данных #cdc
Вопрос:
Я внедряю витрину данных, следуя методологии Кимбалла, и у меня есть проблема с применением дельт из нескольких исходных таблиц к одному целевому измерению.
Вот пример входящих исходных данных:
STG_APPLICATION
APP_ID, APP_NAME, APP_START_DATE, CDC_HASH, ...
1, FOOBAR, 20/10/2018, MD5_XXX
STG_APPLICATION_STATUS
APP_ID, STATUS_CODE, STATUS_DESC, CDC_HASH, ...
1, SUBMITTED, "APP WAS SUBMITTED", MD5_YYY
Каждая из этих таблиц (есть несколько других) представляет собой нормализованную версию исходных данных, т.Е. Одно приложение может иметь один или несколько статусов, связанных с ним.
Теперь, поскольку мы получаем только полную альфа-версию для этих таблиц, нам нужно выполнить слияние моментальных снимков, то есть применить полное внешнее объединение к набору записей текущего дня к набору записей предыдущего дня для каждой отдельной таблицы. Это вычисляется путем сравнения CDC_HASH (конкат всех исходных столбцов). Результат этого сравнения сохраняется в дельта-таблице следующим образом:
STG_APPLICATION_DELTA
APP_ID, APP_NAME, APP_START_DATE, CDC_HASH, CDC_STATUS ...
STG_APPLICATION_STATUS
APP_ID, STATUS_CODE, STATUS_DESC, CDC_HASH, CDC_STATUS...
1, AWARDED, "APP WAS AWARDED", MD5_YYY, NEW
Итак, в этом примере первая таблица STG_APPLICATION не создавала дельта-запись, поскольку атрибуты, относящиеся к этой таблице, не менялись между ежедневными загрузками. Однако связанная таблица STG_APPLICATION_STATUS рассчитала дельту, т. Е. Одно или несколько полей изменились с момента последней загрузки. Это выделяется CDC_STATUS, который идентифицирует его как новую запись для вставки.
Проблема сейчас, конечно, в том, как правильно справиться с этой ситуацией при загрузке целевого измерения? Например:
DIM_APPLICATION
ID, APPLICATION_ID, APP_NAME, APP_START_DATE, APP_STATUS_CODE, FROM_DATE, TO_DATE
1, 1, FOOBAR, 20/10/2018, SUBMITTED, 20/10/2018, 12/04/2019
2, 1, NULL, NULL, NULL, AWARDED, 13/04/2019, 99/99/9999
Здесь показана первая запись, основанная на объединении этих двух промежуточных таблиц, и вторая запись, которая должна отражать обновленную версию записи. Однако, как показано ранее, мои дельта-таблицы заполнены лишь частично, и поэтому я не могу корректно обновить измерение, как показано здесь.
Логически я понимаю, что мне нужно иметь возможность включать все поля, которые используются измерением, как часть моего дельта-вычисления, чтобы у меня была копия полной записи при обновлении измерения, но я не уверен в лучшем способе реализовать это в моей промежуточной области. Как уже было показано, в настоящее время у меня есть только независимые промежуточные таблицы, каждая из которых вычисляет свою дельту отдельно.
Пожалуйста, может кто-нибудь посоветовать, как лучше всего справиться с этим? Я тщательно изучил книги Кимбалла по этому вопросу, но безрезультатно. И я также не нашел подходящего ответа ни на одном онлайн-форуме. Это распространенная проблема, поэтому я уверен, что существует подходящий архитектурный шаблон для ее решения.
Ответ №1:
Вам нужно будет либо сравнить объединенные записи, либо выполнить поиск текущих значений измерений.
Если объем (неизмененных) данных не является чрезмерным, вы можете объединить полные снимки STG_APPLICATION и STG_APPLICATION_STATUS вместе в APP_ID, пока они не будут похожи на запись измерения по столбцам, и сохранить их в отдельной таблице с их хэшем CDC для использования в качестве предыдущего дня. Затем вы берете дельты на этом уровне и отправляете (полные) измененные записи в качестве обновлений в измерение.
Если количество записей в ежедневном обновлении делает непрактичным объединение полных таблиц, вы можете использовать дельты и полное внешнее объединение, как вы делаете сейчас. Затем вы просматриваете текущую запись измерения для этого APP_ID и заполняете все пустые поля в дельта-записи. Затем завершенная запись отправляется в качестве обновления в измерение. Это решение требует меньше места для хранения, но кажется более хрупким, особенно если в течение дня возможно несколько изменений. Если изменений много, производительность также может пострадать. Для нескольких изменений в миллионах записей это должно быть более эффективным.