인계받은 시스템에 DB 문서가 없었다. 테이블이 140개였다.
Table of contents
Open Table of contents
상황 — 문서가 없었다
DESC 로 표를 하나씩 볼 수는 있었다.
tb_enroll
enr_no int
st_no int
cs_no int
st_cd char(2)
reg_dt datetime
st_no 와 st_cd 가 무엇인지 몰랐다.
st_no 와 st_cd 가 접두사는 같은데 하나는 번호고 하나는 코드였다. 컬럼 이름만으로는 무엇을 담는 자리인지 알 수 없는 것이 대부분이었다.
검증 — 코드에서 찾았다
tb_enroll 을 다루는 코드를 grep 으로 찾았다.
$enroll = [
'st_no' => $student->no,
'cs_no' => $course->no,
'st_cd' => 'AP', // 승인 대기
];
st_no 는 수강생 번호이고 st_cd 는 상태 코드였다.
$student->no 와 'AP' 가 각각 다른 성격이었다. 값의 종류도 모아 봤다.
$ grep -rn "st_cd" --include=*.php app/ | grep -o "'[A-Z]\{2\}'" | sort -u
'AP'
'CF'
'CN'
'DN'
AP 와 CF 와 CN 과 DN 이 나왔고 문맥에서 뜻을 찾았다.
대응 — 화면에서 찾은 실제 뜻
코드로 안 나오는 것은 화면 쪽 statusLabel 에서 봤다.
$statusLabel = ['AP' => '승인대기', 'CF' => '수강중', 'CN' => '취소', 'DN' => '수료'];
DN 은 완료가 아니라 수료였다.
코드만 보면 짐작이고 화면을 봐야 실제 뜻이 나온다. 화면에도 안 나오는 컬럼은 모르는 것으로 적어 뒀는데 억지로 짐작해 적으면 그것이 나중에 잘못된 근거가 된다.
전체 흐름 — 관계 찾기와 확인
외래키가 하나도 없어서 관계가 안 보였다.
$ grep -rnE "join .*tb_[a-z_]+ .* on" --include=*.php app/ | grep -oE "on [a-z_.]+ *= *[a-z_.]+" | sort -u
조인 조건을 모으니 관계가 그려졌다.
tb_enroll.st_no = tb_student.st_no
tb_enroll.cs_no = tb_course.cs_no
tb_course.ct_no = tb_category.ct_no
코드에서 JOIN 하는 것이 실제 관계이고 문서에 있을 관계보다 정확하다.
찾은 관계가 맞는지 데이터로 확인했다.
SELECT COUNT(*) FROM tb_enroll e
LEFT JOIN tb_student s ON e.st_no = s.st_no
WHERE s.st_no IS NULL;
412
tb_student 에 대응이 없는 것이 412건 남아 있었다.
관계는 맞는데 데이터가 깨져 있는 것이었다. 지워진 수강생의 수강 기록이 남은 것이라 그 사실까지 문서에 함께 적었다.
결과 — 문서로 만든 것
그려 낸 것을 표 하나로 정리했다.
[tb_enroll] 수강 신청
enr_no int 수강신청 번호 PK, 자동 증가
st_no int 수강생 번호 → tb_student.st_no (FK 없음)
cs_no int 과정 번호 → tb_course.cs_no (FK 없음)
st_cd char(2) 상태 AP/CF/CN/DN
reg_dt datetime 신청일시
상태 코드
AP 승인대기 / CF 수강중 / CN 취소 / DN 수료
주의
외래키가 없어 대응하지 않는 st_no 가 412건 있다 (2019-06 기준)
st_no 와 st_cd 는 접두사가 같지만 다른 것을 가리킨다
주의 항목이 가장 쓸모 있었다.
컬럼 이름과 타입은 DESC 로 바로 볼 수 있지만 이런 것은 조사하지 않으면 안 나온다. 다음 사람이 같은 데서 헷갈리지 않게 하는 것이 그 항목이었다.
판단 기준 — 그리는 순서
tb_ 로 시작하는 140개를 다 그리는 데는 오래 걸린다.
1. 자주 건드리는 것 (코드에서 참조 횟수)
2. 관계의 중심에 있는 것 (조인에 자주 나오는 것)
3. 나머지
참조 횟수는 grep 으로 세어서 정했다.
$ grep -rohE "tb_[a-z_]+" --include=*.php app/ | sort | uniq -c | sort -rn | head -20
상위 20개가 참조의 대부분이라 그것부터 그렸다.
두 달에 걸쳐 60개를 그렸고 나머지는 필요해질 때 그리기로 미뤘다. 전부 하려고 들면 끝나기 전에 앞부분이 이미 낡는다.
정리
- 문서가 없으면 코드에서 거꾸로 그린다
- 컬럼 이름만으로는 모르고 코드에서 무엇을 넣는지 본다
- 코드로도 모르면 화면에 보이는 이름을 본다
- 화면에 보이는 이름이 실제 뜻이다
- 모르는 것은 모른다고 적는다
- 외래키가 없으면 조인 조건을 모아 관계를 찾는다
- 찾은 관계를 데이터로 확인하고 안 맞는 건수도 적는다
- 표만이 아니라 주의 사항을 적는다
- 전부 그리지 않고 자주 쓰는 것부터 한다