-
실무에서 변경된 DDL 관리하기 (Skeema - MySQL 스키마 관리 툴)회사/솔루션기업 2025. 3. 14. 00:38
실무에서는 DDL 이 변경되는 일이 잦다.
이전 회사에서는 ERD 없이 DDL 로만 관리를 해서 아무래도 시각적으로 데이터베이스 구조를 나타내는 툴을 따로 사용하지 않았었다.
그것도 그만의 단점이 있었지만, 방대한 솔루션은 아니었기에 굳이 필요하지 않았던 것 같다.
그래서 DDL 관리와 DDL 변경사항을 자동으로 출력 or 실행해주는 repo 를 따로 관리하고 있었다.
하지만 현재 이직한 회사는 오직 EXERD 를 사용하고 있으며 따로 DDL 을 관리하지는 않는다.
[현재 회사에서 발생하는 관리포인트 문제]
모듈별로 erd 를 관리하므로 EXERD 가 무조건 필요한 곳이다.
너무 많은 database 를 사용한다 (회사 특성 상 posgresql, mysql, oracle db, mssql, ...등등 납품하는 다양한 기업의 데이터베이스 스키마를 쓴다.
oracle 도 영업용, 데모용, 품질서버 등으로 나뉘어 사용하는 db 가 총 최소 8개다.
모든 개발자가 절대 어떤 DB 도 놓치지 못한다는 보장이 있을까?
우선 diff 를 사용해서 DDL 을 별도로 관리하면, ERD 파일 수정 + DDL 커밋 = 이중작업이 될 수 있다는 단점은 있다.
주먹구구식으로 변경된 DDL 은 오직 해당 컬럼을 추가한 본인과 그 팀 정도만 알고 있다.
[문제상황 상세설명]
협업 개발자가 ddl 수정
> 다양한 협업자들이 테이블을 변경하기 때문에 나는 어떤 테이블이 추가되고 어떤 컬럼이 추가된 지 수정사항을 알 수 없음.
> 테이블이 최신화 되지 않아 오류가 나면 트래킹 하느라 시간을 허비하는 문제 발생
[해결방법]
1. 수정된 DDL 을 repo 에서 관리. sql 파일 명은 테이블명으로 하고, 테이블별로 쪼개는 것이 좋다.
2. 해당 repo 소스를 최신화 하고, 오류가 나는 DB 접속 URL 을 parameter 로 주고 diff 를 실행한다.
3. 현재 repo 의 최신 DDL 과 실제 DB를 비교해서 어떤 게 수정됐는 지 출력하거나 실행하는 스크립트를 작성한다.
😀유닉스 실행파일이다. description 에는 '😀' 를 사용할 것이다.
########### IMAGE_NAME = skeema → 사용할 Docker 이미지 이름을 skeema로 지정 IMAGE_NAME="skeema" ########### 현재 운영체제를 가져옴 (Linux, Darwin(macOS) 등) OS=$(uname -s) ########### docker images -q $IMAGE_NAME → skeema라는 이미지가 있는지 확인 if [ ! "$(docker images -q $IMAGE_NAME 2> /dev/null)" ]; then ########### 없으면 docker build 명령어를 실행하여 skeema Docker 이미지를 빌드 echo "Build ${IMAGE_NAME} image" ########### --platform linux/amd64 → Linux x86_64 아키텍처용으로 빌드 (Mac M1/M2 호환 고려) ########### Docker 컨테이너가 로컬 머신의 MySQL 서버에 접근할 수 있도록 하기 위해 docker build -t $IMAGE_NAME . --platform linux/amd64 fi # Mac OS인 경우 if [ "$OS" = "Darwin" ] && [ "$MYSQL_HOST" = "127.0.0.1" ]; then # host.docker.internal을 사용하여 local MySQL에 접근 MYSQL_HOST="host.docker.internal" fi ########### docker run → 새로운 컨테이너 실행 ########### 옵션 --rm → 컨테이너 종료 시 자동 삭제 ########### 옵션 -i → 상호작용(interactive) 모드 ########### 현재 디렉토리의 schema/를 컨테이너의 /skeema/schema로 마운트 ########### MySQL DDL 파일이 포함된 schema/ 디렉토리를 컨테이너 내부에서 사용하도록 설정 ########### MySQL 접속 환경 변수 전달 docker run -v $(pwd)/schema:/skeema/schema -i --rm --platform linux/amd64 \ -e MYSQL_HOST=${MYSQL_HOST} \ -e MYSQL_USER=${MYSQL_USER} \ -e MYSQL_PASSWORD=${MYSQL_PASSWORD} \ -e MYSQL_SCHEMA=${MYSQL_SCHEMA} \ ########### --network host → 컨테이너가 호스트와 같은 네트워크를 사용하도록 설정 (이를 통해 컨테이너에서 로컬 MySQL 서버에 직접 접근 가능) --network host \ ########### $IMAGE_NAME "$@" → skeema Docker 이미지 내부에서 사용자가 입력한 명령어 실행 ("$@"는 스크립트 실행 시 입력한 모든 인자를 그대로 전달) $IMAGE_NAME "$@"
[참고]
## 참고 ! Shell Script 문법 if와 fi는 **Shell Script(Bash 등)**에서 **조건문(if statement)**을 정의할 때 사용하는 구문입니다.