| 테이블 | INSERT | UPDATE · DELETE | UPSERT |
|---|---|---|---|
| HDFS Parquet · Text 등 | 가능 | 불가 | 불가 |
| Kudu | 가능 | 가능 | 가능 |
| Iceberg v2 | 가능 | 가능 | 불가 |
UPDATE 와 DELETE 는 Kudu 와 Iceberg 테이블에서만 동작한다. 일반 HDFS 테이블은 파일을 다시 쓰는 수밖에 없다.
INSERT OVERWRITE TABLE db.tbl PARTITION (bse_dt='20250905')
SELECT ... FROM ...;
UPDATE tbl AS a SET ... 는 문법 오류가 난다. 별칭은 테이블 이름 뒤가 아니라 FROM 절에서 도입한다.
UPDATE [db.]table_name SET col = expr [, col = expr ...]
[ FROM joined_table_refs ]
[ WHERE conditions ]
조인 기반 갱신이 지원되지 않는다는 말은 사실이 아니다. FROM 절에 조인을 쓰고 그 결과에 해당하는 행만 갱신할 수 있다.
UPDATE a SET a.amt = b.amt
FROM main_tbl a JOIN staging_tbl b ON a.id = b.id
WHERE b.bse_dt = '20250905';
WHERE EXISTS 서브쿼리 대신 조인으로 바꿔 쓰면 된다. 신규 파일에 없는 기존 행의 플래그를 0 으로 내리는 작업도 같은 방식이다.
UPDATE a SET a.active_flag = 0
FROM main_tbl a LEFT JOIN incoming b ON a.id = b.id
WHERE b.id IS NULL;
기본키 컬럼은 SET 으로 바꿀 수 없다. 키를 바꿔야 하면 DELETE 후 INSERT 다. WHERE 를 빼면 전체 행이 갱신되므로 주의한다.
Kudu 전용이다. 기본키가 있으면 갱신, 없으면 삽입한다.
UPSERT INTO db.kudu_tbl (id, name, amt) VALUES (1, 'a', 100);
UPSERT INTO db.kudu_tbl SELECT id, name, amt FROM staging;
일별 스냅샷을 병합하는 작업은 대부분 UPSERT 한 번으로 끝난다. Iceberg 에는 UPSERT 가 없다.
Impala 는 오랫동안 MERGE 를 지원하지 않았다. 최근 버전에서 Iceberg 테이블을 대상으로 지원이 추가됐으므로, 쓰기 전에 사용하는 배포판·버전에서 동작하는지 확인한다. Kudu 테이블에는 UPSERT 가 사실상 같은 역할을 한다.
MERGE 없이 같은 결과를 내는 표준 패턴은 세 단계다.
-- 1) 삭제 대상 표시 또는 삭제
DELETE FROM main_tbl WHERE id IN (SELECT id FROM staging);
-- 2) 신규·변경분 적재
INSERT INTO main_tbl SELECT * FROM staging;
Kudu 라면 1·2 를 UPSERT 하나로 대체한다. Hive 는 ACID(ORC) 테이블에서 MERGE 를 지원하므로, 병합이 꼭 필요하고 Kudu 를 쓸 수 없다면 Hive 쪽에서 처리하는 선택지도 있다.
Impala 에는 BEGIN · COMMIT · ROLLBACK 이 없다. 문장 하나가 실행되면 그대로 확정된다. JDBC 드라이버의 setAutoCommit(false) 는 의미가 없거나 예외를 던진다.
따라서 여러 문장을 묶어 원자적으로 처리하는 방법은 없다. 중간 실패를 견뎌야 하는 배치는 스테이징 테이블에 모아 두었다가 마지막에 한 문장으로 반영하고, 실패 시 스테이징을 버리는 식으로 설계한다.
Kudu DML 은 동시 실행 시 강한 일관성을 보장하지 않는다. 같은 행을 동시에 건드리는 작업이 겹치면 처리 건수가 기대와 다를 수 있다.