본문 바로가기
프로그래밍

배포 가능한 응용 프로그램 작성 - 데이터베이스 버전

by it-view 2022. 1. 12.
반응형

드물게 애플리케이션과 데이터베이스를 배포해야 사용할 수 있습니다. 여러 고객에게 애플리케이션을 설치/업데이트하거나 Dev/UAT/Prod 환경에 변경 사항을 배포하는 경우 결정론적이고 수동 개입이 필요 없는 방식으로 코드를 푸시할 수 있어야 합니다.

고객이 애플리케이션을 설치하고 "지금 이 테이블을 변경하고 이 3개의 스크립트를 실행하십시오." 또는 "여기서 이 백업을 복구합니다."를 설명하는 동안 고객의 어깨에 기대어서는 안 됩니다. 이런 식으로 하기를 기대하는 것은 프로답지 않고, 보통 실현가능하지도 않으며, 항상 인간의 실수를 저지르기 쉽다.

프로그램에 따라 변경된 내용을 데이터베이스에 배치하려면 몇 가지 분야를 적용해야 합니다. 다음의 지침은 내가 직면한 거의 모든 상황에 폭넓게 적용됩니다.

모든 개발자는 자신만의 인스턴스가 필요합니다.

 

이것은 이상하거나, 낭비적이거나, 심지어 많은 추가 오버헤드처럼 들릴 수 있지만, 모든 개발자는 각자의 데이터베이스에서 운영해야 합니다. 일반적으로 로컬 호스트에서 실행할 수 있는 방법을 찾지만(Docker와 같은 것을 통해 컨테이너된 데이터베이스 서버 인스턴스) 각 개발자에 대해 별도의 데이터베이스를 실행하는 중앙 개발 서버가 있으면 됩니다.

이것의 주된 이유는 개발은 종종 실험적인 변화, 파괴적인 변화, 그리고 동시적인 변화를 수반하기 때문이다. 여러 사람이 있는 데이터베이스에 있는 이 3가지 중 하나 또는 한 사람이 여러 분기를 작업하는 경우 작업이 중단되거나 중단되는 경우가 많습니다.

각 개발자 전용 데이터베이스를 별도로 갖추면 개발자는 다른 개발자에 의해 중단되거나 중단될 염려 없이 자유롭게 변경 사항을 탐색할 수 있습니다. 개발자가 다른 사용자에게 영향을 미치지 않고 자신의 인스턴스를 완전히 파괴/회수할 수 있다는 추가적인 이점이 있습니다.

모든 데이터베이스 변경은 성문화되어야 한다.

데이터베이스 변경이 필요한 경우. 변화를 성문화하는 것이 중요하다. 이러한 방식으로 변경 사항을 개발자 및 환경 전반에서 재생할 수 있습니다. 어떤 변화가 필요한지 파악하고 이를 실행하는 것은 도구를 통해 이루어집니다. 몇 가지 예를 들자면 엔티티 프레임워크, 리퀴베이스, 플라이웨이 등이 있다.

 

필요한 변화를 만드는 것을 종종 "마이그레이션" 또는 "진화"라고 합니다.

변경이 필요한 새 기능을 추가할 때 "모두들 Users 테이블에 새 열을 추가하세요!"라는 이메일을 보내지 않습니다. 대신, ALTER TABLE ... 명령은 변경사항을 마이그레이트하는 데 사용되는 도구에 스크립트로 작성됩니다. 비록 내가 어떤 변화를 만들고 왜 만들었는지 팀원들과 소통하겠지만, 실제 변화는 사람에 의해 조정되는 것이 아닙니다.

변경사항을 코드화하고 마이그레이션 방법을 사용하면 데이터베이스에서 변경한 내용이 다른 개발자에게 전달됩니다. 또한 UAT/Testing 환경에 구축한 후 승인을 받으면 배포 시 동일한 변경 사항이 적용된다는 것을 확신할 수 있습니다.

성문화된 변경은 불변이어야 합니다.

개발자로서, 당신은 또한 데이터베이스가 변하지 않도록 주의할 필요가 있다. 통합하고 마이그레이션을 실행한 후에는 변경하지 않는 것이 중요합니다. 기존 마이그레이션을 변경하면 각 마이그레이션이 각 환경에서 한 번만 실행되므로, 이미 마이그레이션을 실행한 사용자는 변경 내용을 받을 수 없습니다.

 

대신 변경 사항을 다른 마이그레이션으로 추가해야 합니다.

코드화된 변경 사항을 코드 검토할 수 있습니다.

데이터베이스를 변경하는 것은 다양한 환경에서 수동으로 스크립트를 실행하는 일부 랜덤 개발자 또는 DBMS가 아닌 코드로 작성되기 때문에 풀 리퀘스트에서 검토될 수 있다. 이러한 방식으로, 변화는 더 쉽게 전달되고 오류는 더 빨리 잡힙니다.

자주 성문화된 변경사항 통합

여러 개발자의 데이터베이스 변경사항이 동시에 들어오면 매우 번거로울 수 있습니다. 대신 변경 사항을 소스 제어의 중앙 집중식 공통 분기에 병합해야 합니다. 개발자는 Pull Requests를 통해 변경사항을 병합해야 하며, 향후 변경사항을 적용하기 위해 최신 코드를 분기해야 합니다. 이러한 방식으로 충돌이나 오류가 더 빨리 발견되며, 이러한 오류/충돌의 범위는 최소한으로 유지됩니다.

 

통합은 종종 …으로 이어집니다.

자동화를 사용하여 마이그레이션 배포

여기서 CI/CD가 작동합니다. 코드가 공통 코드 분기에 통합되면 자동화된 빌드를 통해 검증 및 테스트를 수행한 후 중앙 통합 환경에 변경사항을 즉시 배포해야 합니다. 이를 통해 배포 단계를 처음부터 끝까지 실행하고 애플리케이션을 배포하고 마이그레이션을 실행할 수 있습니다.

다시 말씀드리면, 초기 설치이든 최신 상태로 전환하기 위한 마이그레이션이든 상관없이 데이터베이스 배포를 자동화해야 합니다. 환경 전반에 걸쳐 정확하고 논리적인 방식으로 일관되게 수행되어야 합니다. 이 작업은 Azure DevOps, TeamCity, GitHub Actions 등과 같은 릴리스 파이프라인을 사용하여 수행할 수 있습니다.

 

배포 및 마이그레이션 프로세스를 자동화하면서 취한 단계를 성문화하고 비밀을 주입하며 방정식에 인간 오류가 발생할 가능성을 줄일 수 있습니다.

추가 사용 사례

공유 데이터베이스

여러 응용프로그램에 걸쳐 동일한 데이터베이스를 사용하는 경우, 각 응용프로그램이 자체적인 변경사항을 실행하도록 원하지 않을 수 있습니다. 대신 공유 데이터베이스는 독립적인 중앙 집중식 마이그레이션 소스를 가져야 합니다. 이렇게 하면 수정사항을 작성하는 사용자가 이전 수정사항에 액세스할 수 있습니다. 이 저장소/프로젝트에 대한 풀 요청은 영향을 받는 다른 응용프로그램이 알림을 받고 검토를 고려할 수 있도록 팀 경계를 넘나들어야 합니다.

시드 데이터

 

스크립트를 통해 데이터베이스를 계속 시드할 수 있습니다. 이러한 시드 스크립트는 프로덕션에서 실행되면 안 됩니다. 개별적으로 실행되는지 아니면 특정 환경에서 건너뛸지 여부입니다.

어떤 방식으로든 특정 환경에서 실행되도록 지정할 수 있다면 더 좋습니다. 시드 데이터를 작성하면 작성된 후 계속 마이그레이션할 수 있기 때문이다. 반대로 시드 스크립트를 별도로 작성하고 개발자가 수동으로 실행하도록 하려면 이러한 스크립트를 유지 관리해야 합니다. 예를 들어 시드 스크립트가 특정 테이블에 10개(더 나쁜 경우 100개 또는 1000개) 행을 삽입한 후 나중에 열을 놓으면 시드 스크립트를 수정하고 해당 열을 모든 INSERT 문에서 제거해야 합니다. 마이그레이션 프로세스의 일부로 스크립트를 조건부로 실행할 수 있다면 데이터를 삽입한 후 열을 삭제하여 시드 스크립트를 수정할 필요가 없습니다.

예를 들어, 리퀴베이스에서는 마이그레이션이나 ChangeSet이 특정 컨텍스트에서만 실행되는 컨텍스트를 지정할 수 있다. 그러므로 리퀴베이스의 시드 마이그레이션은 다른 환경이 아닌 dev에서만 실행되도록 다음과 같은 문맥으로 지정할 수 있다.

<changeSet id="Insert test data to table XYZ" context="dev">
      INSERT INTO ...
          ...
      </changeSet>

dev에서 마이그레이션을 실행하면 다음과 같은 컨텍스트가 업데이트 명령에 제공됩니다.

 
liquibase --changeLogFile=changelog.xml --contexts="dev" update

그리고 만약 당신이 prod에서 실행했다면, 당신은 그 컨텍스트를 제공했을 것이고 그것은 시드 changeSet을 실행하지 않을 것이다:

liquibase --changeLogFile=changelog.xml --contexts="prod" update

결론

프로세스를 설계할 때 응용프로그램 설치 및 업데이트 방법을 고려해야 합니다.

 

응용 프로그램이 변경됩니다.

데이터베이스가 변경됩니다.

이러한 변경 사항을 구현하는 방법은 프로젝트 상태와 고객 및 팀의 역량에 상당한 영향을 미칩니다.

댓글