ETL-процессы часто прерываются: сетевой сбой, таймаут, рестарт кластера. Если загрузка не спроектирована идемпотентно, после перезапуска могут появиться дубликаты.
Решение – использовать
MERGE (в PostgreSQL) или INSERT ... ON CONFLICT DO UPDATE (в SQLite, PostgreSQL), или REPLACE (MySQL). Уникальный составной ключ (например, order_id + line_id) гарантирует, что повторная вставка не создаст дубль, а обновит существующую строку или проигнорирует её.Пример кода:
sql
INSERT INTO dwh_orders (order_id, amount, loaded_at)
VALUES (123, 1000, NOW())
ON CONFLICT (order_id) DO UPDATE SET
amount = EXCLUDED.amount,
loaded_at = EXCLUDED.loaded_at;
Почему это важно для аналитика?
В требованиях к интеграции данных нужно явно указывать: «Загрузка должна быть идемпотентной. Повторный запуск того же пакета не должен порождать дубликатов». Без этого после каждого сбоя оператору придётся вручную чистить таблицу.
Реальный кейс: В крупном ретейлере из-за отсутствия идемпотентности при ночном сбое накопилось 15% дублей заказов. Отчётность встала на неделю.