프로그래밍백엔드 개발자

SQL에서 데이터베이스 스키마 버전 관리(software version control of database schema)에 대한 접근 방식을 설명하십시오. 어떤 도구와 관행이 사용되며, 이것이 프로젝트 지원 및 발전에 어떤 영향을 미칩니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

문제의 역사
대규모 프로젝트를 진행하는 것은 데이터베이스 구조가 애플리케이션 코드와 함께 발전해야 한다는 것을 요구합니다. 스키마 변경(테이블, 인덱스, 키 추가, 삭제 및 변경)에 대한 소프트웨어 버전 관리가 없으면 팀은 신속하게 동기화를 잃게 되고, 변경 사항 손실, 마이그레이션 실패 및 버그 롤백 또는 재현이 복잡해질 위험이 증가합니다.

문제
전통적인 접근 방식인 SQL 스크립트를 통한 수동 데이터베이스 변경은 변경 사항 실행 순서가 명확하지 않고, 롤백이 복잡하며, 환경(dev, test, prod) 간 버전 불일치로 이어집니다. 마이그레이션을 저장할 수 있는 공통 도구가 없으면 누가, 언제, 왜 스키마를 변경했는지 이해하기 어렵습니다.

해결책
이 문제를 해결하기 위해 스키마 마이그레이션 시스템과 데이터베이스 버전 관리 관행이 사용됩니다. 도구(예: Liquibase, Flyway, Alembic 등 다양한 DBMS용)는 SQL 스크립트 변경 사항을 버전 관리 시스템(git)에서 직접 저장하고, 엄격한 마이그레이션 순서를 형성하며, 모든 환경에서 스키마 업데이트를 자동화할 수 있게 합니다.

코드 예제(플라이웨이를 통한 마이그레이션):

-- V002__add_column_email.sql ALTER TABLE users ADD COLUMN email VARCHAR(255) NOT NULL;

플라이웨이 통합(예: Java):

Flyway.configure().dataSource(url, user, pass).load().migrate();

주요 특징:

  • 모든 개발자가 동일한 변경 사항의 순서를 "보아" 적용할 수 있습니다.
  • 스키마의 모든 버전을 쉽게 "롤백"하거나 복원할 수 있습니다.
  • 스키마 변경 사항의 모든 기록이 투명하며 비즈니스 논리와 함께 리뷰할 수 있습니다.

함정 질문.

스키마의 "원래 상태"(snapshot)를 마이그레이션 대신 저장할 수 있습니까? 첫눈에는 전체 스키마 덤프가 마이그레이션보다 간단해 보입니다. 그러나 그러면 롤백, 중간 상태 복원 및 다양한 브랜치에서의 변경 사항 병합에 문제가 발생할 것입니다. 마이그레이션은 필요한 순서대로 새로운 변경 사항을 연속적으로 적용할 수 있게 해줍니다.

다른 환경 간의 마이그레이션을 수동으로 동기화해야 합니까? 아니요, 현대 시스템은 버전 관리를 존중하며, 데이터베이스에 없었던 마이그레이션만 자동으로 적용합니다. 가장 중요한 것은 수동 동기화가 아니라 배포 시 자동화된 마이그레이션 적용입니다.

SQL 스크립트 마이그레이션만으로 충분합니까, 아니면 다른 것을 저장해야 합니까? SQL 스크립트 외에 작성 목적, 저자, 날짜 및 새로운 구조 변경에 대한 유효성 검사 테스트를 저장하는 것이 좋은 관행입니다. 이렇게 하면 마이그레이션 품질 관리가 자동화됩니다.

일반적인 오류 및 안티 패턴

  • 마이그레이션 없이 "수동" 변경 적용: 환경 불일치로 이어진다.
  • 기존 마이그레이션을 "역사적 후퇴"로 수정하는 것: 역사 손상 및 비가역적 작업을 초래할 수 있다.
  • 되돌리기 가능한 (down) 마이그레이션을 무시합니다.

실생활 사례

부정적인 사례

프로젝트는 일반적인 스키마 덤프와 개발자들에 의한 "수동" 변화를 사용했습니다. 업데이트를 시작한 후 고객은 일부 새로운 열이 프로덕션 데이터베이스에 나타나지 않았고, 일부 인덱스가 각 스키마 업데이트 시마다 두 배가 되었다고 지적했습니다.

장점:
아주 작은 프로젝트의 경우 신속합니다.

단점:
유지보수의 어려움; 무엇이 변했는지와 누가 변경했는지 이해할 수 없음; 롤백 불가능; 다양한 환경이 다르게 된다.

긍정적인 사례

팀은 Flyway를 통합했으며, 모든 구조적 변경은 코드 리뷰와 함께 마이그레이션으로 이루어져 롤백은 몇 분이 걸리며, 모든 환경에서 테스트 및 검증이 쉽게 이루어졌습니다.

장점:
자동화, 역사, 배포 시 버그 가능성이 낮음.

단점:
구조 변경 사항을 문서화하는 데 다소 긴 시간이 필요합니다.