LabHub

SI DB 운영 · 데이터 이관과 검증 · 이론

데이터 이관은 별도 트랙이다

LabHub 에서 이어서 보기

한 줄 요약

데이터 이관은 개발이 끝나고 시작하는 일이 아니라 개발과 나란히 가는 별도 트랙이고, 이관에서 발견되는 데이터 문제가 설계를 바꾸기도 한다.

왜 이게 문제인가

이관을 후반 작업으로 미루면 발견의 시점이 늦어진다. 그런데 이관에서 나오는 문제는 대개 선택지가 시간에 달린 문제다.

신규 스키마에 NOT NULL 로 잡은 컬럼이 레거시에서는 30% 비어 있다고 하자. 6 개월 전에 알면 스키마를 고치거나, 기본값 규칙을 합의하거나, 업무 쪽에 정리를 요청할 수 있다. 오픈 2 주 전에 알면 남는 선택지는 하나뿐이다 — 그냥 채워 넣는 것. 그리고 그렇게 채운 값은 몇 년 동안 그 시스템의 데이터로 남는다.

이관은 프로젝트 후반의 일이 아니다

차세대 프로젝트 회고에서 반복적으로 나오는 교훈이 있다.

> 데이터 이행은 프로젝트 초기부터 별도 트랙으로 관리해야 한다.

이유는 단순하다. 이관은 **개발이 끝나야 시작할 수 있는 일이 아니라
개발과 병렬로 가야 하는 일**이기 때문이다.
그리고 이관 과정에서 발견되는 데이터 문제가 설계를 바꾸기도 한다.

실제로 자주 벌어지는 일:

이걸 오픈 2주 전에 발견하면 선택지가 없다. 6개월 전에 알면
스키마를 고치거나, 정제 규칙을 합의하거나, 업무 정리를 요청할 수 있다.

이관 리허설은 3회

대형 프로젝트의 이관 계획에는 리허설이 여러 번 들어간다.

1차 리허설 (D-90) : 절차 확인. 시간이 얼마나 걸리는가2차 리허설 (D-30) : 데이터 품질 확인. 정제 규칙 검증3차 리허설 (D-7)  : 실전과 동일 조건. 시간·순서·인원 확정

리허설의 진짜 산출물은 데이터가 아니라 소요 시간 실측치다.
"이관에 4시간 걸립니다"를 추정이 아니라 측정으로 말할 수 있어야
이행 계획의 타임라인이 성립한다. 그리고 대부분 첫 리허설에서
예상보다 2~3배 걸린다는 것을 알게 된다.

AS-IS → TO-BE 매핑 정의서

이관의 핵심 산출물이다. 컬럼 단위로 이렇게 적는다.

| TO-BE 테이블 | 컬럼 | AS-IS 원천 | 변환 규칙 | 미매핑 시 |
| --- | --- | --- | --- | --- |
| CUSTOMER | CUST_NM | TB_CUST.NAME | TRIM, 공백 정규화 | 오류 |
| CUSTOMER | REG_DT | TB_CUST.REGDATE | YY/MM/DDYYYYMMDD | 19000101 |
| CUSTOMER | GRADE_CD | TB_CUST.LEVEL | 코드 매핑표 참조 | 99(기타) |
| ORDERS | ORD_STS_CD | TB_ORD.STATUS | 코드 매핑표 참조 | 이관 제외 |

"미매핑 시" 열이 핵심이다. 매핑되지 않는 값이 나왔을 때
오류로 볼 것인지, 기본값을 넣을 것인지, 그 행을 제외할 것인지.
이걸 정하지 않으면 개발자가 임의로 처리하고, 그 결과는
"건수가 안 맞는다"로 돌아온다.

그리고 제외한 건은 반드시 목록으로 남긴다.
"1,200건 중 1,187건 이관, 13건 제외"까지가 결과이고,
그 13건이 무엇인지 답할 수 있어야 한다.

정제(cleansing)에서 실제로 하는 일

레거시 데이터는 대개 이렇다.

| 증상 | 예 | 처리 |
| --- | --- | --- |
| 앞뒤 공백 | " 홍길동 " | TRIM |
| 날짜 형식 혼재 | 20260801, 2026-08-01, 26/08/01 | 하나로 정규화 |
| 문자열 NULL | 값이 문자 "NULL" 또는 "null" | 진짜 NULL 로 |
| 금액에 서식 | "1,250,000" | 콤마 제거, 숫자로 |
| 중복 | 같은 키가 여러 건 | 규칙 정해 하나만 (보통 최신 수정일) |
| 코드값 불일치 | 폐기된 코드, 오타 | 매핑표 또는 기타 코드 |
| 인코딩 깨짐 | ????? | 원천에서 재추출 |

중복 제거 규칙은 반드시 업무와 합의해야 한다.
"최신 것을 남긴다"가 자연스러워 보이지만, 최신 행이 오히려
불완전한 경우도 있다. 기술적 판단이 아니라 업무 판단이다.

검증 — 네 층으로

이관 후 검증은 아래에서 위로 쌓는다. 하나라도 빠지면 구멍이 생긴다.

1. 스키마 검증   테이블·컬럼·타입·제약·인덱스가 의도대로 있는가2. 데이터 검증   건수 · 합계 · NULL 개수 · 체크섬3. 성능 검증     주요 쿼리의 실행계획과 응답시간4. 애플리케이션  핵심 업무 시나리오 스모크 테스트

2번에서 체크섬을 쓰는 이유를 다시 강조한다.
건수와 합계만으로는 "한 건이 빠지고 다른 한 건이 두 배가 된" 상황을 못 잡는다.
정렬된 키 목록의 해시를 비교하면 그런 경우까지 잡힌다.

-- 개념적으로: 키를 정렬해 이어 붙인 문자열의 해시SELECT md5(group_concat(CUST_ID, ',' ORDER BY CUST_ID)) FROM CUSTOMER;

검증 비용과 신뢰도는 이렇게 다르다.

| 방법 | 비용 | 신뢰도 |
| --- | --- | --- |
| 표본 확인 | 낮음 | 낮음~중간 |
| 집계(건수·합계) | 낮음 | 중상 |
| 체크섬 | 중간 | 높음 |
| 전수 비교 | 높음 | 매우 높음 (금융 등 무결성 필수 영역) |

이관 결과 확인서

구두 확인으로 끝내면 안 된다. 문서로 남긴다.

## 이관 대상  CUSTOMER  원천 1,200건 → 이관 1,187건, 제외 13건  ORDERS    원천 45,320건 → 이관 45,320건, 제외 0건## 제외 사유  코드 미매핑  9건 (목록: excluded_code.csv)  필수값 누락  4건 (목록: excluded_null.csv)## 검증 결과  건수 일치     OK  금액 합계 일치 OK (원천 8,213,400,000 / 대상 8,213,400,000)  키 체크섬 일치 OK## 재이관 대상  13건 - 업무 정리 후 D+3 재이관 예정, 담당 ○○○## 확인  수행사 ___  발주사 ___

이 문서가 있으면 오픈 후 "데이터가 없는데요"라는 문의에
그 13건은 이관 제외 대상이고 D+3 재이관 예정입니다 라고 답할 수 있다.
없으면 처음부터 조사해야 한다.

이관 실패 시의 원칙

마지막으로 하나. 이관 중 문제가 생겼을 때의 원칙이다.

> 데이터를 건드리는 복구는 최후의 수단이다.

순서는 이렇다.
1. 기능 플래그로 신규 경로를 끈다 (가능하면)
2. 트래픽을 이전 시스템으로 되돌린다
3. 그래도 안 되면 스키마 롤백
4. 마지막에 데이터 복구(백업 복원, 시점 복구)

4번이 가장 오래 걸리고 가장 위험하다.
그래서 앞의 세 단계를 미리 준비해 두는 것이 이행 계획의 실력이다.

현장에서 만나는 모습

이관이 끝났는지를 판단하는 기준도 자주 어긋난다. "오류 없이 돌았다" 는 끝났다는 뜻이 아니다. 대사(對査)를 해 보면 건수가 다르거나 금액 합계가 안 맞는 일이 흔한데, 그 차이가 설명 가능한 차이인지가 진짜 기준이다.

중복 제거로 20 건이 줄었다면 건수는 당연히 안 맞고, 그건 정상이다. 반대로 아무 이유 없이 3 건이 비면 그건 사고다. 그래서 대사표에는 차이를 0 으로 만드는 칸이 아니라 차이와 그 사유를 적는 칸이 있어야 한다.

제외된 건의 목록도 반드시 남긴다. 이 파일이 없으면 오픈 뒤 "우리 고객이 안 넘어왔다" 는 문의에 답할 방법이 없고, 그때 다시 세는 것은 불가능하다.