
개발을 하다보면, 넣어 놓은 dump data로 테스트를 진행한다. 이 때, `ddl-auto: create`로 설정해 다 날리곤 했다.
보통 `create`와 `update`만을 사용했는데, 다른 옵션은 어떤 것들이 있는지 궁금해졌다.
ddl-auto란?
`ddl-auto` 옵션은 스프링 부트 애플리케이션에서 Hibernate와 같은 JPA 구현체를 사용할 때 데이터베이스 스키마 관리를 제어하는 설정이다. 이 옵션은 `application.properties` 또는 `application.yml` 파일에서 설정하며, 각 옵션 값에 따라 데이터 베이스 스키마에 대해 다른 동작을 수행한다.
`ddl-auto` 옵션에는 `none`, `validate`, `update`, `create`, `create-drop`이 있다.
none
`none`은 데이터베이스 스키마와 관련된 어떠한 작업도 수행하지 않는다. 이는 데이터베이스 스키마를 수동으로 관리하고 싶을 때, 유용하며 프로덕션 환경에서 주로 사용한다. 데이터베이스 스키마는 DBA나 마이그레이션 도구(Flyway, Liquibase 등)를 통해 별도로 관리한다.
validate
`validate`는 애플리케이션이 시작될 때, 엔티티 매핑이 데이터베이스 스키마와 일치하는지 검증하며 스키마 변경은 따로 수행하지 않는다. 프로덕션 환경에서 엔티티와 데이터베이스 스키마가 일치하는지 확인하고 싶을 때 사용한다.
동작 방식
- 어노테이션과 XML설정을 통해 모든 엔티티 클래스의 메타데이터를 조회
- JDBC 메타데이터 API를 사용해 데이터베이스 스키마 정보 조회
- 엔티티 메타데이터와 데이터베이스 메타데이터를 비교
- 엔티티에 매핑된 테이블의 존재 여부
- 필드에 매핑된 컬럼의 존재 여부
- 컬럼 데이터 타입의 호환성
- 기본 키 구성의 일치 여부
- 외래 키 관계의 일치 여부
- 불일치 시 어플리케이션을 중단하고 오류 메세지를 로그에 기록
- 일치 시 어플리케이션을 정상적으로 시작하고 스키마 변경은 수행하지 않음
⚠️ `validate`는 스키마의 모든 세부사항을 검증하지 않고, Hibernate가 실제로 사용하는 부분만 확인한다. 사용하지 않는 테이블의 불일치는 오류로 간주하지 않는다.
update
`update`는 엔티티 매핑과 데이터베이스 스키마를 비교하여 필요한 경우 스키마를 업데이트한다. 기존 데이터는 유지되지만, 새로운 엔티티나 변경된 엔티티 필드는 스키마에 반영된다. 해당 옵션은 엔티티에 변경이 발생할 때 자동으로 스키마를 업데이트하고 싶을 때 유용하다. 프로덕션 환경에서는 예기치 않은 스키마 변경을 방지하기 위해 주의가 필요하다.
동작 방식
- 어노테이션과 XML설정을 통해 모든 엔티티 클래스의 메타데이터를 조회
- JDBC 메타데이터 API를 사용해 데이터베이스 스키마 정보 조회
- 엔티티 메타데이터와 데이터베이스 메타데이터를 비교하고 업데이트
- 누락된 테이블 생성
- 누락된 컬럼 추가
- 컬럼 타입 변경
- 제약조건 추가
- 기존 데이블의 데이터는 유지, 컬럼 이름이 변경된 경우 새 컬럼이 추가되고 기존 데이터는 유지
⚠️ update는 사용하지 않는 테이블을 자동으로 삭제하지 않고, 엔티티에서 제거된 필드에 해당하는 컬럼을 삭제하지 않는다.
create
`create`는 애플리케이션이 시작될 때 기존 스키마를 삭제하고 새로 생성한다. 데이터가 모두 삭제되며 엔티티 매핑을 기반으로 새로운 스키마가 생성된다. 개발 초기에 빈 데이터베이스 스키마를 반복적으로 생성해야 할 때 유용하다. 기존 데이터가 모두 삭제되므로 프로덕션 환경에서는 사용되지 않는다.
동작 방식
- 기존 테이블을 DROP
- 엔티티 매핑을 분석해 DDL 스크립트를 생성
- 생성된 DDL을 실행해 새로운 스키마 생성
- 애플리케이션이 종료되어도 스키마는 그대로 유지
create-drop
`create-drop`은 `create`와 유사하지만, 애플리케이션이 종료될 때 스키마를 삭제한다는 점이 다르다. 해당 옵션은 테스트 환경에서 일시적인 데이터 스키마가 필요한 경우 유용하며, 매 테스트 실행 시마다 깨끗한 데이터베이스 상태를 유지하고자 할 때 사용한다. 프로덕션 환경에서는 사용하지 않는다.
동작 방식
- 기존 테이블을 DROP
- 엔티티 매핑을 분석해 DDL 스크립트를 생성
- 생성된 DDL을 실행해 새로운 스키마 생성
- 애플리케이션이 정상적으로 종료되면 생성한 스키마를 다시 삭제 ➡️ 애플리케이션 생명주기 전체에서만 스키마가 존재
`create-drop`은 주로 자동화된 테스트에서 테스트 간 격리를 위해 사용한다. 또, 단위 테스트나 통합 테스트에서 매 테스트마다 깨끗한 상태를 유지할 수 있다.
사용 단계
- 초기 개발 단계 or 로컬 테스트: `create` or `update`
`create`를 통해 항상 깨끗한 상태에서 시작해 스키마 변경 충돌이 없고, 엔티티 모델이 자주 변경되는 초기 개발에 적합하다. 어느 정도 틀이 정해져, 기존 테이블을 유지하면서 필요한 변경사항만 적용하고 싶다면 `update`로 스키마를 업데이트하면 된다. - 테스트 서버: `update` or `validate`
테스트 중 엔티티 변경사항을 스카마에 반영하고 싶다면 `update`를 사용하자. 엔티티와 스키마의 일치성만 확인하고 싶다면 'validate'를 사용해 확인할 수 있다. - 스테이징 및 운영 서버: `validate` or `none`
`validate`를 통해 코드와 스키마의 일치성을 확인하고 `none`으로 자동 스키마 변경을 방지해 데이터베이스 변경을 통제된 프로세스를 통해서만 이뤄지도록 한다.
💡 프로덕션 환경에서 스키마 변경은 어떻게 할까?
스키마 변경이 필요할 때는 적절한 데이터베이스 마이그레이션 도구(Flyway, Liquibase 등)를 사용하여 제어된 방식으로 스키마를 관리하거나, 사용자가 없는 새벽에 스키마 변경 작업을 수동으로 진행하는 것이 더욱 안전할 수 있다.
'Spring > Spring Data JPA' 카테고리의 다른 글
| [Spring Data JPA] ID에 관하여 (2) | 2025.03.13 |
|---|---|
| [Spring Data JPA] JPA의 N + 1 문제 (0) | 2025.03.07 |
| [Spring Data JPA] 엔티티 매니저(Entity Manager) (0) | 2025.03.05 |
| [Spring Data JPA] 영속성 컨텍스트(Persistence Context) (0) | 2025.03.04 |
| [Spring Data JPA] 새로운 Entity인지 판단하기 (0) | 2025.02.27 |