MySQL 에 있던 기존 자료 1,200건을 새 테이블로 옮겼다. 옮기고 나서 이걸 어떻게 고치느냐는 말을 들었다.
Table of contents
Open Table of contents
넣는 것만 만들었다
옮기는 것은 INSERT ... SELECT 한 줄이었다. 돌리고 건수를 확인한 뒤 끝냈다. 이 테이블을 보는 JSP 는 있었지만 고치는 화면은 안 만들었다. 옮긴 자료 중에 틀린 것이 있어도 손댈 방법이 없는 상태였다.
매번 내가 불렸다
상품 이름을 고쳐 달라는 요청이 들어왔다. 한 번은 UPDATE 한 줄이라 금방인데 이게 하루에 몇 번씩 왔다. 일주일에 서른 번쯤 됐고 그때마다 하던 일을 멈췄다.
들어온 요청을 종류별로 적어 봤다.
이름 고치기 14건
가격 고치기 8건
분류 바꾸기 5건
숨기기 3건
지우기 2건
이름과 가격이 대부분이라 전부 만들 필요는 없었다. 그 둘만 고치는 화면을 Spring Controller 하나와 JSP 하나로 먼저 만드니 요청의 70퍼센트가 없어졌다. 무엇이 실제로 필요한지는 요청을 적어 보니 나왔다.
옮기는 일에 딸려 오는 것
자료를 옮기면 그것으로 끝이 아니었다. 넣는 것 말고도 보고, 고치고, 지우거나 숨기고, 틀렸을 때 되돌리는 것이 딸려 온다.
나는 넣는 것만 했고 보는 것은 원래 있었다. 나머지 셋이 없었다. 다음부터는 옮기기 전에 이 다섯 개가 있는지 확인하기로 했다. 없는 것이 있으면 옮기고 나서 무엇을 하게 될지 미리 안다.
옮기기 전 자료는 지우지 않고 뒀다. 나중에 이름이 잘린 건이 나왔을 때 원본과 맞대어 볼 수 있었다. 컬럼 길이가 달라서 잘린 것이었는데 오류 없이 조용히 잘렸다.
찾아보니 MySQL 이 그렇게 동작하는 이유가 있었다. sql_mode 가 비어 있으면 긴 값을 넣어도 실패하지 않고 잘라서 넣는다. SHOW WARNINGS 를 치면 그때 1265 Data truncated for column 이 나와 있다. sql_mode 에 STRICT_TRANS_TABLES 를 넣으면 그 자리에서 1406 Data too long for column 으로 막힌다.
스크립트가 경고를 안 읽고 넘어갔으니 나는 몰랐던 것이다.
건수가 같아도 내용은 달랐다
옮기고 나서 건수만 세고 넘어갈 뻔했다. 양쪽 다 1,200건이라 맞아 보였다.
LEFT JOIN 으로 옛 테이블과 새 테이블을 이어 붙여 값을 맞대어 보니 17건이 달랐다. 건수가 같은 것과 내용이 같은 것은 다르다. 옮긴 개수는 옮기는 일이 일어났다는 것일 뿐 옳게 옮겨졌다는 뜻이 아니었다.
읽는 자리를 전부 옮겼는지도 봐야 했다. 목록 화면은 새 테이블을 보는데 통계 배치가 옛 테이블을 보고 있었다. 새로 들어온 상품이 통계에 안 잡혔다. iBatis 의 SQL 은 XML 에 모여 있어서 옛 테이블 이름으로 grep 하니 남은 자리가 다 나왔다. 테이블을 옮길 때는 그 이름이 나오는 자리를 전부 찾아 같이 옮겨야 한다.
정리
- 자료를 넣는 것만 만들면 고칠 방법이 없어서 매번 사람이 불린다
- 들어온 요청을 적어 보면 무엇을 먼저 만들지 나온다
- 전부 만들 필요는 없다. 대부분을 차지하는 것부터 만든다
- 옮기는 일에는 넣기와 보기와 고치기와 지우기와 되돌리기가 딸려 온다
- 옮기기 전에 그 다섯이 있는지 확인한다
- 원본을 지우지 않는다. 틀린 것이 나왔을 때 볼 자리가 있어야 한다
- 컬럼 길이가 다르면 MySQL 이 오류 없이 잘라서 넣는다.
SHOW WARNINGS에만 남는다 - 잘리는 것을 막으려면
sql_mode에STRICT_TRANS_TABLES를 넣는다 - 건수가 같은 것과 내용이 같은 것은 다르다. 값을 맞대어 비교한다
- 테이블을 옮기면 그 이름이 나오는 자리를 전부 찾아 같이 옮긴다