그룹웨어 연동의 부서 코드 관련 문의가 왔다. 이름이 딱 맞는 테이블이 있었다.
SELECT * FROM hr_api_departments WHERE company IN ('company_a', 'company_b');
Table of contents
Open Table of contents
증상 — 값이 이상했다
hr_api_departments 에서 나온 데이터를 봤다.
등록일 전부 2016~2017년
코드 전부 D0001
부서가 여럿인데 D0001 하나뿐이고 최근 등록이 없었다.
[정상] 부서마다 다른 코드, 계속 추가됨
[실제] 한 코드, 수년째 그대로
등록일 로 보나 코드 값으로 보나 이미 낡은 데이터였다.
그런데 이대로 답하고 넘어갈 수도 있는 상황이었다. 테이블 이름이 맞고 회사도 맞고 데이터도 있으니 세 조건이 다 맞아 그럴듯해 보인다. 데이터만 보고 답하는 것 대신 코드로 확인하는 쪽을 골랐다. 이유는 값이 전부 같고 오래됐다는 것만으로는 낡은 것인지 원래 안 바뀌는 것인지 안 갈려서다.
검증 — 브로커를 추적했다
확인차 이 값을 실제로 어디서 읽는지 봤다.
// GroupwareBroker.php
public function deptInformations()
{
// 조회하는 테이블
}
deptInformations 가 보는 곳이 다른 테이블이었다.
groupware_dept_informations
전용 테이블이 따로 있었다.
결과 — 전용 테이블이 활성
groupware_dept_informations 를 조회했다.
SELECT org_id, dept_id, company, dept_code, cost_center_code
FROM groupware_dept_informations WHERE org_id = ?;
company_a dept_code 5~6자리 cost_center_code 4~6자리
company_b (같은 코드)
company_c (같은 코드)
groupware_dept_informations 쪽이 활성 입력처였다.
여기서 구조도 하나 보였는데 계열사들이 동일 코드를 공유하고 있었다. 같은 그룹의 회사라 코드 체계가 같아서 한 회사에서 확인하면 나머지도 안다.
원인 — 두 테이블의 관계
hr_api_departments 와 groupware_dept_informations 를 나란히 놓았다.
[공용 테이블] 이름이 일반적. 예전에 쓰다 멈춤. 낡음
[전용 테이블] 이름이 구체적. 현재 활성
공용이 먼저 생기고 나중에 전용이 생겼는데 공용 쪽을 안 지운 것이다.
여기서는 이름 자체가 함정이었는데 hr_api_departments 는 일반적이라 정본처럼 보이고 groupware_dept_informations 는 특수한 것처럼 보인다. 그런데 실제로 살아 있는 쪽은 구체적인 이름을 가진 쪽이었다.
판단 기준 — 어느 쪽이 산 것인가
이런 상황의 판별법을 정리했다.
[데이터로] 최근 등록이 있나, 값이 다양한가
[코드로] 실제로 조회하는 쪽이 어디인가 ← 확실
데이터만으로는 애매한데 애초에 안 바뀌는 성격의 데이터일 수도 있다.
그래서 규칙으로 하나 적어 뒀는데 부서 코드를 조사할 때 공용 테이블만 보면 낡은 데이터를 최신으로 오판하기 쉬우므로 반드시 전용 테이블을 조회한다.
주의 — NULL과 미사용 컬럼
groupware_dept_informations 에도 빈 값이 많았다.
SELECT COUNT(*), COUNT(dept_code) FROM groupware_dept_informations;
dept_code 가 비어 있는 행이 전체의 상당수를 차지했다.
값 있음 입력 완료
NULL 미입력
입력 완료 여부를 이 컬럼으로 판단하고 있었다.
아예 안 쓰는 컬럼도 있었다.
SELECT large_org_code, middle_org_code, small_org_code FROM ...;
"0", 빈 문자열, NULL
조직 코드 셋은 대부분 이 모양이라 실질 미사용이었다.
스키마에는 남아 있지만 실제로는 아무도 그 컬럼을 안 채우고 있었다. 비어 있는 것과 안 쓰는 것은 다르므로 그것부터 갈라야 했다.
정리
- 이름이 일반적인 테이블이 정본처럼 보인다
- 이름의 일반성과 활성 여부는 무관하다
- 값이 전부 같고 오래됐으면 낡은 데이터를 의심한다
- 활성 입력처는 코드로 확인한다
- 데이터만으로는 애매하다
- 전용 테이블이 따로 있을 수 있다
- 공용은 안 지워진 채 남는다
- 계열사가 동일 값을 공유할 수 있다
- 빈 값이 미입력을 뜻하면 그것으로 완료 여부를 판단한다
- 스키마에 있어도 실질 미사용 컬럼이 있다