ABOUT ME

Today
Yesterday
Total
  • 실무에서 변경된 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)**을 정의할 때 사용하는 구문입니다.

     

    https://velog.io/@kylexid/Github-Action%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-MySQL-DB-Migration-%EC%9E%90%EB%8F%99%ED%99%94

     

Designed by Tistory.