#snowflake-cloud-data-platform #data-warehouse #external-tables #delta-lake #dbt
#snowflake-облачная платформа для обработки данных #хранилище данных #внешние-таблицы #дельта-озеро #dbt ( дбт ) #snowflake-облачная платформа данных #внешние таблицы #dbt
Вопрос:
Вопрос
основной вопрос
Как я могу эфемерно материализовать медленно изменяющийся тип измерения 2 из папки ежедневных извлечений, где каждый csv представляет собой одно полное извлечение таблицы из исходной системы?
обоснование
Мы разрабатываем эфемерные хранилища данных как витрины для конечных пользователей, которые можно развернуть и сжечь без последствий. Для этого у нас должны быть все данные в озере / большом двоичном объекте / корзине.
Мы ежедневно копируем полные выдержки, потому что:
- мы не смогли надежно извлечь только набор изменений (по независящим от нас причинам), и
- мы хотели бы поддерживать озеро данных с «наименьшими» возможными данными.
проблемный вопрос
Есть ли решение, которое могло бы предоставить мне состояние на определенную дату, а не только «новейшее» состояние?
экзистенциальный вопрос
Я думаю об этом полностью в обратном направлении, и есть гораздо более простой способ сделать это?
Возможные подходы
пользовательская dbt
материализация
В insert_by_period
пакете есть dbt.utils
материализация dbt, которая, я думаю, может быть именно тем, что я ищу? Но я в замешательстве, поскольку это dbt snapshot
, но:
- запуск
dbt snapshot
для каждого файла постепенно, все сразу; и, - создается непосредственно из внешней таблицы?
Дельта-озеро
Я мало что знаю о дельта-озере Databricks, но, похоже, это должно быть возможно с дельта-таблицами?
Исправьте задание извлечения
Решена ли наша проблема, если мы можем заставить наши извлечения содержать только то, что изменилось с момента предыдущего извлечения?
Пример
Предположим, что следующие три файла находятся в папке озера данных. (Суть с 3 CSV и желаемым результатом таблицы в формате CSV). Я добавил извлеченный столбец на случай, если разбор метки времени из имени файла слишком сложен.
2020-09-14_CRM_extract.csv
| OppId | CustId | Stage | Won | LastModified | Extracted |
|-------|--------|-------------|-----|--------------|-----------|
| 1 | A | 2 - Qualify | | 9/1 | 9/14 |
| 2 | B | 3 - Propose | | 9/12 | 9/14 |
2020-09-15_CRM_extract.csv
| OppId | CustId | Stage | Won | LastModified | Extracted |
|-------|--------|-------------|-----|--------------|-----------|
| 1 | A | 2 - Qualify | | 9/1 | 9/15 |
| 2 | B | 4 - Closed | Y | 9/14 | 9/15 |
| 3 | C | 1 - Lead | | 9/14 | 9/15 |
2020-09-16_CRM_extract.csv
| OppId | CustId | Stage | Won | LastModified | Extracted |
|-------|--------|-------------|-----|--------------|-----------|
| 1 | A | 2 - Qualify | | 9/1 | 9/16 |
| 2 | B | 4 - Closed | Y | 9/14 | 9/16 |
| 3 | C | 2 - Qualify | | 9/15 | 9/16 |
Конечный результат
Ниже приведен SCD-II для трех файлов по состоянию на 9/16. SCD-II по состоянию на 9/15 будет таким же, но OppId=3
имеет только один из valid_from=9/15
и valid_to=null
| OppId | CustId | Stage | Won | LastModified | valid_from | valid_to |
|-------|--------|-------------|-----|--------------|------------|----------|
| 1 | A | 2 - Qualify | | 9/1 | 9/14 | null |
| 2 | B | 3 - Propose | | 9/12 | 9/14 | 9/15 |
| 2 | B | 4 - Closed | Y | 9/14 | 9/15 | null |
| 3 | C | 1 - Lead | | 9/14 | 9/15 | 9/16 |
| 3 | C | 2 - Qualify | | 9/15 | 9/16 | null |
Комментарии:
1. Существует ли период хранения, в течение которого вы хотели бы сохранить эти исторические данные? Вы могли бы легко использовать перемещение во времени в Snowflake для этого, если ваше хранение составляет менее 90 дней, что, как я понимаю, встречается нечасто.
2. @MikeWalton отличный вопрос. Хотя я уверен, что некоторые сценарии рассчитаны только на 90 дней, большинству заинтересованных сторон требуется 2 года для годовых ключевых показателей эффективности, а жадная команда ML хочет получить всю историю за все время (смехотворно).
3. Довольно типично. Я также видел, как ежемесячно продлевается 13-месячное удержание в годовом исчислении, но сделка одна и та же.
4. Привет — не могли бы вы пояснить, что вы подразумеваете под «эфемерным хранилищем данных»? Я могу понять, почему вы могли бы создать «эфемерную витрину данных» из постоянного хранилища данных, но я никогда не сталкивался с концепцией эфемерного хранилища данных. Если вы «просто» пытаетесь создать хранилище данных, то ситуация, которую вы описываете, является стандартным шаблоном: вы сравниваете свой исходный файл с таблицей измерений и вставляете записи, которые не существуют, и обновляете те, которые существуют. Учитывая, что это такой распространенный сценарий, я предполагаю, что я не понимаю, в чем ваша реальная проблема? Если да, не могли бы вы уточнить, пожалуйста?
5. К вашему сведению — «наилучшей практикой» является установка ваших значений valid_to на дату в далеком будущем, а не на нули. Это упрощает / повышает производительность запросов, поскольку вы можете использовать «где дата между valid_from и valid_to», а не «где дата между valid_from и valid_to или (дата>= valid_from и valid_to равно нулю)»
Ответ №1:
Интересная концепция и, конечно, это займет больше времени, чем возможно на этом форуме, чтобы полностью понять ваш бизнес, заинтересованных лиц, данные и т.д. Я вижу, что это могло бы сработать, если бы у вас был относительно небольшой объем данных, ваши исходные системы редко менялись, ваши требования к отчетности (и, следовательно, к таблицам данных) также редко менялись, и вам нужно было только очень редко запускать эти таблицы данных.
Мои опасения были бы:
- Если ваши исходные или целевые требования изменятся, как вы собираетесь с этим справиться? Вам нужно будет развернуть вашу таблицу данных, выполнить полное регрессионное тестирование на ней, применить ваши изменения, а затем протестировать их. Если вы делаете это по мере того, как / когда изменения известны, то это требует больших усилий для неиспользуемой таблицы данных, особенно если вам нужно делать это несколько раз между использованиями; если вы делаете это, когда нужна таблица данных, то вы не достигаете своей цели по предоставлению карты данных для «мгновенного» использования.
Я не уверен, что ваше утверждение «у нас есть DW как код, который можно удалять, обновлять и воссоздавать без сложностей, связанных с традиционным управлением изменениями DW», верно. Как вы собираетесь тестировать обновления своего кода без запуска datamart (ов) и прохождения стандартного цикла тестирования с данными — и чем это отличается от традиционного управления изменениями DW?
- Что произойдет, если в ваших исходных системах есть поврежденные / неожиданные данные? В «обычном» DW, где вы загружаете данные ежедневно, это обычно было бы замечено и исправлено в течение дня. В вашем решении сомнительные данные могли появиться несколько дней / недель назад, и, предполагая, что они загружены в вашу таблицу данных, а не с ошибкой при загрузке, вам понадобятся процессы, чтобы определить это, а затем, возможно, придется распутывать записи SCD за несколько дней, чтобы устранить проблему
- (Актуально только при наличии значительного объема данных) Учитывая низкую стоимость хранилища, я не уверен, что вижу преимущество в развертывании datamart, когда это необходимо, в отличие от простого хранения данных, чтобы они были готовы к использованию. Загрузка больших объемов данных при каждом запуске datamart займет много времени и будет дорогостоящей. Возможный гибридный подход может заключаться в том, чтобы запускать инкрементные загрузки только тогда, когда требуется datamart, а не запускать их каждый день — таким образом, у вас всегда есть данные о том, когда datamart использовался в последний раз, и вы просто добавляете записи, созданные / обновленные с момента последней загрузки
Ответ №2:
Я не знаю, лучшее это решение или нет, но я видел, как это делается. При создании исходной таблицы SCD-II добавьте столбец, который является сохраненным HASH()
значением всех значений записи (вы можете исключить первичный ключ). Затем вы можете создавать внешнюю таблицу поверх вашего ежедневного полного набора данных, который включает ту же HASH()
функцию. Теперь вы можете выполнить MERGE
или INSERT/UPDATE
для вашего SCD-II на основе первичного ключа и того, изменилось ли значение ХЭША.
Ваше главное преимущество при выполнении таких действий заключается в том, что вы избегаете ежедневной загрузки всех данных в Snowflake для сравнения, но выполнение этого способа будет медленнее. Вы также можете загрузить временную таблицу с HASH()
функцией, включенной в вашу COPY INTO
инструкцию, а затем обновить SCD-II и затем удалить временную таблицу, что на самом деле может быть быстрее.
Комментарии:
1. полностью. но предположим, что этот процесс SCD-II выполнялся в течение нескольких месяцев, но затем был удален в одночасье. Как я мог воссоздать его точно таким, каким он был до его удаления, но ссылаясь на исходные файлы. Моя идея заключается в том, чтобы перебирать каждый CSV в хронологическом порядке и запускать обновление для каждого файла? Меня беспокоит то, что это кажется большой перегрузкой и не способствует распараллеливанию.
2. Нет, ИМЕННО здесь вступает в игру ваше путешествие во времени в Snowflake. Просто воссоздайте таблицу с использованием перемещения во времени в точке, где таблица была удалена.
3. Теперь, если вы хотите чисто гипотетическую перестройку, вы могли бы использовать внешнюю таблицу для каждого имеющегося у вас файла, а затем использовать оконные функции и хэш для воссоздания вашей таблицы. Это можно сделать с помощью одной инструкции, функции окна для выбора записей, хэш которых отличается от текущего хэша, используя
LAG
, а затем выберитеLAG
значение для вашей даты valid_to.4. да, так что путешествие во времени исключено, потому что нам нужно поддерживать многолетнюю историю. идея внешней таблицы для каждого файла интересна. Я думаю, что я мог бы использовать
dbt
, чтобы это произошло в обязательном порядке с Jinja5. Когда я упоминал о путешествии во времени, я имел в виду «восстановление после случая, когда ваша таблица была удалена». Вместо того, чтобы перестраивать всю таблицу, вы могли бы просто использовать перемещение во времени для восстановления после этого удаления.