Data Driven / Bogdan Ivanov
892 subscribers
68 photos
47 videos
2 files
53 links
Данные, карьера, саморазвитие

https://datadrivenbogdan.com/

Помогаю вырасти в работе с данными и зарабатывать больше.
За менторством и сотрудничеством — @b_ivanov_kz
Download Telegram
Greenplum: от архитектуры к правильному проектированию таблиц (ч. 1)

Greenplum — MPP-база (в посте выше рассматривали, что это такое и зачем, а также рассмотрели архитектуру GP) , где данные распределяются по сегментам и обрабатываются параллельно.

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

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

*️⃣Дистрибуции — распределения данных по сегментам
*️⃣Партиционирование — деления данных внутри сегмента,
*️⃣Оптимальных типов таблицы и параметров хранения/сжатия.

⚙️ Дистрибуция

Дистрибуция — это метод, по которому данные распределяются между сегментами в GP.
Цель — чтобы объём данных на каждом сегменте был примерно одинаковым.

Если распределение неравномерное (data skew), один сегмент будет обрабатывать больше строк и замедлит выполнение всего запроса.

Основные типы:

HASH (DISTRIBUTED BY ()) — равномерно распределяет данные по ключу (например, client_id) или связке ключей. Это наиболее предпочтительный и при этом автоматический способ дистрибуции: если явно не задать ключ распределения при создании таблицы, Greenplum по умолчанию использует первый столбец таблицы в качестве ключа дистрибуции.

Хэш-дистрибуция позволяет:

*️⃣получить максимальную выгоду при JOIN таблиц без избыточного хранения данных;
*️⃣обеспечить равномерное распределение строк между сегментами;
*️⃣минимизировать перераспределение при запросах.

Используется чаще всего для таблиц фактов и больших объёмов данных.

RANDOMLY (DISTRIBUTED RANDOMLY) — тип распределения, при котором Greenplum сам распределяет строки по сегментам.
Подходит для небольших таблиц или временных данных, когда ключ дистрибуции неочевиден.

Особенности:
*️⃣равномерное распределение по сегментам;
*️⃣теряется выгода при соединениях (JOIN) — система выполняет Redistribute/Broadcast Motion;
*️⃣исключает перекосы данных.

REPLICATED (DISTRIBUTED REPLICATED) — копия таблицы на каждом сегменте.
Отлично подходит для маленьких справочников, но дублирует объём данных.

Особенности:

*️⃣JOIN выполняются максимально быстро, без движения строк между сегментами;
*️⃣удобно для маленьких справочников (dimensions).
*️⃣ главный недостаток - дублирование данных на всех сегментах

💡 Рекомендации по дистрибуции:

1. Явно задавай DISTRIBUTED BY — даже для временных таблиц.
Иначе по умолчанию система возьмёт первый столбец, который вероятно приведет к skew

2. Если нет хорошего ключа — выбирай RANDOMLY.
Также выбирай рандом для финальной таблицы, которая не будет участвовать в join в дальнейшем

3. Не используй для дистрибуции поле часто встречающееся в WHERE.
Иначе при запросах данные будут перераспределяться по сегментам → падение производительности.

4. Избегай типов date и datetime + выбирай integer вместо string для дистрибуции.
Для первых хэш вычисляется долго + для str аналогично

5. Лучший ключ дистрибуции — тот, что участвует в JOIN ON.
Это минимизирует motion и делает запросы стабильнее.

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Greenplum: от архитектуры к правильному проектированию таблиц (ч. 2)

🧱 Партиционирование

Партиционирование — это разделение таблицы на логические части (партиции) внутри каждого сегмента по определённому признаку (чаще всего — по дате). Такое деление позволяет ускорить запросы, снизить нагрузку на диск и упростить администрирование данных.

Зачем нужно партиционирование

*️⃣Ускоряет аналитику — при фильтрации по WHERE Greenplum читает только нужные партиции, а не всю таблицу.
*️⃣Снижает нагрузку на сегменты — не происходит полного сканирования таблицы, читаются только нужные диапазоны.
*️⃣Упрощает сопровождение — можно быстро удалить или архивировать старые данные, не трогая актуальные.
*️⃣Изолирует данные по периодам — удобно для построения витрин с логикой «по месяцам» или «по кварталам».

Принцип и пример:
При указании фильтра WHERE Greenplum читает только нужные партиции, а не всю таблицу.

SELECT *
FROM dm.xyz
WHERE datetime BETWEEN '2025-04-01' AND '2025-06-30';

Если таблица партиционирована по datetime, будет прочитан только 2 квартал, а не весь объём.
Это значительно снижает время выполнения запроса, особенно при миллионах строк данных.

🧩 Как пользоваться партициями:

Узнать ключи партиционирования:

SELECT *
FROM pg_catalog.pg_partition_columns
WHERE schemaname = 'dm'
AND tablename = 'xyz';


Проверить, что запрос использует нужную партицию - через EXPLAIN перед запросом:
EXPLAIN
SELECT *
FROM dm.xyz
WHERE datetime BETWEEN '2025-04-01' AND '2025-06-30';

Если всё корректно, в плане запроса будет видно, что используется только выбранный диапазон партиций.

Добавить или удалить партицию:
ALTER TABLE dm.xyz ADD PARTITION p202507 START ('2025-07-01') END ('2025-08-01');
ALTER TABLE dm.xyz DROP PARTITION p202301;

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

💡 Советы по проектированию партиций:

1. Партиционируй таблицы фактов — это основной кандидат для деления по дате.

2. Не делай слишком мелкие партиции (например, по дням) — это создаёт избыточные метаданные и замедляет DDL-операции.

3. Оптимальный уровень — по месяцам или кварталам.

4. Используй фильтры в WHERE по ключу партиционирования — иначе Greenplum не сможет исключить ненужные партиции.

5. Для небольших справочников (dictionary tables) партиционирование избыточно — оно не ускорит запросы, но усложнит структуру.

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Greenplum: от архитектуры к правильному проектированию таблиц (ч. 3)

🧩 Типы таблиц в Greenplum


1. Heap (row storage)
Это классический тип таблиц, унаследованный от PostgreSQL.
Данные хранятся построчно — каждая запись (row) хранится целиком, что делает работу с отдельными строками быстрой, но аналитические запросы медленнее.

Используется для:

*️⃣небольших таблиц (до ~300 тыс. строк или до ~100 MB);
*️⃣таблиц, где часто происходят операции UPDATE, DELETE, INSERT;
*️⃣задач с OLTP-нагрузкой (операционные системы, логирование, промежуточные буферы).

2. Append-Optimized (AO)
AO — это оптимизированный под аналитику формат хранения, доступный только в Greenplum.
Такие таблицы предназначены для OLAP-нагрузки, где данные в основном читаются, а не обновляются.

AO-таблицы позволяют:
*️⃣экономить место за счёт сжатия (compresstype и compresslevel);
*️⃣ускорять аналитические запросы, т.к. считываются только нужные колонки (orientation = column);
*️⃣эффективно работать с батчевыми вставками (INSERT пакетами).

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

CREATE TABLE schema.table_name
WITH (
appendonly = true, -- таблица только для добавления (без UPDATE/DELETE)
orientation = column, -- колоночное хранение (эффективно для аналитики)
compresstype = zstd, -- алгоритм сжатия Zstandard
compresslevel = 4, -- уровень сжатия (оптимальный баланс скорость/размер)
blocksize = 32768 -- размер блока в байтах (кратно 8192)
)
DISTRIBUTED BY (client_id); -- ключ дистрибуции по клиенту


💡 Best Practices для таблиц в Greenplum

1. Сжимай данные.

Компрессия (zstd, compresslevel=4) сокращает занимаемое место в хранилище при минимальном влиянии на производительность.

2. Используй колоночное хранение для аналитики.
Greenplum — OLAP-система, и колоночные таблицы значительно ускоряют агрегации и фильтрацию.

3. Heap — только для частых обновлений.
Для оперативных таблиц с частыми UPDATE/DELETE используйте Heap. Для аналитических витрин — AO.

4. Не смешивай типы хранения в одной цепочке.
Факт-таблицы делай AO, справочники — Heap или AO column (если редко обновляются).

5. Обновляй статистику (ANALYZE) после загрузки данных.
Это поможет оптимизатору правильно оценивать стоимость запросов.

Итого

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

Пишите в комментариях вопросы/замечания/что понятно, а что нет👇

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Топ-10 SQL вопросов, которые точно спросят на собесе (уровень junior)

Без практики не обойтись, но теорию не забываем

1️⃣Порядок выполнения SQL-запроса

FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

💡 Поэтому WHERE не видит алиасы из SELECT.

2️⃣ WHERE vs HAVING

*️⃣WHERE — фильтрует строки до группировки
*️⃣HAVING — фильтрует после GROUP BY

Пример:
SELECT city, COUNT(*)
FROM users
WHERE age > 18
GROUP BY city
HAVING COUNT(*) > 10;


3️⃣ Виды JOIN-ов (логические)

JOIN — это оператор, который объединяет строки из двух таблиц по общему полю (ключу), чтобы получить связанные данные в одном наборе.

*️⃣INNER — только совпавшие
*️⃣LEFT — все из левой
*️⃣RIGHT — все из правой
*️⃣FULL — всё подряд

Таблицы склеиваются в "ширину"

4️⃣ UNION vs UNION ALL

UNION (/ALL) — это оператор, который склеивает таблицы вертикально, то есть добавляет строки из одной таблицы под строки другой. Главное — структура (кол-во и типы столбцов) должна совпадать.

UNION — объединяет вертикально и убирает дубли
UNION ALL — объединяет вертикально и оставляет все записи

💡 UNION ALL быстрее, UNION безопаснее, когда хочешь избавиться от повторов.

5️⃣ Как убрать дубликаты?

DISTINCT vs GROUP BY vs ROW_NUMBER() = 1


✅ DISTINCT — просто убрать дубли на уровне строк
SELECT DISTINCT user_id FROM orders;


✅ GROUP BY — группировать по колонке, где требуется оставить уникальные значения
SELECT user_id, COUNT(*) FROM orders GROUP BY user_id;


✅ ROW_NUMBER() — когда дубли одинаковы не по всем полям и нужно выбрать одну по выбранному признаку
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC) AS rn
FROM orders
) t
WHERE rn = 1;

.
6️⃣ DELETE vs TRUNCATE vs DROP

DELETE - Удаляет строки (можно с условием where), можно откатить
TRUNCATE - Удаляет все строки (быстро, без условий)
DROP - Удаляет таблицу целиком

7️⃣ Подзапрос vs CTE

Подзапрос — быстро и локально, когда нужно одно промежуточное значение:
SELECT user_id
FROM orders
WHERE order_date = (
SELECT MAX(order_date)
FROM orders o2
WHERE o2.user_id = orders.user_id
);

💡Минус — код тяжело читать и отлаживать, особенно если вложено несколько уровней.

CTE (WITH) — удобно для пошаговых расчётов и чистого кода:
WITH last_orders AS (
SELECT user_id, MAX(order_date) AS last_dt
FROM orders
GROUP BY user_id
)
SELECT u.user_name, l.last_dt
FROM users u
JOIN last_orders l USING(user_id);

💡 CTE проще дебажить, можно переиспользовать, выглядит как «story» запроса.

8️⃣ Оконные функции
Позволяют считать агрегаты без потери строк 👇
SELECT
user_id,
SUM(amount) OVER (PARTITION BY user_id) AS total_spent,
COUNT(*) OVER () AS total_rows
FROM payments;


💡 GROUP BY схлопывает строки, а OVER() просто добавляет новые расчётные поля.
Например, можно посчитать долю:
SUM(amount) OVER (PARTITION BY category) / SUM(amount) OVER () AS share


9️⃣RANK vs DENSE_RANK vs ROW_NUMBER

Оконные функции, которые:

ROW_NUMBER() - Просто нумерует строки
RANK() - Пропускает номера при одинаковых значениях
DENSE_RANK() - Без пропусков, ранги идут подряд

🧩 Пример:
Зарплаты — [100, 90, 90, 80]

ROW_NUMBER - 1,2,3,4
RANK - 1,2,2,4
DENSE_RANK - 1,2,2,3

1️⃣0️⃣ Работа с NULL в SQL

NULL — это не значение, а отсутствие данных.
Он не равен ничему, в том числе другому NULL.

Фильтровать можно только так:
WHERE col IS NULL
WHERE col IS NOT NULL

а не = NULL или != NULL.

💡 Важно помнить:

*️⃣COUNT(col) игнорирует NULL,
*️⃣COUNT(*) — считает всё,

Также в арифметике 5 + NULL = NULL, в таком случае для подстановки значения используйте функцию COALESCE() для подставки 0 или 'tbd'.

Добавил бы что-то в этот список базированных вопросов? Пиши в комменты

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🆒2🔥1
Как оформить резюме (уже не только опыт) (Ч.2)

Продолжаем рубрику оформления резюме.
В прошлой части разобрали основной блок — опыт работы, теперь возьмемся за остальные части.

1. Релевантность опыта

*️⃣Не отходя от кассы с опытом отмечу важный поинт - релевантность опыта. Оформляем резюме конкретно под вакансию: собесимся на продуктового аналитика — делаем отдельное резюме под ПА, с уклоном в опыт с A/B-тестами; на ДЕ — акцент на архитектуру и ETL, и так далее.

*️⃣Опыт работы также должен соответствовать вакансии (никаких практикантов, менеджеров по планированию и т.д.).

*️⃣Нерелевантный опыт либо удаляем, либо переигрываем под нужную нам вакансию.

2. Контакты

*️⃣Для РФ указываем Москву — повышаем шанс найти вакансию, т.к. больше предложений.
Возраст не указываем — чтобы не натолкнуться на эйджизм.
С зарплатой и должностью уже разобрались в прошлых постах.

3. Блок «О себе»

*️⃣Коротко о себе в рамках вакансии — крутой ДЕшник, работал в X сферах, потрогал Y стек ищу команду/компанию, где можно развиваться в Z.

Пример:
Data Engineer с опытом построения ETL-пайплайнов и моделирования DWH в ритейле и финтехе.
Работал с Airflow, Kafka, Greenplum, ClickHouse, dbt, Docker.
Ищу команду, где можно развивать архитектурные решения и оптимизацию потоков данных

*️⃣Не забываем в данный блок добавлять контакт для связи — Telegram / номер телефона, дабы повысить конверсию.
telegram: @...
phone: +79....

*️⃣Также на hh есть отдельный блок «Контакты – комментарии», куда можно тоже написать tg, но часто HR долбятся в глаза, поэтому дублируем в блоке «О себе» тоже.

4. Навыки

*️⃣Указываем по максимуму хард-скиллы и стек — релевантные под вакансию и рынок (что писать, если не знаешь, обсуждали в посте выше). На hh максимум можно указать 30 навыков — используй это место по максимуму.

4. Курсы

*️⃣Тут много споров - я не пишу полотно курсов, только качественные и, если все таки есть желание их написать, то основную массу советую ставить в даты старта карьеры.

Резюме — это не просто документ, а инструмент продаж твоего опыта/тебя как специалиста.

Если есть вопросы по составлению резюме или его адаптацией под DA/DE — пиши в личку, посмотрим, где можно усилить формулировки и добавить импакта.

А сколько версий резюме у тебя сейчас — одно универсальное или под каждую вакансию отдельное?

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥3
С Никитой больше не здороваемся
🤣8
Оконные функции SQL — must-have для аналитика

SQL — это не только про выборки и фильтры.
Когда нужно посчитать метрики “внутри группы”, сравнить значения между строками или построить рейтинг — обычного GROUP BY уже не хватает.
Здесь на помощь приходят оконные функции (window functions) — они позволяют считать по наборам строк, сохраняя при этом детализацию данных.

Что такое оконная функция ❓

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

Партиция VS Окно❓

*️⃣Партиция (partition) — это логическая группа строк, по которой происходит расчёт.
Например, все заказы одного клиента или все продажи за месяц.

*️⃣Окно (window) — это конкретный набор строк внутри партиции, который реально участвует в вычислении. Окно может совпадать с партицией, а может быть её частью — например, ограничено frame_clause (“три предыдущие строки”).

Коротко:
Партиция — “где считать”,
Окно — “с чем считать”.

Синтаксис
FUNCTION(column)
OVER (
PARTITION BY column1 -- делим данные на группы
ORDER BY column2 -- порядок внутри каждой группы
[frame_clause] -- диапазон строк для вычисления
)


Отличие от GROUP BY❓

GROUP BY схлопывает данные → на выходе одна строка на группу (скрин 1).
WINDOW FUNCTION оставляет все строки, добавляя результат расчёта в отдельный столбец (скрин 2).

Классы оконных функций:

1️⃣Агрегирующие
SUM(), AVG(), COUNT(), MIN(), MAX()
Считают значения по окну (например, средний чек клиента).


2️⃣Ранжирующие
ROW_NUMBER(), RANK(), DENSE_RANK(), NTILE(), CUME_DIST()
Помогают рассчитать позицию строки в группе. RANK() — с пропусками, DENSE_RANK() — без, NTILE(n) — деление на квантильные группы.


3️⃣Функции смещения
LAG(), LEAD(), FIRST_VALUE(), LAST_VALUE(), NTH_VALUE()
Позволяют обращаться к предыдущим/следующим строкам или фиксированным позициям.


4️⃣Статистические
PERCENT_RANK(), PERCENTILE_CONT(), PERCENTILE_DISC()
Используются для анализа распределений — например, вычисления квантилей, процентилей или относительного положения строки в выборке.


Пример
SELECT
name, -- имя ученика
subject, -- предмет
term, -- четверть (1, 2, 3, 4)
grade, -- оценка

AVG(grade) OVER (PARTITION BY name) AS avg_grade, -- средняя оценка по ученику за все четверти
RANK() OVER (PARTITION BY subject ORDER BY grade DESC) AS rank, -- место ученика по оценке среди всех по предмету
LAG(grade) OVER (PARTITION BY name, subject ORDER BY term) AS prev_grade -- оценка ученика по этому же предмету в прошлой четверти
FROM student_grades;


Каждая строка остаётся на месте, но обогащается новыми вычислениями.
То есть оконные функции добавляют в таблицу дополнительные метрики — не схлопывая данные, как GROUP BY, а дополняя их аналитическим контекстом.

Примеры когда и где это нужно:

*️⃣Анализ динамики — LAG/LEAD по датам
*️⃣Расчёт квантилей и рангов
*️⃣Сравнение с группой (среднее, максимум, доля)
*️⃣Аналитика “внутри сегмента” без подзапросов

🎯 Главная идея:

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

🤔 Я чаще всего использую ROW_NUMBER() — когда нужно сделать дедубликацию,
и LAG()/LEAD() — чтобы смотреть динамику по времени.

А ты какие оконные функции применяешь чаще всего?


@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
Запускаю серию длинных постов про теорию данных

Все часто говорят про инструменты — Airflow, dbt, Kafka, Spark и тд...
Но за каждой технологией стоит теория, без которой не бывает зрелой платформы.
Именно с ней мы и разберёмся.

📚 Что будет в серии

Мы пройдём две ключевые книги, которые задают теоретическую базу для работы с данными в целом:

1️⃣ 📘 “Основы инженерии данных”

Практическая книга о жизненном цикле инженера данных.
Рассказывает, какие фоновые процессы обеспечивают устойчивость платформы:
безопасность, управление данными, DataOps, архитектура, оркестрация и программная инженерия.
Главная ценность — системное видение: не «как написать ETL», а как выстроить экосистему данных как инженерную дисциплину.

2️⃣ 📗 DAMA-DMBOK 2. Data Management Body of Knowledge

Международный стандарт управления данными, используемый в Amazon, Netflix, Deloitte.
Описывает 11 областей знаний (DAMA Wheel): от Data Governance и Architecture до Quality, Security и Metadata.

Это не справочник — это карта зрелости data-практик: показывает, какие процессы нужны, чтобы данные стали активом, а не хаосом таблиц.

🧩 Как всё будет устроено

📖 Часть 1. “Основы инженерии данных”
Серия из трёх постов, где разберём все шесть фоновых процессов жизненного цикла (по рис. 2.7 из книги):
1️⃣ Безопасность и управление данными
2️⃣ DataOps и архитектура данных
3️⃣ Оркестрация и программная инженерия

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

🌀 Часть 2. “DAMA Wheel” — 11 областей управления данными

После этого перейдём к обзору DAMA-DMBOK:
Data Governance, Quality, Architecture, Security, Metadata, MDM, Data Ops, Integration, Warehousing, Documents & Content, Big Data Analytics.
Каждую область раскроем отдельным постом — зачем она нужна, кто отвечает, как реализуется в практике.

🎯 Зачем всё это

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

📎 В этом посте (+ под ним) прикреплены:
*️⃣ Схема из книги «Основы инженерии данных» с 6 фоновыми процессами + книга
*️⃣ Классическая диаграмма DAMA Wheel с 11 областями знаний + книга

🚀 Следующий пост — погружаемся в первую книгу:
Ч. 1 — Безопасность и управление данными.

Знаком ли ты с этими книгами?

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥2
Теория о данных.

Безопасность и управление данными — Ч.1


🔐 Безопасность данных

Безопасность — это не “чужая зона ответственности”, а часть профессии каждого, кто работает с данными.

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

P.S. На практике, конечно, матрица ответственности в каждой компании своя:
где-то контроль доступов лежит на ИБ и DevOps, где-то — на владельцах доменов данных, где-то распределён между инженерами, администраторами и data stewards. Но независимо от формальных ролей, все, кто работает с данными, находятся на стыке технологий и ответственности: он первый, кто может предотвратить риск, и часто последний, кто видит его последствия.


Главные принципы:

1️⃣ Минимальные привилегии.
Дай ровно столько доступа, сколько нужно — и только на время задачи.
“На всякий случай” = источник инцидента.
Работа с суперпользовательскими ролями ради SELECT-запросов, создаёт не гибкость, а дыру.

2️⃣ Безопасность во времени.
Доступ должен быть временным.
В зрелых системах права отзываются автоматически, ключи истекают, а доступы согласуются.

3️⃣ Люди — главный риск.
Большинство утечек — не от взломов, а от человеческих ошибок: фишинг, общий доступ, халатность.
Первая линия обороны — культура безопасности, а не технологии.

4️⃣ Защита на всех этапах.
Данные нужно шифровать и при передаче, и при хранении.
Маскирование, токенизация, аудит действий и контроль видимости — стандарт, а не “доп. опция”.

5️⃣ Понимание IAM.
Любой специалист, работающий с данными, должен понимать роли, политики, пароли, сетевые права и ключи доступа. Без этого невозможно построить безопасную и масштабируемую экосистему данных.

📌 Суть проста: безопасность = доверие.
Если данные не защищены, вся аналитика теряет смысл.

🧭 Управление данными

Data Management — звучит корпоративно, но по сути это просто способ сделать данные понятными, надёжными и согласованными между командами.

Ключевые направления:

1️⃣ Data Governance (руководство данными)

Это не про документы, а про согласованность людей, процессов и технологий вокруг данных.
DG определяет, кто владеет данными, как они определяются, как контролируются доступы и как обеспечивается их качество. Когда DG нет — появляются “серые зоны”: дубли, противоречия, отчёты, которым никто не верит, и вечные “откуда эти цифры?”.

DG включает в себя роли (Data Owner, Data Steward), политики, контрольные процедуры и технические инструменты (каталоги, lineage, data contracts).

На практике же в крупных компаниях часто есть отдельно выделенная ставка под stewardship, к которому можно заходить по вопросам данных/их качеству/происхождению и тд.

2️⃣ Изучаемость (Data Discoverability) и подотчётность (Accountability)

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

Data Governance. Изучаемость достигается через data catalogs, документацию, lineage, и систему data stewardship, где за каждый домен отвечает конкретный человек.
Примеры дата каталогов - OpenMetaData/ dbt docs


3️⃣ Metadata Management — управление метаданными

Метаданные — это нервная система платформы.
Они обеспечивают прозрачность и повторное использование данных.

Они бывают четырёх типов:
*️⃣Бизнес-метаданные: определения, владельцы, правила, контекст.
*️⃣Технические: схемы, data lineage, ETL-логика, связи между объектами.
*️⃣Операционные: логи, job ID, SLA, статусы процессов.
*️⃣Справочные: коды, классификаторы, единицы измерения.

Хорошая Metadata Management System связывает инженеров и бизнес: автоматически собирает lineage, но сохраняет человеческий контекст.

Продолжение...

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Теория о данных.

Безопасность и управление данными — Ч.2


4️⃣ Data Quality Management — управление качеством данных
Качество — это не абстракция, а чёткий набор характеристик:

*️⃣Accuracy (точность),
*️⃣Completeness (полнота),
*️⃣Timeliness (своевременность).

Проверка качества должна быть частью пайплайна: тесты данных, SLA и мониторинг аномалий.
“Проверим потом” = потеря доверия к платформе

5️⃣ Master Data Management (MDM)

MDM отвечает за согласованность “основных сущностей”: клиентов, продуктов, контрагентов, филиалов.
Это система и процесс, создающие “золотые записи” (Golden Records) — единые определения для всей организации.

MDM устраняет расхождения между системами и делает возможным единый аналитический контур: CRM, DWH и отчёты работают с одними и теми же объектами.

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

📌 Управление данными делает платформу предсказуемой.
Без него каждый отчёт — гадание на данных, где никто не уверен, откуда взялись цифры и можно ли им верить.

📚 Главные выводы

*️⃣Безопасность — часть инженерного мышления.
*️⃣Управление данными — способ сохранить смысл данных.
*️⃣Метаданные — память платформы.
*️⃣MDM — источник единой истины.

С этими практиками работа с данными становится системной, а не хаотичной.

📘 Пост основан на книге «Основы инженерии данных»
Разбираем первый два блока из схемы “Основные фоновые процессы жизненного цикла инженерии данных”.

А как в вашей компании устроены процессы безопасности, управление качеством и MDM❓👇

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
Теория о данных

DataOps и архитектура данных — Ч. 2


🧩DataOps

Если DevOps ускорил выпуск кода, то DataOps делает то же для данных.
Он переносит принципы Agile, DevOps и Statistical Process Control (SPC) в работу с данными — чтобы информационные продукты создавались быстро, качественно и предсказуемо.

Ключевые принципы DataOps

1️⃣ Автоматизация

*️⃣CI/CD для данных, тесты пайплайнов, версионирование.
*️⃣Контроль зависимостей, блокировка «хрупких» изменений.
*️⃣Проверка качества, дрейфа данных, целостности метаданных.

Пример: раньше выгрузки крутились на локальном Cron/Планировщике — «в 03:00», пока включен ноут, независимо от того, готовы ли данные. После перевода в Airflow/Dagster запуск идёт через сенсор, который ждет обновления таблицы, те задачи стартуют по готовности данных, а не по времени, что убирает ложные запуски и снижает число инцидентов

2️⃣ Наблюдаемость и мониторинг (Data Observability)

Данные ломаются тихо, а ошибки могут жить и накапливаться месяцами.
DataOps ставит наблюдаемость в центр: логи, SLA, алерты, SPC, аномалии.
Подход DODD (Data Observability Driven Development) — наблюдаемость проектируется заранее, а не «когда всё упало».

3️⃣ Реакция на инциденты

Зрелая команда ловит проблему раньше бизнеса.
Автоматические уведомления, быстрый ретроанализ, прозрачная коммуникация.
Цель — сохранить доверие к платформе.

📌 Итог: DataOps = скорость + надёжность + предсказуемость.

🏗 Архитектура данных


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

Ключевые элементы архитектуры

1️⃣ Анализ компромиссов

Каждое решение — баланс между стоимостью, скоростью и поддержкой.
Например, модель Data Vault дает гибкость, но усложняет ETL;
Подход Kimball проще, но менее адаптивен к изменениям и хуже масштабируется при большом количестве СИ по одной сущности

2️⃣ Проектирование для гибкости

Архитектура должна «переживать» изменения бизнеса.
Помогают:
*️⃣многослойность (raw → stage → core → mart),
*️⃣контрактность (data contracts),
*️⃣слабая связанность доменов (DDD),
*️⃣модульность пайплайнов.

💡 Хорошая архитектура позволяет поменять источник без слома десятков отчётов.

3️⃣ Внедрение в бизнес (domain-driven data)

Архитектура отражает бизнес-домены: продажи, логистика, финансы.
Именно поэтому доменная архитектура (Data Mesh, DDD) сегодня так важна.
Она позволяет командам владеть своими данными как продуктом.

4️⃣ Эволюционность

Архитектура — живой организм:
— инструменты меняются,
— паттерны устаревают,
— домены растут.
Зрелая система допускает расширение без «удалить и переписать всё».

📌 Хорошая архитектура данных — это та, которую можно объяснить не только инженеру, но и бизнесу.

📚 Главные выводы

*️⃣ DataOps — это Agile для данных: автоматизация, наблюдаемость, реакция.
*️⃣ Архитектура — это скелет платформы: гибкость, масштабируемость и связь с бизнесом.
*️⃣ Вместе они делают экосистему данных живой и предсказуемой.

📘 Пост основан на книге «Основы инженерии данных».

👉 В следующей части — Оркестрация и программная инженерия: как пайплайны оживают и почему код остаётся сердцем всей data-системы.

🙌 Подпишись и при желании поддержи канал бустом.
P.S. Сделать это можно здесь (для tg premium — бесплатно).

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
Теория о данных

Оркестрация и программная инженерия — Ч. 3


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

⚙️ Оркестрация


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

Чтобы понять, как это работает, нужно объяснить базовый элемент — DAG (Directed Acyclic Graph).
Это просто граф из задач, связанных зависимостями: что должно выполниться до чего.
DAG описывает логику работы пайплайна так, чтобы система могла его корректно и предсказуемо исполнять.

Что делает оркестратор:
*️⃣ запускает задачи в нужном порядке по зависимостям DAG;
*️⃣отслеживает их статус (успех/ошибка/ожидание);
*️⃣реагирует на внешние условия (например, появление данных в хранилище);
*️⃣поднимает тревогу, если пайплайн выбивается из SLA;
*️⃣даёт историю выполнения и визуализацию.

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

Сейчас наиболее распространены Airflow, Prefect, Dagster и Argo.
Инструменты разные, задача одна — превратить хаотичный набор скриптов в управляемую систему.

💻 Программная инженерия

Вот тут важно объяснить что это вообще такое в контексте данных.
В книге программная инженерия поднимается как фундаментальная дисциплина, которая отвечает за создание надёжного, поддерживаемого и воспроизводимого кода — независимо от того, Spark это, SQL, Beam, Python или real-time логика.

Про что программная инженерия в данных:

1️⃣ Про сам код обработки данных
Даже если инструменты стали абстрактными — DataFrame API, SQL-движки в облачных DWH — код писать всё равно нужно. Логика преобразований, бизнес-правила, расчёты, агрегации — это всё инженерная работа.

2️⃣Про качество и надёжность
Пайплайны чаще ломаются не из-за «плохих данных», а из-за кода. Задача инженера — писать предсказуемый, тестируемый код.

3️⃣ Про управление сложностью
Чем больше данных и процессов — тем важнее архитектура кода: модули, структуры, слои трансформаций, единые правила именования, обработка ошибок.
Это не про «программистские практики ради практик»: только так пайплайны можно поддерживать годами.

4️⃣ Про взаимодействие с инструментами
Инженер работает не только с кодом, но и с фреймворками: Spark, Beam, Flink, функции в облаках, API-коннекторы. Всё это требует понимания, как устроена обработка под капотом: распределение, партиции, память, сериализация.

5️⃣ Про инфраструктуру
Сегодня инфраструктура — тоже код: Terraform, Helm, Kubernetes.
IaC (Infrastructure as Code) — это когда конфигурации описываются в файлах, а не вручную.
Так система становится воспроизводимой и не зависит от «настроек на сервере, которые никто не помнит».

В итоге программная инженерия — это не «уметь писать на SQL и Python».
Это способность создавать устойчивый процесс обработки данных, который работает предсказуемо под нагрузкой, в потоке и в долгой эксплуатации.

📚 Главные выводы

*️⃣Оркестрация — делает пайплайны управляемыми: порядок, зависимости, SLA, ошибки.
*️⃣Программная инженерия — делает пайплайны надёжными: код, качество, предсказуемость и инфраструктура.
*️⃣Вместе они превращают хаос скриптов в стабильную платформу данных.

📘 Пост основан на книге «Основы инженерии данных».

Как отметил в начале, это финальный пост по жизненному циклу на уровне концепций — дальше будем разбирать его глубже уже через DAMA-DMBOK, где эти процессы разложены куда детальнее.

🙌 Подпишись и при желании поддержи канал бустом.
P.S. Сделать это можно здесь (для Premium — бесплатно).

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
🤨SQL-практика: сколько строк вернет JOIN?

Возвращаемся к практическим задачам - а то мы с вами последнее время залипли в теорию. И начнем с темы, которая встречается почти на каждом собесе - поведение JOIN-ов.

Смотрим, что происходит со строками в разных типах соединений.
Представим две таблицы по ключу id:

t1 — 10 строк
t2 — 10 строк


И дальше важный момент: итог зависит не от того, «сколько строк в таблицах», а от того, как распределены значения ключей внутри таблиц. Поэтому min/max у каждого JOIN-а - это про математику, но на радость - 2го класса😁

1️⃣ INNER JOIN

Минимум — 0 строк.
Если пересечений нет, результат пустой.

Максимум — 100 строк.
Если каждая строка в t1 соединяется с каждой строкой в t2 (кейс «все id одинаковые»).

2️⃣ LEFT JOIN

Минимум — 10 строк.
Даже если совпадений нет, все строки левой таблицы остаются.

Максимум — 100 строк.
Та же логика перемножения при одном повторяющемся значении в 2х таблицах.

3️⃣ RIGHT JOIN

Аналогично LEFT, только «базовая» таблица — правая.

Минимум — 10 строк
Максимум — 100 строк

4️⃣ FULL JOIN

Вот здесь часто допускают ошибку...

Минимум — 10 строк.
Минимальное количество — это объём большей таблицы.
Если обе по 10, минимум тоже 10.

Максимум — 100 строк.
Как уже разбирали выше - в случае полного совпадения всех id.

5️⃣ CROSS JOIN

Всегда одно и то же:
100 строк — и min, и max.
Это декартово произведение без условий.

🤨Что происходит с дублями?

Если в t1 три строки с id=1, а в t2 четыре строки с id=1, то на выходе:

3 × 4 = 12 строк

JOIN умножает, если ключ не уникален.
Это главный источник "роста" выборки.

🤔 А что с NULL?

Ещё одна любимая ловушка на собесах:

NULL = NULL → FALSE
NULL != NULL → FALSE

То есть строки с NULL не соединяются друг с другом ни при каком обычном JOIN-е.

INNER JOIN → NULL-ы полностью выпадут
LEFT JOIN → останутся с правой частью NULL
RIGHT JOIN → наоборот, справа
FULL JOIN → попадут как несвязанные строки для каждой из сторон

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

🧠 Итоговая памятка по JOIN-ам (t1 = 10 строк, t2 = 10 строк)

*️⃣INNER JOIN
min — 0
max — 100

*️⃣LEFT JOIN
min — 10
max — 100

*️⃣RIGHT JOIN
min — 10
max — 100

*️⃣FULL JOIN
min — 10
max — 100

*️⃣CROSS JOIN
min — 100
max — 100

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

🙌 Подпишись и при желании поддержи канал бустом.
P.S. Сделать это можно здесь (для Premium — бесплатно).

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
Прочитай это перед тем, как идти работать аналитиком в ритейл 🛒📊

Допустим, ты уже разобрал харды - SQL, Питон и, собираешься на собес в крупный ритейл/FMCG: Магнит, X5, Ленту, ВкусВилл и т.д. Чтобы пройти финал с командой, важно понимать не только инструменты, но и какими метриками живет офлайн-ритейл.

Работая аналитиком в большом федеральном ритейле (🧲), я заметил простую штуку: как только ты понимаешь метрики, работа перестает быть механическим подсчётом и превращается в разбор причин и последствий. Понимание метрик ускоряет решение любых задач и позволяет видеть причины, а не просто считать цифры.

🔥 ТОП 10 основных метрик в ритейле / FMCG

1️⃣GMV / RTO (Gross Merchandise Value / Выручка)

Общая сумма продаж за период.
Используется для анализа динамики, план-факт, сезонности, можно разбить по форматам, регионам и тд.

2️⃣Margin

Показывает, сколько денег остаётся после вычета себестоимости.
Ключевой показатель прибыльности категорий и конкретного SKU.

3️⃣Back Margin (Бэк-маржа)

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

4️⃣Количество проданных штук (QNT)

Фактическая штуковая продажа конкретного SKU или целой товарной группы.

5️⃣Количество чеков (Traffic)

Это базовая метрика потока: сколько покупок (чеков) совершили за период.

Используется для анализа:
*️⃣эффективности акций (даёт ли промо рост трафика);
*️⃣изменение поведения покупателей (день недели / часы пиков);
*️⃣сравнения форматов (в формате X трафик выше, в Y ниже);
*️⃣операционки (планирование персонала, касс, выкладки).

Рост чеков ≠ рост выручки → важно держать связку чеков с AOV.

6️⃣ Количество клиентов (QNT client)

Показывает, сколько покупателей совершили покупку за период.

Это важная метрика для:
— лояльности (сколько покупателей возвращается);
— клиентских сегментаций (RFM, CVM и тд);
— частоты (frequency) — напрямую рассчитывается через клиентов;
— оценки удержания (retention на период);
— эффекта промо на клиентскую базу (привели новых или крутили старых).

В офлайне корректно считать клиентов можно только по лояльным (кто показал карту при оплате).

7️⃣ Количество магазинов

Если чеков и клиентов много — нужно понимать, сколько точек генерируют этот поток.

Используется для:
— LFL (like-for-like) — фильтрация только тех магазинов, которые работали в оба периода
(Период X и X-n, где n время до);
— оценки эффективности форматов;
— распределения инвестиций и промо-бюджетов;
— оценки потенциала регионов.

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

8️⃣Frequency

Частота покупок (посещений). Рассчитывается отношением количества чеков к числу клиентов за период. Показывает удержание и глубину лояльности.

9️⃣ARPPU (Average Revenue per Paying User)

Средняя выручка на "покупающего" клиента.
В офлайн ритейле под “покупающим клиентом” обычно понимают лояльного клиента (с картой) — тех, кого можно идентифицировать. Рассчитывается отношением GMV на одного лояльного клиента. Метрика активно используется в loyalty-аналитике.

1️⃣0️⃣ AOV (Average Order Value / Средний чек)

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

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

💬С какой метрикой у вас были реальные проблемы в задачах или на собесах? Давайте обменяемся опытом. Напишите в комментариях👇

Подпишись и при желании поддержи канал бустом.
P.S. Сделать это можно здесь (для Premium — бесплатно).

@data_driven_bogdan
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥3👍1
Обзор собеседования

Компания: AVON
Вилка: 350 net вроде готовы
Должность: DE
Формат: Удаленный/гибрид
Этапы собеседования:
HR – Тех. собес 1 (с лидом + бизнес разговорный) – Тех. собес 2 (лайфкодинг) – Offer
Грейд: Senior
Дата собеса: ноябрь 2025

Вопросы:
1. Data Vault: сущности, плюсы/минусы, зачем нужен.
2. SCD2: что такое, как могут фиксироваться изменения
как выстроить scd2 если уник. ключ записи составной и состоит из 15 колонок
3. как работает CDC?
4. Расскажи с чем работал и пример одного из нетривиальных потоков данных
5. PXF что такое и зачем нужен?
6. Greenplum: heap vs AO, выбор distribution key, data skew.
7. Индексы в БД, привести пару примеров типов индекса и чем они отличаются, плюсы и минусы (когда нужны, а когда делают хуже). Можно ли в ГП использовать индексы? Если нужно, приведи примеры
8. Сценарий: много insert-ов + точечные селекты под условия (много where запросов) - что выбираем: нужен ли индекс? если нет, то что можно использовать для оптимизации?
9. План запроса: что читаю первым делом? какие красные флаги?
10. DAG упал по таймауту: как ищу узкое место и работаю с оптимизацией
11. PostgreSQL: где смотреть блокировки и активность (pg_stat_activity, pg_locks, журналы).
12. Какие есть виды блокировок?
13. Что такое OLAP и OLTP? Опыт сбора куба на клике
14. Работал со спарком? Расскажи как в пайплайнах его использовали

Коротко мои мысли:

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

Подпишись и при желании поддержи канал бустом.
P.S. Сделать это можно здесь (для Premium — бесплатно).

@data_driven_bogdan
❤11🔥6🙈2