건수가 같아도 같은 업무표는 아니다
어제 20건, 오늘 20건이라는 요약만으로 변경이 없다고 볼 수 없습니다. 2건이 추가되고 2건이 삭제됐거나 담당자·상태가 바뀌었을 수 있습니다. 두 업무표를 행 번호가 아니라 변하지 않는 업무 ID로 연결해야 추가·삭제·속성 변경을 나눌 수 있습니다. 이 글은 두 시점의 사본을 비교하는 방법을 설계합니다.
비교 대상은 어제와 오늘의 동일 업무 범위입니다. 한쪽이 전체 업무, 다른 쪽이 진행 중 업무만 내보낸 파일이면 완료 행이 사라진 것을 삭제처럼 볼 수 있습니다. 스냅샷 비교는 두 파일 사이의 차이를 보여주지만 파일 범위가 다른 이유나 실제 삭제 행위를 자동으로 입증하지 않습니다. 아래 사례는 가상 업무 ID와 담당자 표기로 구성했습니다.
비교 전에 두 파일의 계약을 맞추기
파일 이름, 내보내기 시각, 포함 상태, 기간, 조직·구역 범위를 기록합니다. 같은 화면에서 내보냈더라도 필터가 달랐는지 확인합니다. 업무 ID는 문자열로 보존하고 빈 ID·중복 ID가 있으면 먼저 보류합니다. 변하지 않는 ID가 없을 때는 행 전체를 연결 기준으로 삼기보다 원본 시스템의 식별값을 확인합니다.
변경 검사 대상 열도 먼저 고릅니다. 이 예제는 담당자와 상태 두 열만 비교합니다. 수정 시각처럼 저장할 때마다 바뀌는 열은 결과가 항상 변경으로 보일 수 있으므로 별도 메타데이터로 둡니다. 금액·기한·내용까지 검사하려면 각 열의 의미와 자료형을 맞춘 뒤 대상에 추가합니다.
열이 추가되거나 이름이 바뀌었다면 스키마 변경을 먼저 기록합니다. 어제 “담당”, 오늘 “책임자”가 같은 의미인지 확인하지 않으면 값 비교를 시작할 수 없습니다. 스냅샷마다 빈 열을 만들어 넣는 방법도 그 열이 원래 없었다는 사실을 보존해야 합니다. “열 없음”과 “열은 있지만 값 없음”은 구분합니다.

8행에서 추가·삭제·변경·보류를 읽기
T-01은 양쪽에 있고 담당·상태가 같아 이 비교 범위에서 동일입니다. T-02는 담당만, T-03은 상태만, T-04는 담당과 상태 모두 바뀌었습니다. T-05는 오늘에만 있으므로 추가 후보, T-06은 어제에만 있으므로 삭제 후보입니다. 후보라는 표현은 원본 시스템에서 어떤 행위가 있었는지 아직 확인하지 않았기 때문입니다.
T-07은 오늘 쪽 동일 ID가 2행이라 보류합니다. T-08은 오늘 담당이 원본 문자열 “박담당 ”처럼 공백을 포함해 바뀐 사례입니다. 업무 의미가 같을 수 있어도 정확 문자열 기준에서는 담당 변경입니다. 이 실습표의 정상 비교 결과는 동일 1, 속성변경 4, 추가후보 1, 삭제후보 1, 중복보류 1로 총 8키입니다.
| 업무 ID | 어제 키 수 | 오늘 키 수 | 어제 담당 | 어제 상태 | 오늘 담당 | 오늘 상태 | 변경 열 | 판정 |
|---|---|---|---|---|---|---|---|---|
| T-01 | 1 | 1 | 김담당 | 대기 | 김담당 | 대기 | 동일 | |
| T-02 | 1 | 1 | 김담당 | 진행 | 이담당 | 진행 | 담당 | 속성 변경 |
| T-03 | 1 | 1 | 박담당 | 대기 | 박담당 | 완료 | 상태 | 속성 변경 |
| T-04 | 1 | 1 | 김담당 | 진행 | 이담당 | 완료 | 담당·상태 | 속성 변경 |
| T-05 | 0 | 1 | 이담당 | 대기 | 추가 후보 | |||
| T-06 | 1 | 0 | 박담당 | 보류 | 삭제 후보 | |||
| T-07 | 1 | 2 | 김담당 | 대기 | 오늘 중복 키 | |||
| T-08 | 1 | 1 | 박담당 | 대기 | 박담당 | 대기 | 담당 | 속성 변경 |
이 글의 기록 양식 내려받기
어제와 오늘의 업무표에서 추가·삭제·변경을 나누어 확인하기 — CSV 양식
UTF-8 BOM이 있는 기록용 CSV입니다. 계산식·드롭다운·서식은 들어 있지 않습니다. 첫 행 9열, 설명용 데이터 8레코드가 있습니다.
가상 업무 8키입니다. 담당 표기는 실제 개인 이름이 아닙니다. 마지막 행의 담당 값에는 끝 공백1개를 남겼습니다. CSV는 두 파일을 자동 비교하는 도구가 아닌 비교 기록 양식입니다.
CSV 구조와 식별자 점검 도구에서 사본의 열 수와 문자열을 확인할 수 있습니다.
가상 업무 8키입니다. 담당 표기는 실제 개인 이름이 아닙니다. 마지막 행의 담당 값에는 끝 공백 1개를 남겼습니다. CSV는 두 파일을 자동 비교하는 도구가 아닌 비교 기록 양식입니다.
키의 합집합에서 양쪽 존재 여부 확인하기
어제 ID 목록과 오늘 ID 목록의 합집합을 만들고 각 ID의 양쪽 개수를 셉니다. 어제 0·오늘 1이면 추가 후보, 어제 1·오늘 0이면 삭제 후보입니다. 양쪽 모두 1인 행만 담당·상태 값 비교로 넘어갑니다. 어느 쪽이든 2이상이면 속성값을 선택하지 않고 중복 보류로 남깁니다.
이 순서는 순서 변경과 실제 값 변경을 분리합니다. 오늘 파일을 담당자순으로 정렬해도 ID별 판정은 같아야 합니다. 행 번호 2에 있던 업무가 행 번호 9로 옮겨갔다고 삭제·추가로 분류하지 않습니다. CSV 내보내기 과정에서 새 행 번호를 만들었다면 그것도 비교 키로 쓰지 않습니다.
파일 전체 해시가 달라졌다는 사실은 바이트가 달라졌음을 알려줍니다. 줄바꿈·열 순서·정렬만 달라져도 해시가 바뀌므로 업무 내용이 바뀌었다는 직접 증거는 아닙니다. 반대로 해시가 같으면 사본 바이트의 일치 확인에 유용하지만 실제 시스템 상태가 최신인지는 별도입니다. 스냅샷 파일의 생성 시각과 범위를 함께 보관합니다.
열별 비교 결과를 변경 이유와 구분하기
같은 키의 담당·상태는 각각 비교하고 바뀐 열 이름을 남깁니다. Google Sheets의 EXACT는 문자, 대소문자, 공백·숨겨진 문자를 포함해 같은지 확인할 때 참고할 수 있습니다. 어제 담당과 오늘 담당이 정확히 같은지, 어제 상태와 오늘 상태가 정확히 같은지를 분리하면 한 열의 변화가 다른 열의 변화에 가려지지 않습니다.
이 예제에서 “변경”은 값 차이를 뜻합니다. 누가 왜 바꿨는지, 승인됐는지, 적절했는지를 뜻하지 않습니다. 상태가 대기에서 완료로 바뀌면 완료 근거가 실제로 존재하는지 원본을 열어 확인해야 합니다. 담당이 바뀌면 인계나 권한이 함께 반영됐는지도 별도 절차로 확인합니다.
숫자나 날짜 열을 추가할 때는 문자 비교만으로 판단하지 않습니다. 숫자 1과 표시 1.00이 업무적으로 같은지, 통화·소수 자리·자료형이 맞는지 정합니다. 시간대가 다른 날짜·시각은 같은 시간축으로 바꾼 뒤 비교합니다. 비교 기준을 바꾸면 이전 결과도 어떤 기준에서 나왔는지 버전으로 남깁니다.
공백 정규화를 하려면 두 결과를 남기기
T-08의 담당 공백을 무조건 제거하면 변경 목록에서 사라집니다. 이름의 앞뒤 공백을 의미 없는 입력으로 처리하는 규칙이 승인돼 있다면 원문 비교와 정규화 비교를 함께 둘 수 있습니다. 원문 변경·정규화 동일이라는 두 상태를 남겨 실제 문자가 바뀌었다는 사실은 보존합니다.
새 규칙을 양쪽 파일에 같은 방식으로 적용합니다. 오늘 파일에서만 공백을 지우면 비교가 비대칭이 됩니다. 대소문자, 줄바꿈, 날짜표현도 같은 원칙입니다. 업무 내용에서 공백이 의미 있는 경우에는 정규화하지 않습니다. 메모나 계약 문장을 보기 좋게 고치는 작업을 스냅샷 비교 전처리로 끼워 넣지 않습니다.
정규화 결과는 원문을 대신하는 새 원장이 아니라 비교용 보조 열입니다. 문제가 생기면 보조 열과 비교표만 다시 만들 수 있도록 원본 사본은 그대로 둡니다. 표를 깔끔하게 만들기 위해 원본에서 중복 행을 삭제하는 방식도 피합니다.
추가·삭제 후보를 조사할 때 필요한 질문
추가 후보는 새로 생성된 업무인지, 어제 파일의 필터에서 빠졌던 업무인지, ID가 변경된 같은 업무인지 확인합니다. 삭제 후보는 실제 삭제·보관 이동·완료 필터 제외·권한 변경으로 인한 미노출 중 무엇인지 확인합니다. 후보 목록의 행 수만으로 “업무 몇 건이 삭제됐다”고 확정하지 않습니다.
담당자가 삭제를 확인했다면 변경 시각, 실행 주체, 사유, 연결 근거를 남깁니다. 삭제가 승인되지 않았거나 원본 시스템에 문제가 있으면 복원 절차 담당자에게 넘깁니다. 비교표의 과거 값을 현재 원장에 그대로 복사하는 것은 상태를 되돌리는 별도 변경이므로 이 읽기 비교와 분리해야 합니다.
비교 결과를 원복 가능한 자료로 전달하기
어제 원본, 오늘 원본, 키 목록, 비교 규칙, 변경 결과를 한 작업 폴더에 보관하고 파일 버전을 적습니다. 각 결과 행은 양쪽 원본의 행 ID 또는 원문 위치와 연결합니다. 비교 범위나 정규화 규칙이 잘못됐으면 같은 사본으로 다시 계산하고 이전 결과가 왜 바뀌었는지 설명할 수 있어야 합니다.
최종 요약에는 비교 대상 키 수, 보류 키 수, 추가·삭제 후보 수, 변경 열별 건수를 적습니다. 한 업무가 담당과 상태 모두 바뀌면 변경 업무 1건이면서 변경 열 2개입니다. 두 숫자를 혼동해 변경 건수를 두 배로 세지 않습니다. 샘플 T-04가 이 구분을 확인하기 위한 행입니다.
마지막으로 오늘 파일의 정렬을 바꿔도 판정이 유지되는지, T-01을 두 번 넣으면 중복 보류가 되는지, T-03의 상태를 어제와 같게 되돌리면 동일로 바뀌는지 확인합니다. 이 글의 범위는 두 사본의 대응과 값 차이이며 원본 시스템의 모든 변경 이력이나 사용자 행동을 감사한 결과는 아닙니다.
건수와 바뀐 열 수를 다시 대조하기
8키 예제의 속성 변경은T-02·T-03·T-04·T-08의 4건입니다. 바뀐 열 수는 담당 1, 상태 1, 담당·상태 2, 담당 1을 합해 5개입니다. 추가·삭제 후보와 중복 보류는 이 열 변경 합계에 넣지 않습니다. 두 숫자를 분리하면 어느 표를 수정할지와 어느 업무를 다시 확인할지가 함께 보입니다.
오늘 사본이 전체 목록이라는 확인 없이 삭제 후보T-06을 원장에서 삭제하는 작업은 수행하지 않습니다. 먼저 원본 시스템에서T-06을 ID로 조회하고 파일 내보내기의 상태 필터·권한·보관 범위를 확인합니다. 원장에 여전히 존재하면 두 사본의 범위 차이로 기록하고 비교 규칙을 맞춘 새 사본을 받습니다. 비교표에 없는 행이 곧 원장에도 없다는 가정은 피합니다.
업무 ID 자체가 변경됐다면T-05와T-06이 사실 같은 업무의 새·옛 ID일 수도 있습니다. 이 경우에는 담당자의 공식 대응 관계를 받은 뒤 원문 ID와 대응 ID를 나눠 비교합니다. 값이 비슷하다는 이유로 자동으로 같은 업무로 붙이지 않습니다. ID 변경을 확인한 근거와 적용일을 남기면 기존 결과에서 왜 추가·삭제 후보가 사라졌는지도 설명할 수 있습니다.
원문에서 확인할 범위
- PostgreSQL 18: Unique constraints·Primary keys — 여러 열 조합의 고유성과 기본키의 빈값 배제를 설명하는 개념 참고. 이 작업표가 데이터베이스 제약을 자동 수행한다는 뜻은 아님.
- Google Sheets EXACT — 대소문자·공백·숨겨진 문자까지 포함한 문자열 일치.