ETL против ELT

Урок разбирает два подхода к построению конвейера — ETL и ELT — и помогает выбрать правильный.

ETL — Extract, Transform, Load: извлечь, преобразовать, загрузить. ELT — Extract, Load, Transform: извлечь, загрузить сырыми, преобразовать уже внутри хранилища.

Три буквы конвейера

Любой пакетный конвейер состоит из трёх шагов: Extract (забрать данные из источника), Transform (очистить, привести к нужному виду, посчитать) и Load (положить в приёмник). Разница между ETL и ELT — только в порядке шагов T и L.

ETL:  Extract → Transform → Load     (преобразуем ДО загрузки)
ELT:  Extract → Load → Transform     (грузим сырьё, преобразуем ВНУТРИ)

Когда какой подход

ETL — классика

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

ELT — современный подход

Сырые данные грузят в облачное хранилище (Snowflake, BigQuery, ClickHouse), а преобразования пишут на SQL уже там. Хранилища стали дешёвыми и мощными, поэтому считать прямо в них выгоднее. Бонус: сырьё сохранено, и логику преобразований можно переписать задним числом, не выкачивая данные заново. Это огромное преимущество для аналитики, где требования меняются постоянно: добавили новую метрику — просто написали ещё одну SQL-модель поверх того же сырья, и backfill пересчитал историю.

КритерийETLELT
Где преобразованиена сервере конвейеравнутри хранилища (SQL)
Хранится сырьёобычно нетда
Типичный стекPython, SparkSQL, dbt

Как работает под капотом

Покажем шаг Transform на чистом Python: фильтруем строки и приводим валюту к рублям до загрузки (это «T» в ETL).

rows = [
    {"id": 1, "sum": 100, "cur": "USD"},
    {"id": 2, "sum": 50, "cur": "RUB"},
    {"id": 3, "sum": 0, "cur": "RUB"},
]
rate = {"USD": 90, "RUB": 1}
clean = [
    {"id": r["id"], "rub": r["sum"] * rate[r["cur"]]}
    for r in rows if r["sum"] > 0
]
for r in clean:
    print(r)

Вывод:

{'id': 1, 'rub': 9000}
{'id': 2, 'rub': 50}

А вот тот же Transform, но в стиле ELT — на SQL прямо в хранилище, куда сырьё уже загружено.

CREATE TABLE raw_orders (id INTEGER, sum INTEGER, cur TEXT);
INSERT INTO raw_orders VALUES (1, 100, 'USD'), (2, 50, 'RUB'), (3, 0, 'RUB');

SELECT id,
       sum * CASE cur WHEN 'USD' THEN 90 ELSE 1 END AS rub
FROM raw_orders
WHERE sum > 0;

Логика одна и та же — отфильтровать пустые заказы и пересчитать валюту, — но в ETL она исполняется на сервере конвейера на Python, а в ELT уже внутри хранилища на SQL. Заметьте: в ELT-версии сырая таблица raw_orders остаётся нетронутой, и если завтра курс доллара поменяется, достаточно переписать SELECT, не трогая загрузку. Именно эта гибкость и сделала связку «ELT + dbt» индустриальным стандартом для аналитических хранилищ.

Частые ошибки

  • Думать, что ELT всегда лучше. Если в данных есть персональные сведения, которые нельзя хранить сырыми, ETL с очисткой на входе уместнее.
  • Грузить «всё подряд» в ELT без плана. Дешёвое хранилище не повод сваливать туда мусор — это превращается в неуправляемое болото данных.
  • Путать порядок букв. В ELT сырьё ложится в хранилище до преобразования, а не после.

Итог

  • ETL и ELT отличаются порядком шагов Transform и Load.
  • ETL преобразует до загрузки, ELT — внутри хранилища на SQL.
  • Дешёвые облачные хранилища сделали ELT подходом по умолчанию для аналитики.
Проверьте себя
1. В чём ключевое отличие ELT от ETL?
AВ ELT данные не преобразуются вовсе
BВ ELT преобразование происходит внутри хранилища, после загрузки сырья
CВ ELT нет шага извлечения данных
DELT работает только с CSV-файлами
2. Почему ELT стал популярным подходом в последние годы?
AОблачные хранилища стали дешёвыми и мощными, считать прямо в них выгодно
BETL перестал работать технически
CSQL запретили использовать в конвейерах
DELT не требует извлекать данные из источников
3. Когда ETL предпочтительнее ELT?
AКогда нужно как можно больше сырых данных
BКогда хранилище очень дешёвое
CКогда персональные данные нужно очистить или скрыть ещё до загрузки в хранилище
DКогда нет источников данных