IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  자바 | 오픈 소스  >

사람을 위한 자동화: 손 쉬운 데이터베이스 마이그레이션

LiquiBase를 사용하여 데이터베이스 변경 관리하기

developerWorks
문서 옵션

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

영어원문

영어원문


제안 및 의견
피드백

난이도 : 초급

Paul Duvall, CTO, Stelligent Incorporated

옮긴이: 백기선 dwkorea@kr.ibm.com

2008 년 11 월 18 일

데이터베이스는 종종 그것을 기반으로 하는 애플리케이션과 어긋난 상태로 존재하는데, 이로 인해 데이터베이스와 데이터를 안정된 상태로 끌어내는 것은 관리에 있어서 상당한 도전 과제가 됩니다. 사람을 위한 자동화 이번 기사에서는, 자동화 전문가 Paul Duvall이 오픈 소스 LiquiBase 데이터베이스-마이그레이션 도구를 사용하여 데이터베이스와 애플리케이션의 변경 사항을 관리할 때 발생하는 고통을 줄이는 방법을 보여줄 것입니다.

수년간 내가 일했던 애플리케이션들은 대부분 다량의 데이터를 관리해야 하는 엔터프라이즈 애플리케이션이었다. 그런 프로젝트에서 일하는 개발 팀은 보통 데이터베이스를 애플리케이션과는 완전히 별개의 것으로 취급한다. 이는 때때로 데이터베이스 팀과 애플리케이션 개발 팀으로 나뉘어 있기 때문이거나, 단순하게 팀이 그런 식으로 일을 하기 때문일 것이다. 두 방법 모두 다음과 같은 결과를 초래할 수 있다.

  • 데이터베이스에 변경 사항 직접 반영하기
  • 데이터베이스 변경 사항을 다른 팀원과 공유하지 않기
  • 일관되지 않은 방법으로 데이터베이스나 데이터 변경 적용하기
  • 데이터베이스 버전을 다음 버전으로 변경하는 관리를 비효율적으로 손수 다루기

개발자들이 데이터 변경 사항을 제대로 인지하지 못한 상태로 두는 비효율적인 상황이 발생한다. 게다가, 그들은 애플리케이션 사용자가 데이터 불일치나 충돌 문제를 경험하게 할 수도 있다.

그림 1은 소프트웨어 개발 프로젝트에서 흔히 사용하는 데이터베이스에 직접 변경을 가하는 방법을 보여준다. 직접 데이터를 변경하는 방법은 불안하고 에러가 발생할 여지가 많다, 그리고 방금 한 것을 되돌리는 걸 어렵게 하며 시간 흐름에 따라 데이터베이스에 어떤 변화가 있었는지 그 히스토리를 분석하는 것도 힘들다. 예를 들어, DBA가 한 건의 조회 데이터를 변경해야 한다는 것을 기억하고 있을지 모른다. 하지만 한 개발자가 나중에 이 데이터를 같은 테이블에 넣어야 한다는 것을 깜빡할 수도 있다.

본 연재에 대하여

개발자로서 우리는 고객의 프로세스를 자동화하기 위해 일한다. 하지만 우리 중 대부분은 우리 스스로의 개발 프로세스를 자동화할 수 있는 기회를 간과한다. 더 이상 그러지 않기 위해, 사람을 위한 자동화 연재를 기획하여 소프트웨어 개발 프로세스를 자동화하는 실용적인 사용법들과 성공적으로 자동화를 언제 어떻게 적용하는지 설명하겠다.


그림 1. 직접 데이터베이스에 변경 적용하기
직접 데이터베이스에 변경 적용하기

데이터베이스에 직접 접근할 때 발생하는 문제를 사람이 직접 데이터베이스를 변경하는 일을 최소화하는 전략을 도입하여 해결할 수 있다. 습관과 도구의 조합을 통해, 여러분은 일관적이고 반복적인 절차를 통해 데이터베이스와 데이터 변경을 적용할 수 있다. 이 기사에서는 다음 내용을 다룬다.

  • LiquiBase라는 도구를 사용하여 데이터베이스 여러 버전 사이에서 마이그레이션하기
  • 데이터베이스 마이그레이션을 자동화하는 방법
  • 지속적인 데이터베이스 변경 적용 실천 사항
  • LiquiBase로 데이터베이스 리팩터링 적용하기

그림 2를 보면 빌드/CI(Continuous Integration) 서버가 Subversion 같은 버전 관리 저장소에서 변경 사항을 읽어온다. 저장소에서 변경 사항이 있으면, 자동화 빌드 스크립트를 실행하여 LiquiBase가 데이터베이스를 수정하도록 한다.


그림 2. 데이터베이스 마이그레이션 자동화하기
데이터베이스 마이그레이션 자동화하기

그림 2에 보여준 것과 같은 프로세스를 사용하면, 모든 팀원이 동일한 변경 사항을 데이터베이스에 반영할 수 있다. 각자의 로컬 혹은 공유 데이터베이스 서버 모두 된다. 게다가, 이런 프로세스가 자동화 스크립트를 사용하므로 이런 변경 사항들이 데이터베이스와 그 내용을 누군가 가리키는 일 없이도 각기 다른 환경에 적용할 수 있다.

DDL, DML, 스키마, 데이터베이스 데이터는 무엇인가?

본 기사에서, 나는 DDL(Data Definotion Language, 몇몇 데이터베이스 벤더는 이 용어를 스키마라고 하기도 한다) 스크립트 애플리케이션을 통해 데이터베이스 구조를 변경할 때, 이것을 데이터베이스 변경이라는 용어로 표현하겠다. 그리고 DML(Data Manipulation Language) 스크립트를 이용해 데이터베이스에 변경을 적용할 때는 간단하게 데이터 변경이라고 하겠다.

LiquiBase로 데이터베이스 변경 관리하기

LiquiBase는 2006년부터 사용할 수 있었던 오픈 소스로, 무료로 데이터베이스 버전을 다른 버전으로 이전할 때 무료로 사용할 수 있는 도구다(참고자료 참조). openDBcopy와 dbdeploy를 비롯한 많은 오픈 소스 데이터베이스 마이그레이션 도구가 등장했다. LiquiBase는 DB2, 아파치 Dervy, MySQL, PostgreSQL, 오라클, 마이크로소프트(Microsoft®) SQL 서버, Sybase, HSQL을 비롯한 열 가지 데이터베이스를 지원한다.

LiquiBase를 설치하려면, LiquiBase Core 압축 파일을 다운로드하고, 압축을 풀어서 그 안에 들어있는 liquibase-version.jar 파일을 시스템 경로에 둔다.

네 단계로 LiquiBase를 시작해보자.

  1. 데이터베이스 변경사항 로그(change log) 파일 만들기
  2. 변경사항 로그 파일 안에 변경 내역(change set) 만들기
  3. 커맨드 라인이나 빌드 스크립트를 사용하여 데이터베이스에 변경 내역 실행하기
  4. 데이터베이스에 변경 확인하기

변경사항 로그와 변경 내역 생성하기

LiquiBase를 사용하는 첫 번째 단계로, Listing 1에 보이는 것처럼 XML 파일로 데이터베이스 변경사항 로그를 작성한다.


Listing 1. LiquiBase XML 파일에 변경 내역 정의하기
<?xml version="1.0" encoding="UTF-8"?>

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.7"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.7
         http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.7.xsd">
  <changeSet id="2" author="paul">
    <createTable tableName="brewer">
      <column name="id" type="int">
        <constraints primaryKey="true" nullable="false"/>
      </column>
      <column name="name" type="varchar(255)">
        <constraints nullable="false"/>
      </column>
      <column name="active" type="boolean" defaultValue="1"/>
    </createTable>
  </changeSet>
</databaseChangeLog>

또... XML

XML 스크립트 세상에 사는 사람도 있고 그렇치 않은 사람도 있다. 개발자들은 점점 XML 스크립트를 사용하여 개발하는 데 익숙해져 가고 있다(예를 들어, 아파치 앤트 같은). 하지만 DBA가 사는 곳은 그렇지 않다. 최근에, 나는 DBA에게 흥분된 어조로 LiquiBase의 기능을 보여준 적이 있다. 그 DBA는 데이터베이스 변경 관리가 가능한 막강한 기능에 대해서는 매우 좋아했지만, DBA가 XML을 다뤄야 한다는 것에 대해서는 회의적이었다. LiquiBase는 sqlFilesql 커스텀 리팩터링을 사용하여 커스텀 SQL 스크립트도 호출할 수 있다는 사실을 알려주어 그를 안심시킬 수 있었다.

보다시피, 데이터베이스 변경사항 로그 파일은 XML 스키마를 참조한다(dbchangelog-1.7.xsd 파일은 LiquiBase를 설치할 때 포함되어 있다). 변경사항 로그 파일 안에, <changeSet>을 정의했다. <changeSet>을 사용하여, LiquiBase 스키마에서 정의한 구조화된 방법으로 데이터베이스에 변경을 적용한다.

LiquiBase를 커맨드 라인에서 실행하기

변경 내역을 정의한 다음, Listing 2에 보이는 것처럼 커맨드 라인에서 LiquiBase를 실행할 수 있다.


Listing 2. 커맨드 라인에서 LiquiBase 실행하기
liquibase --driver=org.apache.derby.jdbc.EmbeddedDriver \
--classpath=derby.jar \
--changeLogFile=database.changelog.xml \
--url=jdbc:derby:brewery;create=true \ 
--username= --password= \
update

예제에서 LiquiBase를 실행할 때 다음 값들을 넘겨주었다.

  • 데이터베이스 드라이버
  • 데이터베이스 드라이버 JAR 파일 위치에 해당하는 클래스패스
  • 내가 작성한 (Listing 1의) 변경 내역 파일의 이름 database.changelog.xml
  • 데이터베이스 URL
  • username과 password

마지막으로, Listing 2는 update 명령을 실행하여 LiquiBase가 이 변경 사항을 데이터베이스에 반영할 수 있게 한다.

LiquiBase를 자동화 빌드에서 실행하기

Instead of using the command-line option, I can make the database changes as part of the automated build by calling the Ant task provided by LiquiBase. 커맨드 라인을 사용하는 대신, LiquiBase에서 제공하는 앤트 태스크를 호출해 자동화된 빌드의 일부로 데이터베이스를 변경할 수 있다. Listing 3은 앤트 태스크 예제를 보여준다.


Listing 3. updateDatabase 태스크를 실행하는 앤트 스크립트
<target name="update-database">
  <taskdef name="updateDatabase" classname="liquibase.ant.DatabaseUpdateTask" 
    classpathref="project.class.path" />
  <updateDatabase changeLogFile="database.changelog.xml"
    driver="org.apache.derby.jdbc.EmbeddedDriver"
    url="jdbc:derby:brewery"
    username=""
    password=""
    dropFirst="true"
    classpathref="project.class.path"/>
</target>

Listing 3에서 update-database라는 타깃을 만들었다. 그 안에, LiquiBase가 제공하는 updateDatabase를 사용하는 앤트 태스크를 정의했다. changeLogFile(Listing 1에서 정의한 변경사항 로그를 기술한다)과 데이터베이스 연결 정보를 포함한 필요한 값들을 넘겨줬다. classpathref에 정의한 클래스패스는 반드시 liquibase-version.jar 파일을 포함하고 있어야 한다.

이전과 이후

그림 3은 Listing 1의 변경 내역을 실행하기 전 데이터베이스 상태를 보여준다.


그림 3. LiquiBase 변경 내역 실행 전 데이터베이스 상태
LiquiBase 변경 내역 실행 전 데이터베이스 상태

그림 4는 커맨드 라인(Listing 2 참조)이나 앤트를 사용하는 방법(Listing 3 참조)으로 데이터베이스 변경 내역을 실행한 이후를 보여준다.


그림 4. LiquiBase 변경 내역을 실행한 이후 변경이 적용된 데이터베이스
LiquiBase 변경 내역을 실행한 이후 변경이 적용된 데이터베이스

전체 그림은 여기에서 참조하라.

그림 4에서 몇몇 부분은 자세히 살펴볼 필요가 있다. 두 개의 LiquiBase 관련 테이블을 생성했다. 이는 Listing 1에 정의한 변경 내역을 기반으로 만들어진 테이블이다. LiquiBase 관련 첫 번째 테이블은 databasechangelog로 데이터베이스에 적용하는 모든 변경 내역을 관리한다. 누가 데이터베이스를 왜 변경했는지 추적하는 데 유용하다. LiquiBase 관련 두 번째 테이블은 databasechangelock으로 데이터베이스 변경을 할 때 록(lock)을 지닌 사용자를 식별할 때 사용한다.

LiquiBase를 여러 다른 방법으로도 실행할 수 있다. 하지만 나는 여러분이 데이터베이스 변경을 적용할 때 알아야 할 대부분의 것을 설명하고 있다. LiquiBase를 사용하다 보면, 대부분의 시간을 데이터베이스 리팩터링을 적용하는 여러 방법을 익히는 데 시간을 소비할 것이다. 거기에 특정 데이터베이스에 따라 변경해야 하는 복잡도까지 겸해서 말이다. 예를 들어, LiquiBase는 상당한 학습이 필요한 데이터베이스 롤백 기능을 제공한다. 데이터베이스 리팩터링 예제를 보여주기 전에, 간략하게 데이터베이스 통합 기본 원칙과 사용법을을 공유하여 데이터베이스 마이그레이션에 대한 감을 잡을 수 있도록 하겠다.




위로


데이터베이스 변경을 자주 통합하기

최근에 개발 팀은 소스 코드를 관리하듯이 데이터베이스에도 그와 비슷한 원칙과 방법을 적용하고 있다. 따라서 데이터베이스 변경 스크립트, 소스 코드 저장소를 통해 이런 자원을 공유하고, 빌드와 지속적인 통합 프로세스를 통해 변경 사항을 통합하는 등의 방법을 적용하는 건 매우 자연스러운 과정이다. 표 1은 데이터베이스 변경을 자동화 프로세스 일부로 사용할 때 개발 팀이 반드시 지켜야 할 주요 실천 사항들을 요약한 것이다.

여러분의 DBA를 자동화하라

내가 일했던 몇몇 프로젝트에서 DBA가 개발 데이터베이스 변경을 관리할 때 불필요한 병목 지점을 만들어두곤 했다. DBA는 통제와 안정성이라는 가면을 쓰고 불필요한 반복 작업을 하며 관리할 것이 아니라 데이터베이스의 성능을 올리고 모니터링하는 활동에 시간을 투자해야 한다.


표 1. 데이터베이스 통합 실천 사항
실천 사항설명
모든 DDL과 DML 스크립트 만들기 데이터베이스 변경은 커맨드 라인에서 실행할 수 있어야 한다.
데이터 자원에 대한 소스 관리 버전 관리 저장소를 모든 데이터베이스 관련 변경 사항을 관리하는 데 사용한다.
로컬 데이터베이스 샌드박스(Sandbox) 각각의 개발자는 변경을 가할 수 있는 로컬 데이터베이스 샌드박스를 사용한다.
데이터베이스 통합 자동화데이터베이스 관련 변경은 빌드 과정 중 일부로 적용한다.

이런 실천 사항들은 더 나은 안정성을 보장하며 한 번의 배포에서 다음 배포로 넘어갈 때 변경 내역 유실을 막는다.




위로


기존 데이터베이스에 리팩터링 적용하기

새로운 기능을 애플리케이션에 추가할 때, 데이터베이스 구조를 바꾸거나 테이블 제약 사항을 변경해야 하는 경우가 자주 있다. LiquiBase는 서른 가지가 넘는 데이터베이스 리팩터링(참고자료 참조)을 제공한다. 이번 절에서는 그 중 네 가지 리팩터링인 컬럼 추가, 컬럼 제거, 테이블 추가, 데이터 조작을 다루겠다.

컬럼 추가

프로젝트 초기에 데이터베이스에 필요한 모든 컬럼을 생각해내는 것은 불가능에 가깝다. 그리고 때로 사용자가 새로운 기능을 요구하기도 한다. 그로 인해 새 컬럼을 추가해야 하는 경우가 발생한다. Listing 4는 LiquiBase addColumn 리팩터링을 사용하여 데이터베이스의 distributor 테이블에 컬럼 하나를 추가한다.


Listing 4. LiquiBase 변경 내역에서 컬럼 추가 데이터베이스 리팩터링 사용하기
<changeSet id="4" author="joe">
  <addColumn tableName="distributor">
    <column name="phonenumber" type="varchar(255)"/>
  </addColumn> 
</changeSet>

새 컬럼 phonenumbervarchar 데이터 타입으로 정의했다.

컬럼 제거

몇 번의 배포 이후에, Listing 4에서 추가한 phonenumber 컬럼을 제거하기로 결정했다고 가정하자. 이때는 Listing 5에 보이는 것처럼 dropColumn 리팩터링을 호출하기만 하면 된다.


Listing 5. 데이터베이스 컬럼 제거하기
<dropColumn tableName="distributor" columnName="phonenumber"/>

테이블 추가

새 테이블을 데이터베이스에 추가하는 것도 역시 가장 흔한 데이터베이스 리팩터링이다. Listing 6은 여기에 정의한 컬럼과, 제약 사항, 그리고 기본 값으로 distributor라는 새로운 테이블을 생성한다.


Listing 6. LiquiBase로 새로운 데이터베이스 테이블 생성하기
<changeSet id="3" author="betsey">
  <createTable tableName="distributor">
    <column name="id" type="int">
      <constraints primaryKey="true" nullable="false"/>
    </column>
    <column name="name" type="varchar(255)">
      <constraints nullable="false"/>
    </column>
    <column name="address" type="varchar(255)">
      <constraints nullable="true"/>
    </column>
    <column name="active" type="boolean" defaultValue="1"/>
  </createTable>
</changeSet>

이 예제는 createTable 데이터베이스 리팩터링을 변경 내역의 일부로 사용한다(createTableListing 1에도 사용했다).

데이터 조작하기

(컬럼 추가나 테이블 추가 같은) 구조적인 데이터베이스 리팩터링을 적용한 뒤에는 보통 이런 리팩터링에 영향을 받은 테이블에 데이터를 추가하고 싶을 것이다. 또한, 조회 테이블이나 기타 타입의 테이블에 있는 기존 데이터를 변경하고 싶을지도 모른다. Listing 7은 LiquiBase 변경 내역을 사용하여 데이터를 추가하는 방법을 보여준다.


Listing 7. LiquiBase 변경 내역으로 데이터 추가하기
<changeSet id="3" author="betsey">
  <code type="section" width="100%">
  <insert tableName="distributor">
    <column name="id" valueNumeric="3"/>
    <column name="name" value="Manassas Beer Company"/>
  </insert>
  <insert tableName="distributor">
    <column name="id" valueNumeric="4"/>
    <column name="name" value="Harrisonburg Beer Distributors"/>
  </insert>
</changeSet>

데이터 조작을 하려고 이미 작성한 SQL 스크립트를 가지고 있을 수도 있다. 또는 LiquiBase XML 변경 내용이 너무 제한적일 수도 있다. 그리고 데이터베이스에 대규모 변경을 가하는 데는 SQL 스크립트가 더 간단할 때도 있다. LiquiBase는 이런 상황에도 역시 잘 활용 할 수 있다. Listing 8은 distributor 테이블 데이터를 넣는 변경 내역에 insert-distributor-data.sql을 사용한다.


Listing 8. LiquiBase 변경 내역에서 커스텀 SQL 파일 실행하기
<changeSet id="6" author="joe">
  <sqlFile path="insert-distributor-data.sql"/>
</changeSet>

LiquiBase는 이밖에도 룩업 테이블 추가(Add Lookup Table)와 컬럼 병합(Merge Column) 같은 다양한 데이터베이스 리팩터링을 제공한다. 이것들은 전부 방금 보여준 Listing 4에서 8과 비슷한 방법으로 사용할 수 있다.




위로


지속적으로 데이터를 동일하게 유지하기

소프트웨어 개발에서, 만약 무언가가 잘못되면, 그 문제가 더 커져서 다음 개발 주기에서 해당 기능을 수행할 때 더 많은 비용을 쓰고 고통을 가져다 주기 전에 그것을 더 많이 신경써야 한다. 데이터베이스 마이그레이션은 쉬운 것이 아니다. 따라서 자동화를 통해 상당히 많은 장점을 얻을 수 있다. 이 기사에서는 다음 내용을 살펴본다.

  • LiquiBase를 사용하여 데이터베이스 마이그레이션 스크립트를 만들고 자동화 빌드 프로세스 일부로 활용하는 방법
  • 안전성을 보장하는 데이터베이스 통합 실천 사항
  • LiquiBase를 사용하여 컬럼 추가, 테이블 추가, 데이터 갱신 등의 데이터베이스 리팩터링을 적용하는 방법

표 2는 LiquiBase가 제공하는 기능 몇 가지를 요약한 것이다.


표 2. LiquiBase 기능 요약
기능 설명
여러 데이터베이스 지원 DB2, 아파치 더비, MySQL, PostgreSQL, 오라클, 마이크로소프트 SQL 서버, Sybase, HSQL, 그외 다수를 지원한다.
데이터베이스에 적용한 변경 내역 조회 databasechangelog 테이블을 사용하여, 데이터베이스에 적용한 모든 변경 내역을 조회할 수 있다.
데이터베이스 차이 로그 생성 LiquiBase를 이용하지 않고 데이터베이스에 적용한 변경에 대해 알 수 있다.
커스텀 SQL 스크립트 실행 기능 LiquiBase를 사용하여 여러분이 기존에 작성해둔 SQL 스크립트를 호출할 수 있다.
데이터베이스 변경 롤백 기능 데이터베이스에 적용한 모든 변경 내역을 롤백할 수 있다.

자동화 스크립트를 통해 잘 적용하면, 데이터베이스 마이그레이션은 덜 고통스러우며, 모든 팀원이 실행할 수 있는 반복적인 프로세스가 될 것이다.



참고자료

교육

제품 및 기술 얻기
  • LiquiBase: LiquiBase를 다운로드하고 데이터베이스 마이그레이션을 수행하라.

  • 앤트: 앤트를 다운로드하고 예측, 반복 가능한 소프트웨어 개발을 시작하라.


토론


필자소개

Paul Duvall

Paul Duball은 Stelligent Incorporated의 CTO로, 개발팀이 배포 준비가 된 소프트웨어를 도출할 수 있도록 돕는 애자일 컨설팅을 하고 있다. Paul Duball은 Addison-Wesley 시그너처 시리즈 책인, Continuous Integration: Improving Software Quality and Reducing Risk(Addison-Wesley Professional, 2007년, 2008 졸트 상 수상작)의 공동 저자이기도 하다. 또 UML 2 Toolkit(Wiley, 2003년)과 No Fluff Just Stuff Anthology(Programatic Programmers, 2007년)에도 기여했다.




기사에 대한 평가


보다 나은 서비스를 제공하기 위함이오니 잠시 짬을 내어 이 양식을 제출하여 주십시오.



 


 


 


이 문서 북마킹 하기

mar.gar.in mar.gar.in naver naver eolin eolin del.icio.us del.icio.us





위로


Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. 기타 회사, 제품, 및 서비스명은 다른 상표나 서비스 마크일 수 있습니다.

developerWorks 콘텐트를 다른 사이트에 전재하기:
developerWorks 콘텐트에 대한 저작권은 IBM에 있습니다. IBM의 서면 허가나 원본 저자의 허락이 없이는 전재를 금합니다. 저희 콘텐트를 전재하시려면 IBM developerWorks 담당자 에게 문의하십시오.
    IBM 소개 개인정보 보호정책 문의