В мире больших данных
218 subscribers
34 photos
5 files
54 links
Полезные заметки о системном анализе в мире больших данных. Если вам интересны Big Data, DWH, SQL и как навести порядок в данных — заглядывайте. Будет интересно и по делу.

Автор: @JuliaMur
Download Telegram
Загрузка данных в хранилище: полная, инкрементальная и частичная перезагрузка

Что самое главное в DWH? Конечно же, данные, которые как-то должны попасть в хранилище. Чаще мы используем современные методы загрузки, но на ранних этапах или из-за тех. ограничений, или при исследованиях, мы всё также прибегаем к классическим методам.

Есть три основных подхода: полная загрузка, инкрементальная и частичная перезагрузка. Системным аналитикам важно понимать когда какой подход лучше использовать.

При полной загрузке мы каждый раз заново забираем все данные из источника, полностью заменяя существующие данные в хранилище. Почему "полностью" курсивом? Иногда нам нужно отслеживать удалённые строки, тогда мы не просто транкейтим, а размечаем отсутствующие строки флагом DELETED.

Полная загрузка — самый простой метод со своими особенностями:
простота реализации
100% актуальность данных
высокая нагрузка при больших объемах данных
время выполнения
неэффективное использование ресурсов при небольших изменениях.

Этот метод идеален для небольших таблиц или когда нужна полная уверенность в актуальности данных. Также он хорошо подходит для справочников и других статичных данных, которые обновляются очень редко (обратите внимание, что редко определяется требованиями конкретного бизнеса).


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

Для больших таблиц с частыми апдейтами — то, что надо. Важно❗️если нужно отслеживать изменения, у таблиц должно быть поле, содержащее дату и время обновления строки. Убедитесь, что вы можете доверять ему. Комментарии к полям могут врать! В моей практике были случаи, когда дата содержала инфу об изменении только нескольких полей из таблицы, что не было нигде явно указано 🥲 (да, иногда нужно покапаться в коде источника)

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

Если мы говорим только про забор новых изменений, нам нужно инкрементное поле или поле с датой добавления строки (желательно заполняемое getdate), по которому мы будем забирать только новые строки. Метод отлично подходит для логов.


Частичная перезагрузка — гибрид предыдущих способов. Здесь мы перезагружаем только часть данных, обычно за какой-то конкретный период.
баланс актуальности и эффективности
обновление за определенный период без полной перезагрузки
удобно для данных с "окном актуальности"
сложно определить оптимальный период
риск дублей при неправильной реализации
нужна дополнительная логика для определения границ загрузки

Частичную перезагрузку часто применяют для данных с "окном актуальности", например, когда нужно обновить данные за последний месяц или квартал. Когда точно известно, что "более старые" данные неизменны. Здесь та же история, про которую я писала выше, у вас должно быть поле с датой, которому вы точно можете доверять.


Подытожу, выбор метода загрузки зависит от многих факторов: объема данных, частоты обновлений, требований к актуальности и доступных ресурсов. Но даже если на первый взгляд кажется, что выбрать нужный метод просто, в реальной жизни часто приходится идти на компромиссы или комбинировать подходы. Например, объект с миллионами строк без даты обновления можно днем грузить инкрементально, а раз в неделю обновлять целиком. Так себе история и, конечно, лучше использовать иные методы загрузки, но ситуации бывают разными. Будьте к ним готовы.

Благодаря тому, что источники не идеальны, работа системного аналитика всегда где-то на грани творчества и здравого смысла 😇

#dwh
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3
Всегда хочется быть сильной, ведь кажется, что сила и развитие — это обязательные условия нашего времени. Но не всегда это можется, а скорее всего и не нужно. Иногда полезно отпустить стремление быть успешной, позволив себе принять слабость как временную передышку.

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

Поэтому на канале небольшая пауза — чтобы восстановиться и вернуться с новыми силами и вдохновением.

Будьте здоровы 🍀

#life
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍1🕊1
NULL + 50: почему иногда арифметика работает не так, как ожидается

Продолжая серию статей про #null, не могу обойти стороной арифметику.

Допустим, мы хотим оценить, сколько всего товара будет на складе, и для этого складываем общий запас товаров с ожидаемыми поставками. Вот таблица с данными:

| product_id | current_stock | expected_delivery |
|------------|---------------|-------------------|
| 1 | 100 | 20 |
| 2 | 50 | NULL |
| 3 | 200 | 30 |


Выполняем запрос:

SELECT
product_id,
current_stock + expected_delivery AS total_stock
FROM inventory;


Результат выполнения будет таким:

| product_id | total_stock |
|------------|-------------|
| 1 | 120 |
| 2 | NULL |
| 3 | 230 |


Почему для второго продукта итог оказался NULL вместо 50? 🤔 Ведь логично ожидать, что результат будет равен текущим запасам.

И тут пора вспомнить то, о чём я всё время напоминаю. NULL — это не число, а специальный маркер. Он говорит "здесь что-то должно быть, но я не знаю что". И его нельзя использовать в любых арифметических операциях с числами напрямую, поскольку это "неопределенность". И когда мы просим прибавить к числу неизвестность, в результате мы также получаем неизвестность.

Что делать?
Как и всегда, важно всегда обрабатывать NULL-значения. Тут нам снова помогут функции COALESCE и IFNULL:


SELECT
product_id,
current_stock + COALESCE(expected_delivery, 0) AS total_stock
FROM inventory;


Функция COALESCE проверяет, является ли значение expected_delivery NULL, и если это так, подставляет 0. Так мы избегаем возможной ошибки, которой точно не место в наших в отчётах.

#null
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Организация мониторинга и алертинга в DWH-системах

Мониторинг и алертинг — это не просто какие-то модные слова из мира IT. Это основа, на которой держится работа с данными. Давайте разберемся, как это устроено в современных хранилищах.

В DWH хранятся важные данные компании: отчеты, аналитика, истории взаимодействий с клиентами. Некорректная загрузка и обработка этих данных может обернуться большими проблемами. Мониторинг помогает вовремя выявлять аномалии в данных и процессах, а оповещения — вовремя на них реагировать.

Основные задачи мониторинга
Первая — контроль выполнения ETL/ELT процессов. Например, если скрипты, которые должны обновлять данные ежедневно, вдруг падают или выполняются слишком долго, мониторинг должен это заметить и сообщить об ошибке дежурных инженеров, чтобы они могли оперативно вмешаться.

Простой пример: у вас есть ежедневный процесс обновления данных об отгрузках со склада, и обычно он выполняется за 15 минут. Если мониторинг фиксирует, что процесс вдруг начал занимать час, он оповещает, что что-то пошло не так. Возможно, сломалась загрузка из источника или увеличился объем данных (тоже не плохо обратить на это внимание).

Еще одна задача — контроль качества данных. Иногда сами данные могут приходить с ошибками. Представьте, что ваш ETL процесс получил пустые строки об отгрузках вместо обычного объема данных. Хорошо настроенный мониторинг заметит это и оповестит команду.

Что конкретно стоит мониторить?
1. Процессы загрузки данных: время выполнения, наличие ошибок, объемы данных.
2. Качество данных: проверки на пустые значения, аномалии, отклонения от ожидаемых значений.
3. Работа сервера: утилизация CPU, память, доступное место на диске. Особенно важно в облачных решениях, где рост нагрузки приводит к дополнительным затратам.


Оповещения должны быть точными и своевременными. Если система засыпает вас уведомлениями по каждому пустяку, вы быстро перестанете на них реагировать. В итоге важные сообщения могут пройти мимо.

Ещё один пример: если ETL процесс падает три раза подряд — это явно повод для тревоги. Алертинг должен отправить сообщение дежурным инженерам по оперативным каналам (но не засыпать этот канал оповещениями нон-стоп). Для этого удобно использовать мессенджеры вроде Slack, хуже — email уведомления.

Инструменты для мониторинга и алертинга
🟠 Prometheus + Grafana: отличный вариант для отслеживания метрик и визуализации данных. Prometheus собирает метрики, а Grafana показывает их в удобных дашбордах.
🟠 dbt Cloud: инструмент для разработки и тестирования ELT процессов, который также имеет встроенные возможности для мониторинга.
🟠 Snowflake Native Alerts: позволяет создавать алерты на основе запросов. Например, если количество записей в таблице падает ниже ожидаемого уровня, система автоматически уведомит об этом.
🟠 самописные решения 🐱

С чего начать?
Например, с базовых метрик для ETL процессов, а затем добавить проверки на качество данных. Используйте оповещения с пороговыми значениями. Например, алерт сработает, если время выполнения процесса превышает обычное более чем на 10%.

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

Используйте (или проектируйте) подходящие инструменты для мониторинга и системы оповещений, и не перегружайте свою команду лишними уведомлениями. Это сделает ваше хранилище надежным и эффективным. В конце концов, зачем нужным данные, если мы не можем положиться на их качество?

#dwh
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Сколько стоит твой SQL запрос?

Облачные хранилища — это гибкость и масштабируемость, простота и скорость работы 🤩 Но кроме этого — вечно растущие расходы. С каждым днём мы грузим всё больше данных, придумываем сложные расчёты и наши расходы растут 📈 Иногда вычислить что (и кто) тратит денежки компании особенно усердно — целое искусство.

Чтобы немного помочь с этой болью, Snowflake добавил новую системную таблицу — QUERY_ATTRIBUTION_HISTORY. Она позволяет решать целый ряд задач:
🔵cколько кредитов "съел" конкретный пользователь?
🔵во сколько обходится тот или иной пайплайн?
🔵какие запросы повторяются и сколько они стоят?

То есть она помогает обнаружить скрытые источники перерасхода. Например, простой SELECT, который запускается каждые пять минут, может стоить намного больше, чем ожидалось. Выявили проблему — сразу оптимизировали. Больше не нужно составлять сложные SQL-запросы, объединяя данные из нескольких таблиц. При этом вся информация хранится год, и доступ к ней можно получить всего за несколько строк кода.

Для вычисления самых злостных потребителей за последний месяц достаточно выполнить запрос:

SELECT user_name, SUM(credits_attributed_compute) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE 1=1
AND start_time >= DATE_TRUNC('MONTH', CURRENT_DATE)
AND start_time < CURRENT_DATE
GROUP BY user_name
ORDER BY credits desc;


Теперь можно легко настроить дашборды и ещё лучше:
— анализировать расходы
— оптимизировать задачи, которые дороже всего стоят
— создать систему уведомлений о высоких расходах.

Что стоит помнить? Не учитываются:
🔵расходы на простои виртуальных варехаузов (про них я рассказывала в одной из статей про #snowflake)
🔵serverless-функции
🔵хранение данных

Документация по QUERY_ATTRIBUTION_HISTORY здесь.

#snowflake
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Прокачиваем SQL-запросы с фишками оконных функций

Многие аналитики активно используют базовые оконные функции, но не всегда знают, как применять такие инструменты, как фрейм окна (window frame). А ведь это сделает запросы ещё более читабельными и эффективными. Давайте разбираться вместе.

Фрейм определяет набор строк для вычислений оконной функции относительно текущей строки.


В этой статье рассмотрим два способа определить, какие строки включать в окно для расчетов: ROWS и RANGE.

Начнем с ROWS BETWEEN. Эта конструкция работает с физическими строками и помогает анализировать конкретное количество записей до и после текущей строки. Чтобы стало понятнее, рассмотрим пример: мы хотим рассчитать скользящую сумму продаж за последние 3 дня, включая текущий день. Для этого подсчёта нам необходимо от каждой строки отсчитать две строки назад и суммировать значения продаж за эти дни.


| sales_date | sales_amount |
|------------|--------------|
| 2024-01-01 | 100 |
| 2024-01-02 | 150 |
| 2024-01-03 | 200 |
| 2024-01-04 | 250 |



SELECT
sales_date,
sales_amount,
SUM(sales_amount) OVER (
ORDER BY sales_date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS rolling_sum
FROM sales_daily;


Результат:

| sales_date | sales_amount | rolling_sum |
|------------|--------------|-------------|
| 2024-01-01 | 100 | 100 |
| 2024-01-02 | 150 | 250 |
| 2024-01-03 | 200 | 450 |
| 2024-01-04 | 250 | 600 |


Выражением ROWS BETWEEN 2 PRECEDING AND CURRENT ROW мы буквально говорим, что нужно от каждой строки отсчитывать две строки назад и суммировать значения продаж за эти дни (включая значение в текущей). Таким образом, каждая строка будет содержать сумму продаж за текущий день и два предыдущих. Важно! В нашей исходной витрине данные уже сгруппированы по дням, поэтому в данном случае корректно говорить Х дней назад, но по сути мы говорим про строки.

RANGE BETWEEN работает иначе. Он группирует строки по значению, а не по их физическому положению. Это бывает полезно, когда нужно учитывать все строки с определённым диапазоном значений относительно текущей строки. Не понятно? Перейдём к примеру.

Нужно рассчитать среднюю цену за последние 3 дня от каждой даты:

| price_date | stock_price |
|-------------|-------------|
| 2024-01-01 | 100 |
| 2024-01-01 | 102 |
| 2024-01-02 | 105 |
| 2024-01-04 | 103 |
| 2024-01-04 | 106 |
| 2024-01-06 | 110 |



SELECT
price_date,
stock_price,
AVG(stock_price) OVER (
ORDER BY price_date
RANGE BETWEEN INTERVAL '3' DAY PRECEDING AND CURRENT ROW
) AS avg_price_3days
FROM stock_prices;


Результат:

| price_date | stock_price | avg_price_3days |
|------------|-------------|-----------------|
| 2024-01-01 | 100 | 101.00 |
| 2024-01-01 | 102 | 101.00 |
| 2024-01-02 | 105 | 102.33 |
| 2024-01-04 | 103 | 103.20 |
| 2024-01-04 | 106 | 103.20 |
| 2024-01-06 | 110 | 106.33 |


При использовании RANGE все строки с одинаковым значением столбца, указанного в ORDER BY, обрабатываются вместе. А RANGE BETWEEN INTERVAL '3' DAY PRECEDING AND CURRENT ROW говорит о том, что нужно посчитать значения в фрейме с интервалом 3 дня до текущей строки.

Обратите внимание, что даты 2024-01-03 и 2024-01-05 отсутствуют в таблице. Когда мы используем указанный RANGE BETWEEN, SQL ищет все строки, где price_date находится в диапазоне от текущей даты минус календарных 3 дня, то есть учитывает только имеющиеся даты в этом диапазоне.

Поняли разницу? RANGE учитывает все записи в указанном временном интервале, даже если их много. А ROWS всегда отсчитывает фиксированное количество строк.

Естественно обе функции можно использовать не только при расчётах связанными с датами. Давайте в одной из следующих статей рассмотрим другие примеры. Фреймы кажутся той темой, которой стоит уделить особое внимание.

#sql
👍4
Обожаю Snowflake за множество классных функций, делающих sql-код более читабельным. При этом специально "переучиваться" для работы в снежке не нужно, так как он поддерживает всем знакомый (ну я надеюсь) стандарт ANSI SQL. Просто каждый раз в работе (или листая документацию) ты находишь прикольные фишки, которые хочется использовать.

Например, как бы вы посчитали, сколько задач разработчиков завершено до дедлайна, а сколько — нет? Обычно пришлось бы писать что-то вроде:

SELECT
developer,
SUM(CASE WHEN completion_date <= deadline THEN 1 ELSE 0 END) AS on_time_tasks,
SUM(CASE WHEN completion_date > deadline THEN 1 ELSE 0 END) AS late_tasks
FROM tasks
GROUP BY developer;


В Snowflake этот подсчёт выглядит куда лаконичнее:

SELECT
developer,
COUNT_IF(completion_date <= deadline) AS on_time_tasks,
COUNT_IF(completion_date > deadline) AS late_tasks
FROM tasks
GROUP BY developer;


Кажется, что это незначительная мелочь? Но насколько приятнее и понятнее становится разбирать тысячи строк какого-нибудь сложного аналитического запроса. Краткость — сила!

#snowflake #sql
👍2🔥1
Полезные привычки для продуктивности

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

Что помогает лично мне?
🟢 систематизация — в душé где-то очень глубоко я человек-система и мне важно разложить дела по полочкам, поэтому активно веду календарь, заметки и прочее. Большие вещи всегда декомпозирую на маленькие и простые ("есть слона по частям" набило оскомину, но это реально упрощает жизнь).
🟢 не нужно стараться успеть всё, это не продуктивно и не дальновидно. Умение расставлять приоритеты и отсеивать зёрна от плевел — важнейший навык. Если задача не требует срочного решения, она идёт в бэклог. А ещё учимся говорить "нет" там, где это необходимо.
🟢 удобное рабочее место (настроенная под себя IDE и горячие клавиши — тоже про это). Всё нужное должно быть под рукой и перед глазами (несколько экранов — ван лав даже для системного аналитика). Рутина не должна отнимать много времени! Чем неудобнее пространство вокруг нас, тем больше шансов сместить фокус внимания и "зависнуть".
🟢 автоматизируем всё, что возможно. Пишем небольшие скриптики, облегчающие рутину, используем gpt, там где это приемлимо (например, вам надо составить ddl-код для данных, получаемых с какого-нибудь открытого api — просто скормите json-ответ и доку gpt, к чёрту копирования)
🟢 используем технику Pomodoro, о которой я уже писала здесь.

Что советуют ещё:
🟡крепкий качественный сон — моя мечта последние 5 лет 😅 высыпаться реально помогает;
🟡планирование задач на день — стараюсь практиковать, но пока чаще получается, что держу всё в голове, тут есть над чем работать;
🟡мелкие-быстрые задачи решать сразу же, не держа их в голове, забивая память. Просто берём и делаем. Я же люблю порой попрокрастинировать и пооткладывать скучное-быстрое на "потом успею".

Конечно, не избежать дней, когда десятки задач летят в нас одновременно, а все результаты нужны были ещё вчера. Но если мы возьмём в привычку не тратить лишнюю энергию и время на мелочи, работа станет проще, да и менталочка будет здоровее.

А что помогает вам?

#soft_skills
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
NULL_COUNT и NULL_PERCENT для мониторинга качества данных в Snowflake

Я уже много раз упоминала, что от данных в DWH не будет никакого смысла, если мы не сможем им доверять. Что нужно для доверия? Регулярный мониторинг за качеством данных. Data quality должно пронизывать все этапы жизни данных в хранилище. И об этом говорить мы будем ещё очень много. Но сегодня я хочу рассказать о классных плюшках в Snowflake, которые чуть упрощают нам некоторые проверки.

В Snowflake есть много встроенных встроенных метрик помогающих отслеживать качество данных. И функция SYSTEM$DATA_METRIC_SCAN как раз одна из них. Она упрощает получение метрик качества данных без необходимости писать сложные запросы.

Например, функция NULL_COUNT возвращает строки в таблице, которые содержат значение NULL в определенном столбце. А NULL_PERCENT помогает посчитать % NULL-значений от общего количества строк. Почему не использовать выборку по условию WHERE column_name is NULL? В рамках разовых точечных расчётов, использование этих встроенных метрик не даёт заметного прироста производительности. А вот вывести несколько метрик разом по одной таблице или одним запросом по нескольким быстрее-проще, используя функции.

Какие метрики можно посмотреть в рамках SYSTEM$DATA_METRIC_SCAN?
🟢 NULL_COUNT — количество NULL-значений в поле
🟢 NULL_PERCENT — % NULL-значений от общего количества строк
🟢 BLANK_COUNT — количество пустых строк (для текстовых полей)
🟢 BLANK_PERCENT — % пустых строк от общего количества строк
🟢 DUPLICATE_COUNT — количество дублей поля (не целиком строки)

Рассмотрим пример. Есть таблица с данными о заказах, куда через ELT-процесс регулярно льются свежие данные:

CREATE TABLE orders (
order_id NUMBER,
customer_id NUMBER,
product_id NUMBER,
order_date DATE,
delivery_date DATE,
amount NUMBER,
promo_code STRING
);

-- Для нашего примера заполним её тестовыми данными:
INSERT INTO orders VALUES
(1, 100, 500, '2024-01-01', '2024-01-03', 1500, NULL),
(2, 101, 501, '2024-01-01', NULL, 2000, 'WINTER24'),
(3, 102, 502, '2024-01-02', '2024-01-04', 1800, ''),
(4, NULL, 501, '2024-01-02', NULL, 2000, NULL);

-- Посчитаем какой % NULL-значений в поле customer_id и % пустых строк в promo_code
SELECT
SNOWFLAKE.CORE.NULL_PERCENT(SELECT customer_id
FROM orders) as null_percent_customer_id,
SNOWFLAKE.CORE.BLANK_PERCENT(SELECT promo_code
FROM orders) as blank_percent_promo_cd;

--Выведем все строки с BLANK-значениями в поле promo_code
SELECT *
FROM TABLE(SYSTEM$DATA_METRIC_SCAN(
REF_ENTITY_NAME => 'orders',
METRIC_NAME => 'snowflake.core.blank_count',
ARGUMENT_NAME => 'promo_code'
));


Результат первого запроса покажет:

| null_percent_customer_id | blank_percent_promo_cd |
|--------------------------|------------------------|
| 25 | 33,33 |


А второй выведет строки таблицы с promo_code = '' целиком.

Как всё это применять?
🔘определение пороговых значений для NULL и BLANK в критичных колонках
🔘настройка регулярного мониторинга
🔘создание алертов на основе результатов проверок

Использование этой функции (с умом) позволяет нам быстро и просто находить аномалии в данных и реагировать на проблемы до того, как они повлияют на бизнес-процессы. Но даже если вы не используете Snowflake, не забывайте строить метрики качества другими методами.

#snowflake #data_quality
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥42
Не ошибается тот, кто ничего не делает?

Начинала писать этот пост с мыслями о косяках подрядчиков, делающих ремонт в новой квартире, а заканчиваю после утренних попадавших dq-проверок, последствий моих ошибок 🥲

У тех, кто только вкатывается в профессию, порой существует ошибочное представление, что люди с высокими грейдами не ошибаются. Но ошибаться нормально каждому — в конце концов, мы не запрограммированные роботы (да и те не застрахованы от ошибок, ведь их создавали такие же люди 😉).

На мой взгляд, об уровне специалиста говорит не факт наличия или отсутствия ошибок (хотя после утренних алертов я вновь засомневалась на свой счёт 😆). Куда важнее реакция после.

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

Увы, я сталкиваюсь с подобным и в IT. Вместо того, чтобы признать ошибку и сразу её исправить, люди ищут виноватых, придумывают оправдания или перекладывают ответственность. И это, пожалуй, раздражает больше всего.

На мой взгляд, профессионализм начинается там, где ты можешь сказать: «Да, я накосячил. Вот что произошло, и вот что я уже делаю, чтобы это исправить и как стать лучше». Ведь каждая ошибка — наш урок из которого можно вынести что-то полезное. А главное — это наш опыт.

Ошибаться не стыдно, стыдно делать вид, что виноват не ты, а кто-то другой.

#soft_skills
Please open Telegram to view this post
VIEW IN TELEGRAM
👍65💯1
Материализованные представления: ускоряем аналитику

Материализованные представления (Materialized Views, MV, матвью) — способ ускорить выполнение аналитических запросов за счет предварительного вычисления и сохранения данных.


Чтобы понять матвью, давайте вернёмся на шаг назад и вспомним, что такое вью (view, V, представление). Представление — это виртуальные таблицы, которые хранят текст SQL-запроса и запускаются на лету. Они не сохраняют сами данные (в некоторых бд могут кешироваться в рамках сеанса до изменения источников).

Основное отличие MV от V как раз в том, что оно физически хранит результаты вычислений и позволяет использовать их повторно, вместо того чтобы пересчитывать данные каждый раз.

Пример: есть таблица с данными о продажах, которые обновляются раз в сутки. Аналитики несколько раз в день строят отчёты с расчётом суммарного дохода по регионам и категориям товаров. Создание MV позволяет агрегировать данные раз в сутки сразу после обновления источников. Это ускоряет построение отчетов и снижает нагрузку на базу данных.

Рассмотрим пример создания MV для Snowflake:

CREATE MATERIALIZED VIEW sales_summary_mv AS
SELECT
region,
category,
SUM(revenue) AS total_revenue,
COUNT(*) AS transaction_count
FROM sales
GROUP BY region, category;


Как происходит синхронизация данных?
Чаще всего MV автоматически обновляются при изменении исходных данных. Однако частота и способ обновления зависят от СУБД:
— Snowflake: обновляются инкрементально, снижая нагрузку на хранилище.
— PostgreSQL: обновление требует явного выполнения команды REFRESH MATERIALIZED VIEW, что добавляет ручной работы.
— Oracle: поддерживаются как полные, так и инкрементальные обновления в зависимости от настроек.
— Microsoft SQL Server: MV называются индексированными представлениями и обновляются автоматически, но с ограничениями на типы запросов.

Когда использовать MV
🟢 один и тот же сложный запрос выполняется многократно на большом объёме данных;
🟢 исходные данные обновляются редко, а аналитика выполняется часто;
🟢 нужен быстрый доступ к данным с минимальной задержкой;
🟢 есть достаточно места для хранения данных.

Когда не стоит использовать MV
🟣 запросы редкие или исследовательские (ad hoc) — тогда затраты перевешивают выгоду;
🟣 ограничено место для хранения (ведь данные сохраняются физически);
🟣 данные обновляются слишком часто — материализованные представления необходимо часто обновлять, что может привести к дополнительным накладным расходам (актуально не для всех систем);
🟣 запросы содержат конструкции, не поддерживаемые MV (зависит от БД).

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

#dwh
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1🔥1
Как открытые вопросы помогают понимать бизнес

Работа системного аналитика всегда начинается с общения с бизнес-заказчиками, которые приходят с самыми разными требованиями: от настройки дашбордов до расчёта новых метрик. Чтобы разговор получился действительно полезным и заказчик смог поделиться всей нужной информацией, важно задавать открытые вопросы.

Открытый вопрос — это такой вопрос, на который нельзя ответить "да" или "нет". Он подразумевает развернутый ответ и побуждает собеседника делиться деталями.


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

Звучит просто, но давайте разберём на примерах.

— Какие данные вы хотите анализировать?
Часто заказчики начинают с обобщений, например, "Нам нужны все данные". Чтобы понять что же именно от нас хотят, можем спросить:
– Какие процессы или метрики для вас наиболее важны?
– Какие системы предоставляют данные для этих метрик?
– Есть ли данные, которые уже не актуальны или которыми не пользуются?

— В каком разрезе нужны данные?
Чтобы данные действительно помогали бизнесу, нужно понимать, в каких разрезах их нужно подавать:
– Какие временные рамки вас интересуют (дни, недели, месяцы)?
– Какие параметры важны (регионы, продукты, каналы продаж)?
– Есть ли специфические сегменты, которые требуют особого внимания?

Пример:
Плохо: "Нужно ли делить данные по времени?"
Хорошо: "Какой временной разрез наиболее полезен для ваших целей?"

— Как вы хотите использовать эти данные?
Чтобы понять цель запроса, можно обсудить ключевые моменты:
– Какие отчёты вы хотите получить?
– Какие решения вы планируете принимать на их основе?
– Можете ли вы показать примеры отчётов, которые сейчас вас не устраивают и чем?

— Какие есть ограничения?
Здесь можем уточнить моменты, которые помогут понять возможные ограничения или сложности:
– Есть ли ограничения по срокам?
– С какой периодичностью нужно обновлять данные, чтобы они оставались актуальными для отчетов? Какие процессы требуют более частого обновления, а для каких можно использовать данные с задержкой?
– Какие бизнес-процессы зависят от этих данных?

— Что делать, если данные противоречат друг другу?
Работая с хранилищем, аналитики часто сталкиваются с конфликтами в данных. Можем спросить:
– Как определять достоверность данных?
– Кто принимает решение при возникновении противоречий?

Пример:
Плохо: "Данные из разных источников не совпадают?"
Хорошо: "Бывали ли случаи, когда данные из систем не совпадали? Как определяется источник правды?"

— Как могут измениться требования в будущем?
Требования к данным меняются со временем. Не всё очевидно заранее, но открытые вопросы помогут заранее предусмотреть будущие доработки:
– Планируете ли вы подключать новые источники данных?
– Какие дополнительные метрики могут понадобиться?

Как задавать открытые вопросы?
Чтобы вопросы работали, следуйте нескольким правилам:
*️⃣ Начинайте с "Почему?", "Как?", "Что?", "Какие?", ...
*️⃣ Избегайте формулировок, которые допускают ответ "да" или "нет".
*️⃣ Стройте вопросы так, чтобы они побуждали к диалогу. Дайте собеседнику возможность пообщаться и поделиться деталями. Это будет полезно и для нас, и для него. Ведь разговор предполагает дополнительное размышление.

Открытые вопросы — это инструмент, который помогает не только уточнить требования заказчика, но и наладить продуктивное взаимодействие. Важно не просто сделать крутое хранилище (которым никто не пользуется), но и отвечающее ожиданиям пользователей. Чем больше информации мы соберём на начальном этапе общения, тем меньше доработок понадобится в будущем.

#soft_skills
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍1
ETL и ELT: разбираемся вместе

Больше года назад я писала короткую заметку что такое ETL-процессы, но до подробного разбора руки так и не дошли.

Тем временем Вова Никулин, автор канала Lost in Data классно раскрыл эту тему со стороны дата-инженера. Вот его пост про основы ETL: тык. В нём простое объяснение как работает ETL и как реализовать его с помощью Python и SQL. Мега полезно, если вы только начинаете погружаться в тему.

А в свежем посте он развивает тему, объясняя разницу между ETL и ELT и их связь с Data Lake. Ещё вы узнаете, что такое Data LakeHouse, как гибридный подход меняет работу с данными и о том, почему в современном мире разница между ETL и ELT постепенно размывается (спойлер: всё также мы говорим ETL, хотя по факту давно перешли на ELT и EtLT).

Рекомендую канал Lost in Data, если вы хотите развиваться в области хранилищ данных, аналитики или автоматизации 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🔥2
Недавно столкнулась с хейтом к этому посту. Комментатор возмущался, что "понаберут с улицы" и "как вообще может быть связаны ТЗ и sql". Вот что случается, когда смотришь на мир слишком узко и сталкиваешься с вещами вне своей специфики.

Связь, на самом деле, очевидна, если понимать, как работают процессы в хранилище данных. ТЗ описывает не только саму задачу, но и контекст: что именно нужно сделать, с какими ограничениями и какие бизнес-требования лежат в основе (т.е. зачем вообще мы это делаем, согласитесь – важное понимание). SQL, в свою очередь, — это лишь один из возможных инструментов реализации описанного в ТЗ.

Безусловно, есть компании и команды, где просто физически нет возможности (а порой и необходимости, если всё делает 1 человек) писать ТЗ. Но у нас в хранилище этот процесс работает чётко: крупные задачи передаются от системных аналитиков дата-инженерам именно через ТЗ. Мы продумываем решение, экспериментируем, описываем его и только потом передаём на реализацию.
Речь не о каких-то мелких правках, а о чём-то более масштабном. Например, о загрузке данных с новых источников новым методом (у нас дата-инженеры занимаются только разработкой, без исследования самих данных) или доработке текущих и разработке новых фреймворков.

К примеру, при подключении нового API-источника системный аналтик сначала анализирует, как меняются данные со временем, какие поля обязательны, какими методами забирать те или иные сущности, какие ограничения накладывает сам API, и где могут возникнуть потенциальные проблемы. После этого он описывает метод загрузки сущностей в виде ТЗ и передёт его (после ревью, конечно) дата-инженерам, которые уже занимаются разработкой технической части: настройкой пайплайнов, написанием ETL-скриптов, внедрением методов обработки и трансформации. Т.е. реализацией.

И вот здесь я вижу огромную ценность доступной и поддерживаемой документации. Говорю это, исходя из своего опыта. Сейчас мне приходится работать с горой незадокументированного легаси, которое создавалось годами в условиях ограниченных ресурсов, правилось ASAP-требованиями и чаще всего не имеет описаний ни в коде, ни документации. Даже скромное ТЗ на этапе разработки, могло бы помочь понять, какие изменения вносились и зачем. Теперь же приходится тратить время (очень много времени) на разбор неочевидных решений.

Моё имхо: без документации слишком много зависит от устных договорённостей. Это не отслеживаемо, не поддерживаемо и не безопасно — т.е. огромный риск, особенно если кто-то из ключевых сотрудников покинет проект.

А как у вас? Есть ли в вашей компании практика написания ТЗ или всё держится на неформальных договорённостях и тасках в jira?

#документация
🔥6👍2
Happy New Year 🎄

В 2025 хочется пожелать каждому думать больше о себе, а не о чужом «успешном успехе». Сравнивать себя только с собой вчерашним и расти относительно себя. И, конечно, берегите здоровье. Это ваше лучшее вложение и актив.

Пусть 2025 год будет интересным и добрым 🥳 остальное приложится, если захотите 👍
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍8🔥5🤗1
Всем привет!

Хочу начать этот год с поста-знакомства 🐾

Я Юля Иванова – системный аналитик DWH из Сибири (слава удалёнке).

По образованию я спец по ИБ, но работала по профессии совсем недолго. Затем на какое-то грустное время выпадала из IT, но от судьбы не уйдёшь и я вернулась. Поработала на разных ролях от PM до QA, но вот уже третий год как обосновалась в работе с данными и это по большой любви. Ещё тысячу лет назад во времена универа самыми любимыми предметами были вышка и СУБД. А теперь я с командой строю DWH для международного холдинга.

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

Пишу о том, с чем сталкиваюсь в работе, и стараюсь объяснять максимально понятно. Вероятно, вы не найдёте здесь уникальных знаний, но надеюсь мои заметки окажутся полезными. Когда-то я сама начинала путь на чужих статьях, и теперь стараюсь отдавать сообществу то, что получила. Не менее важен и принцип: "Объясняя другим — расту сам". Ну и тяга к писательству так сильна, что просто невозможно не писать и не делиться 😍

Помимо данных люблю путешествия и фотографию, увлекаюсь генеалогией (тоже своего рода работа с данными) и знаю своих предков до 17-18 веков.

Спасибо, что остаётесь со мной 🤗 Давайте расти вместе.
Please open Telegram to view this post
VIEW IN TELEGRAM
18🔥8👍1👌1🤡11
Системный аналитик DWH — кто ты?

Интернет заполнен рекламой курсов по дата инженерии и мы уже более-менее разобрались кто эти ребята и чем занимаются. С дата аналитикой, кажется, тоже плюс минус всё понятно. Но кто такие системные аналитики DWH (SA DWH), зачем они нужны и можно ли обойтись без них?

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

В России исторически закрепилась вертикальная структура компаний, где каждый отдел имеет «ответственное лицо» за свою область. Так у хранилищ данных и появились «системные аналитики DWH», которые:
🔵 согласовывают требования с бизнесом
🔵 расписывают модели данных
🔵 передают задачи дата-инженерам.

По сути, системный аналитик — входная точка в хранилище данных. Да, во многих зарубежных компаниях выделенных SA DWH нет: эти обязанности совмещают Data Warehouse Architect, Data Solutions Analyst, Technical Data Analyst, Analytics Engineer (поговаривают, что эта роль потихоньку уходит в прошлое, но это не точно), ETL или Data Engineer. Однако в российских реалиях системные аналитики DWH — это связующее звено между бизнесом и техническим миром. Правда, иногда их тоже называют дата-инжеренами, выделяя в отдельное направление (как, например, в одном жёлтом банке).

Чем же занимается SA DWH?

Все мы понимаем, что всё меняется от компании к компании, но примерно так:
🔵 общается с бизнесом и командами разработки, собирает требования к данным
(то есть координирует взаимодействие и выступает «переводчиком» между бизнесом, DevOps, ETL, BI и другими участниками дата-процессов).
🔵 проектирует схему хранилища: создает и документирует структуру таблиц, представлений, витрин (включая CDC, STG, ODS, EMART и другие «слои» DWH).
🔵 разрабатывает концепцию обработки данных: какие пайплайны нужны, как реализовать CDC и репликацию, и т.д.
🔵 ведёт анализ данных (и копается в куче legacy 🥲)
🔵 продумывает качество данных (иногда в составе отдельного подразделения по качеству, если позволяет масштаб компании)
🔵 создает стратегии по работе с историческими данными (сколько хранить, как обновлять, как архивировать)
🔵 планирует развитие DWH: какие таблицы добавить, какие поля стоит убрать, как обогатить данные, ...
🔵 проектирует витрины и описывает требования к ETL-процессам, чтобы дата-инженеры могли чётко реализовывать логику загрузки
🔵 разбирается с интеграцией легаси-систем (нередко это самый сложный блок).
🔵 ...

На самом деле список задач SA может сильно отличаться от команды к команде. Например, в идеальной ситуации есть выделенный DWH-архитектор, который строит целостную архитектуру и отвечает за масштабирование. Но если в компании такой роли нет, эти обязанности часто берёт на себя системный аналитик.

Для меня работа SA всегда где-то на грани творчества, экспертизы и здравого смысла. В этом и вся прелесть профессии.

Позже расскажу какими инструментами мы пользуемся в своей работе.

А что ближе вам — техническая внутрянка или работа с бизнес-контекстом и логикой?

#системный_анализ
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93
GROUPING SETS для упрощения агрегации

Мы группируем данные десятки раз в день: по датам, категориям, клиентам или нескольким полям сразу. Но что, если нужно получить несколько уровней агрегации в одном результате? Объединять три разных запроса через UNION ALL? Писать вложенные подзапросы? Такой сценарий превращает простую задачу в головоломку с кучей повторяющегося кода 🔄

Теперь представьте: один запрос возвращает и детализацию, и промежуточные итоги, и общую сумму. И всё это без дублирования логики и потери производительности. Это не магия — это GROUP BY GROUPING SETS. Спойлер: после него вы вряд ли захотите возвращаться к старому подходу.

Синтаксис:

SELECT column1, column2, AGG_FUNC(column3) AS aggregate_result
FROM table_name
GROUP BY GROUPING SETS
(
(column1),
(column2),
(column1, column2),
() -- итоговая строка для всех данных
);


Итак, у нас есть таблица с заказами, и нужно вывести витрину продаж: по дням, категориям, дням и категориям, а также общие продажи.


| order_id | order_dt | category | price |
|----------|------------|-------------|-------|
| 1 | 2025-02-01 | Книги | 100 |
| 2 | 2025-02-01 | Книги | 200 |
| 3 | 2025-02-01 | Электроника | 700 |
| 4 | 2025-02-02 | Книги | 150 |
| 5 | 2025-02-02 | Электроника | 250 |
| 6 | 2025-02-02 | Электроника | 550 |


Запрос:

SELECT
order_dt,
category,
SUM(price) AS total_sum
FROM orders
GROUP BY GROUPING SETS
(
(order_dt, category), -- Группировка по дням и категориям
(order_dt), -- по дням
(category), -- по категориям
() -- Итоговая строка
);


Результат:

| order_dt | category | total_sum |
|------------|-------------|-----------|
| 2024-01-01 | Книги | 300 |
| 2024-01-01 | Электроника | 700 |
| 2024-01-02 | Книги | 150 |
| 2024-01-02 | Электроника | 800 |
| 2024-01-01 | NULL | 1000 |
| 2024-01-02 | NULL | 950 |
| NULL | NULL | 1950 |
| NULL | Книги | 450 |
| NULL | Электроника | 1500 |


🔵Полные строки (order_dt и category заполнены) — детализированные данные.
🔵Строки с order_dt и NULL показывают суммы по каждому дню.
🔵Строки с category и NULL показывают суммы по каждой категории.
🔵Строка с двумя NULL — общая сумма.

Если нужно определить, какие строки являются результатом группировки, используйте функцию GROUPING(). Она возвращает 1 там, где значение агрегировано.

Пример:

SELECT
order_dt,
category,
SUM(price) AS total_sales,
GROUPING(order_dt) AS is_dt_agg,
GROUPING(category) AS is_cat_agg
FROM orders
GROUP BY GROUPING SETS
(
(order_dt), -- Группировка по дням
(category), -- Группировка по категориям
() -- Итоговая строка
);

| order_dt | category | total_sales | is_dt_agg | is_cat_agg |
|------------|------------|-------------|-----------|------------|
| 2024-01-01 | NULL | 1000 | 0 | 1 |
| 2024-01-02 | NULL | 950 | 0 | 1 |
| NULL | NULL | 1950 | 1 | 1 |
| NULL | Книги | 450 | 1 | 0 |
| NULL | Электроника| 1500 | 1 | 0 |


Почему GROUPING SETS лучше UNION ALL?
один запрос вместо нескольких
оптимизация выполнения — СУБД сканирует таблицу один раз и для каждой строки вычисляет все группировки параллельно
читабельность кода

поддерживаются не все диалекты SQL (но основные — PostgreSQL, Oracle, SQL Server, Snowflake, BigQuery — да)

GROUP BY GROUPING SETS полезен для отчетности и аналитических анализов, где нужны сводные данные разной детализации. Это инструмент работает:
🟢 удобно: меньше кода, меньше ошибок
🟢 быстро: один проход по данным
🟢 гибко: возможны любые комбинации группировок

#sql
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3
Привет 👋 Живя за тысячи километров от «цивилизации», не хватает нетворкинга и свежего взгляда на дата-мир. Посты, подкасты, видео — всё это хорошо, но хочется живого общения.

Хочется узнать больше о вас, мои читатели. Расскажите о себе и вашем опыте. Как у вас строятся дата-пайплайны? С какими сложностями сталкиваетесь? Или, может, вы только начинаете свой путь в мире данных?

Моя текущая боль — интеграция с 1С, данные из которой падают в кафку в куче всяческих вариаций структур. И надо всё разложить по красоте, ничего не потеряв по пути и обложив проверками. Бесконечная вложенность объектов, непредсказуемые структуры, русские наименования сущностей... в общем, то ещё извращение 😏 А в жире уже ждет следующая пачка 1С на интеграцию. Вы как, дружите с 1С?) Делитесь опытом!
Please open Telegram to view this post
VIEW IN TELEGRAM
6💔1
SQL под капотом: как выполняются запросы

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

1. Query Parsing (разбор запроса)
Сначала сервер проверяет, правильно ли написан запрос. Проводит так называемый синтаксический анализ. Ошиблись в запятой или перепутали порядок ключевых слов? Получите ошибку.

После синтаксического анализа начинается семантический разбор: существуют ли таблицы и колонки, есть ли у вас права на запрос? Если все ок, база строит parse tree.

Parse Tree — это иерархическое представление запроса, где каждый узел — отдельная операция (например, фильтр, join, сортировка). Это облегчает работу оптимизатора и позволяет строить разные планы выполнения.

2. Query Optimization (оптимизация запроса)
На этом этапе в работу вступает умный планировщик. Он оценивает различные стратегии выполнения запроса, чтобы определить наиболее эффективную и менее ресурсоёмкую. Оптимизаторы сильно отличаются от СУБД к СУБД, но, к примеру, в Snowflake он, действительно, умный и даже плохо написанный запрос в большинстве случаев "переписывает" оптимально самостоятельно (это, конечно, не значит что стоит писать запросы как попало 👿).

Оптимизатор, в зависимости от СУБД может проверять:
Как соединять таблицы — Nested Loop, Hash Join, Merge Join?
Как фильтровать и сортировать данные?
Использовать индексы или нет?

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

3. Query Execution (выполнение запроса)
После этого база данных начинает пошагово выполнять запрос, согласно выбранному плану.

Запросы могут выполняться через:
🔵 Table Scan — полный перебор строк в таблице (долго).
🔵 Index Seek — точечный поиск через индекс (быстро, но требует индекса).

4. Извлечение или изменение данных
Если наш запрос извлекает данные (SELECT - Data Query Language), база выбирает нужные строки из таблиц и формирует результат. Если же запрос изменяет данные (INSERT, MERGE, UPDATE или DELETE - Data Manipulation Language), информация в таблице обновляется, удаляется или дополняется.

5. Формирование результата
Когда SQL-движок собрал нужные строки, он финально формирует итоговый результат: сортирует, группирует, выполняет агрегатные вычисления. Однако часть агрегаций, особенно в запросах с GROUP BY, может выполняться еще на этапе извлечения данных, если движок решит, что это эффективнее. То есть это зависит от плана выполнения запроса и используемого метода обработки.

6. Результат
Когда всё готово, результат возвращается в клиентское приложение, которое уже отображает его пользователю.

Для SELECT-запросов, если данных много, они передаются частями, чтобы не перегружать память.
Некоторые базы поддерживают Lazy Execution — строки выгружаются только при необходимости.


Как видите, написанный запрос запускает целые механизмы внутри СУБД. Каждый этап играет свою роль: разбор проверяет синтаксис на ошибки, оптимизатор выбирает самый быстрый путь, выполнение шаг за шагом приводит к нужному результату, а передача данных гарантирует, что вы получите ответ в удобной форме, ничего не потеряв.

Не всегда имеет смысл знать, что происходит под капотом, но хотя бы верхнеуровневое понимание помогает нам самим работать эффективнее. Если что-то идет не так, вы будете знать, где искать проблему и как ее решить. Понимание происходящего — ключ к написанию быстрых и оптимизированных запросов.

#sql
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👎21🤡1