주요 컨텐츠로 이동
파트너

진화적 데이터베이스 개발 지원: Lakebase를 활용한 데이터베이스 브랜칭 (계속)

파트 2: 젠의 새로운 플레이북

작성자: Pramod Sadalage , Kevin Hartman

이 시리즈는 20년이 지난 지금, 진화적 데이터베이스 설계(Evolutionary Database Design) 방법론을 다시 살펴봅니다. 코드로 관리하는 데이터베이스 변경(database-changes-as-code)의 핵심 제약 조건은 항상 공유 데이터베이스 리소스에 있었습니다. Databricks Lakebase의 copy-on-write 브랜칭을 사용하면 테라바이트 규모의 프로덕션 데이터베이스에서 생성 시 스토리지 사용량이 전혀 없고 1초 만에 완료되는 브랜치 생성이 이제 O(1) 작업이 되며, 실천법 #4(모든 사람이 자신만의 데이터베이스 인스턴스를 갖는다)를 이상적인 목표로만 머물게 했던 제약이 사라졌습니다. 이 시리즈에서 저자는 제약 조건이 사라질 때 무엇이 변하는지 설명합니다. 방법론 자체는 그대로 유지되지만, 최초로 등장하는 실천법들, 자동으로 이루어지는 팀 규모의 거버넌스, DBA의 역할 진화, 그리고 에이전트가 인간 동료들과 공유하는 새로운 기능 등이 그것입니다.

젠(Jen)은 Evolutionary Database Design에 등장하는 개발자 캐릭터입니다. 이 에세이에서 그녀는 일상적인 사용자 스토리로 데이터베이스 리팩터링을 구현하여 inventory_code 필드를 location_code, batch_number, 및 serial_number(으)로 분할함으로써, DBA와 개발자가 협업할 수 있고, 스키마가 소규모로 점진적으로 진화할 수 있으며, 마이그레이션을 통해 변경 사항을 안전하게 전달할 수 있음을 보여주었습니다.

이 시리즈는 20년 후의 젠의 이야기로 이어집니다. 그녀가 따르는 방법론은 2003년에 따랐던 것과 동일합니다. 새로운 점은 lakebase 아키텍처를 통해 가능해진 워크플로의 기술적 기능인 copy-on-write 데이터베이스 브랜칭입니다. 이를 통해 그녀가 읽어왔던 실천법들이 프로덕션 규모에서 운영상 실제로 구현될 수 있게 되었습니다. 이 시리즈의 세 파트 전체에서 그녀는 하루 일과(파트 1), 새로운 플레이북(파트 2), 그리고 팀(파트 3)이라는 세 가지 범위에서 동일한 젠으로 등장합니다.

파트 1에서는 젠이 하나의 기능을 구현하는 과정을 살펴보았습니다. 그녀가 따른 실천법들은 2003년 Evolutionary Database Design 에세이에 설명되어 있고, 2006년 Refactoring Databases 서적에서 확장되었으며, 2010년 Continuous Delivery 서적(12장)에서 CI/CD 파이프라인에 도입되었습니다.

기존의 7가지 실천법

2003년 에세이에서는 7가지 실천법을 제시했습니다. 이 중 5가지는 2026년까지 적용하는 데 한계가 있었습니다.

  1. DBA는 개발자와 긴밀하게 협업합니다.
  2. 모든 데이터베이스 아티팩트는 애플리케이션 코드와 함께 버전 관리됩니다.
  3. 모든 데이터베이스 변경 사항은 마이그레이션입니다.
  4. 모든 사람이 자신만의 데이터베이스 인스턴스를 갖습니다.
  5. 개발자는 데이터베이스 변경 사항을 지속적으로 통합합니다.
  6. 모든 데이터베이스 변경 사항은 데이터베이스 리팩터링입니다.
  7. 개발자는 필요에 따라 데이터베이스를 업데이트할 수 있습니다.

적용상의 한계

  • 실천법 #1 (DBA 협업). 모든 스키마 변경은 잘못될 경우 프로덕션 규모의 영향을 미쳤기 때문에 DBA 검토는 동기식 및 게이팅 방식으로 유지되었습니다. 협업은 DBA의 일정에 따라 제한되었습니다.
  • 실천법 #4 (모든 사람이 자신만의 데이터베이스 인스턴스를 갖는다). 라이선스 비용, 인프라 비용, DBA 시간 등의 문제로 대부분의 팀에게는 이상적인 목표에 불과했습니다. 대부분의 팀은 공유 개발 데이터베이스로 돌아가 충돌을 감수했습니다.
  • 실천법 #5 (데이터베이스 변경 사항의 지속적 통합). 2010년 Continuous Delivery 열풍으로 마이그레이션이 파이프라인에 도입되었지만, 파이프라인은 공유 대상 데이터베이스에 대해 마이그레이션을 실행했습니다. 파이프라인별 격리가 누락되었습니다.
  • 실천법 #6 (모든 데이터베이스 변경 사항은 리팩터링이다). 각 리팩터링을 적용하려면 대부분의 팀이 PR 세분성 수준에서 보유하지 못한 실습 공간(테스트 데이터베이스)이 필요했습니다.
  • 실천법 #7 (개발자는 필요에 따라 업데이트한다). 개발자는 필요에 따라 공유 환경에 대해 마이그레이션을 실행할 수 있었지만, 실험이 다른 사람에게 영향을 미치기 때문에 안전하게 실험할 수 없었습니다.

변화된 점

Databricks Lakebase가 도입한 기술은 위의 실천법을 구현하는 데 가로막던 장애물을 제거합니다. Databricks Lakebase는 나머지 Databricks 레이크하우스가 실행되는 것과 동일한 오브젝트 스토리지 레이어(데이터 레이크)를 사용하는 관리형 Postgres 데이터베이스입니다. 데이터베이스의 데이터는 공유되는 내구성 있는 스토리지(실질적으로 S3 버킷)에 저장되며, Postgres 엔진은 그 위의 별도 컴퓨팅 레이어로 실행됩니다. 컴퓨팅과 스토리지는 독립적으로 확장됩니다. 엔진은 부하가 걸릴 때 확장(scale up)하고, 트래픽이 감소할 때 축소(scale down)하며, 유휴 상태일 때는 제로(0)로 축소할 수 있습니다. Lakebase는 Unity Catalog와 통합되어 여러 환경에서 통합된 거버넌스를 제공합니다.

Copy-on-write 데이터베이스 브랜칭은 분리된 아키텍처 덕분에 대규모로 실용화된 기술입니다. 브랜치는 분기 마커와 함께 동일한 공유 스토리지에 대한 새 포인터를 생성합니다. 브랜치에 쓰기 작업이 발생하기 전까지는 상위(parent)와 모든 페이지를 공유합니다. 브랜치에 쓰기가 발생하면 수정된 페이지 페이지만 분기되고 상위는 그대로 유지됩니다. 브랜칭은 메타데이터 작업이므로 데이터 복사가 필요하지 않으며, 상위 크기에 관계없이 약 1초 만에 완료됩니다. 브랜치는 변경된 페이지의 데이터만 유지합니다.

브랜치의 기술적 비용이 내부 데이터 크기와 분리되면, 실천법 #4(모든 사람이 자신만의 데이터베이스 인스턴스를 갖는다)의 이면에 있던 제약이 해제됩니다. 개발자별, PR별, 실험별 브랜치가 일상화됩니다. 상위의 보완 레이어가 필요 없어집니다. 테스트 루프에서 모크(mock)가 제거되고, 테스트별 브랜치의 실제 Postgres로 대체됩니다. 공유 스테이징이 스키마 변경을 테스트할 수 있는 유일한 공간이 아니게 됩니다. 인메모리 데이터베이스 대체재(H2, SQLite)가 단위 테스트 레이어에서 제거됩니다. 로컬 데이터베이스를 실행하기 위해 Docker 기반 컨테이너를 생성하는 DevOps 비용이 필요하지 않으며, 브랜치가 셀프 서비스로 제공되므로 프로비저닝을 위한 DBA 티켓 대기열이 줄어듭니다.

이 기술은 방법론 최적화를 가능하게 하고 원래 2003년 포스트의 이면에 있는 실천법의 목표를 완성합니다.

2026년을 향해 떠오르는 실천법

Lakebase의 copy-on-write 데이터베이스 브랜칭은 기존 실천법에 대한 이전의 제한 사항을 해제하고, 더 자세히 설명할 네 가지 추가 실천법을 가능하게 합니다.

  1. DBA는 개발자와 긴밀하게 협업합니다. 모든 PR에 스키마 diff가 게시되므로, DBA는 다른 코드 리뷰어와 마찬가지로 비동기식으로 리뷰합니다. 프로비저닝 비용이 거의 들지 않기 때문에 이제 DBA는 구현 후 리뷰하는 대신, 처음부터 개발자와 함께 솔루션을 설계하고 리뷰할 수 있는 여유를 갖게 됩니다.
  2. 모든 데이터베이스 아티팩트는 애플리케이션 코드와 함께 버전 관리됩니다. 이제 스키마 diff, 데이터베이스 마이그레이션 및 마이그레이션 테스트 결과가 아티팩트 세트에 포함됩니다.
  3. 모든 데이터베이스 변경 사항은 마이그레이션입니다. 여기에 멱등성(idempotency)이라는 새로운 작성 규칙이 추가됩니다. 이를 통해 병합된 모든 마이그레이션을 QA, 스테이징 및 프로덕션(Production)과 같은 다운스트림 환경에 자동으로 배포할 수 있습니다.
  4. 모든 사람이 자신만의 데이터베이스 인스턴스를 갖습니다. 개발자별, PR별, 실험별 세분성 수준에서 작동합니다. 이를 통해 개발자는 작동하는 첫 번째 솔루션에 안주하지 않고 여러 솔루션을 실험할 수 있습니다. 이러한 자유는 프로덕션 규모에 맞는 최적의 솔루션 개발로 이어질 것입니다.
  5. 개발자는 데이터베이스 변경 사항을 지속적으로 통합합니다. PR 세분성 수준에서 작동합니다. 모든 PR은 자체 브랜치에서 CI를 통해 실행됩니다.
  6. 모든 데이터베이스 변경은 데이터베이스 리팩터링입니다. 2006년 카탈로그는 여전히 유효합니다. 브랜치를 사용하면 다양한 규모의 환경에서 리팩터링을 시험해 볼 수 있는 저렴한 연습 공간이 생깁니다. 개발 데이터베이스에서 작동했던 마이그레이션이 운영 환경에서는 성능이 저하되는 경우가 많았지만, 이제는 더 큰 규모의 데이터베이스에서 마이그레이션을 테스트하여 성능을 확실히 보장할 수 있습니다.
  7. 개발자는 필요할 때 언제든지 데이터베이스를 업데이트할 수 있습니다. 이제 "온디맨드"란 실제 운영 데이터와 유사한 데이터를 대상으로 1초 만에 격리된 환경을 구축하는 것을 의미합니다.
  8. 파괴적 테스트(destructive testing)를 기본 옵션으로 사용할 수 있습니다. 영향 범위(blast radius)는 제로이며, 재설정하는 데 1초밖에 걸리지 않습니다. "내 테스트가 다른 사람의 데이터를 오염시키지 않을까?" 걱정할 필요가 없습니다. 이제 테스트를 실행할 때마다 새로운 브랜치를 만들 수 있기 때문입니다.
  9. 데이터베이스 수준에서의 A/B 변형 프로토타이핑이 가능합니다. 병렬 브랜치에 두 가지 디자인을 구축하고, 더 큰 팀 및 DBA와 협력하여 솔루션을 논의하고 시연(show and tell)을 진행한 후 최종 선택된 디자인을 유지하세요.
  10. 통합된 Unity Catalog를 사용하면 거버넌스를 한 번만 설계해도 모든 브랜치에 상속됩니다. 정책이 각 브랜치에 자동으로 적용되며, 이에 대한 자세한 내용은 3부에서 다루겠습니다.
  11. 동일한 브랜칭 기능을 갖춘 실무자로서의 에이전트(Agent-as-practitioner)입니다. 에이전트는 운영 환경이 아닌 브랜치를 할당받으며, 이에 대한 자세한 내용은 3부에서 다루겠습니다.

CI에서 워크플로가 실행되는 방식

그림 1: 코드와 스키마 마이그레이션 스크립트가 포함된 PR에 대한 CI 워크플로.

Lakebase가 제공하는 기능 덕분에 가장 크게 개선된 두 가지 프랙티스는 #4(모든 사람이 자신만의 데이터베이스 인스턴스를 가짐)와 #5(개발자가 데이터베이스 변경 사항을 지속적으로 통합함)입니다. 이제 단순히 모든 사람이 데이터베이스를 갖는 것을 넘어, 거의 비용과 시간을 들이지 않고도 모든 PR이나 모든 브랜치, 또는 브랜치당 여러 개의 데이터베이스를 가질 수 있습니다. 이 메커니즘은 모든 프로젝트에 스캐폴딩할 수 있는 두 개의 GitHub Actions 워크플로 템플릿을 사용하여 자동화할 수 있습니다.

PR별 브랜치 생성. pr.yml이(가) pull_request: [opened, synchronize]에서 트리거되어 PR의 베이스 브랜치에서 포크된 ci-pr-<N>을(를) 생성합니다:

동일한 작업이 CI 브랜치에 마이그레이션을 적용하고 실제 Postgres를 대상으로 애플리케이션의 테스트 제품군을 실행합니다. 워크플로의 전체 예시는 다음에서 확인할 수 있습니다: pr.yml

PR에 게시된 스키마 diff. 동일한 pr.yml 작업이 두 브랜치의 스키마를 덤프하고, diff 형식을 지정하여 PR 댓글로 게시합니다. 이를 통해 DBA는 다른 코드 리뷰어처럼 비동기식으로 리뷰를 진행할 수 있습니다(프랙티스 #1, 재구성):

DBA, 코드 리뷰어, 팀, 그리고 마이그레이션을 작성한 에이전트는 모두 PR에서 동일한 아티팩트를 볼 수 있습니다.

머지 시 브랜치 정리. merge.yml은(는) PR이 머지되는 즉시 CI PR 브랜치인 ci-pr-<N> 및 연결된 피처 브랜치의 Lakebase 브랜치를 삭제합니다:

머지 워크플로의 전체 예시는 여기에서 확인할 수 있습니다: merge.yml 수많은 브랜치가 생성되므로 분리되거나 사용되지 않는 브랜치를 제거하는 주간 정리 스크립트를 두는 것이 좋습니다. 예시 워크플로는 여기에서 확인할 수 있습니다: cleanup-orphans.yml. 마지막으로, 스테이징 또는 메인/운영 환경(이 개념은 3부에서 자세히 설명합니다)에 사용되는 '계층형(tiered)' 브랜치로 머지하는 경우, 사용자가 실제로 사용 중이고 지속적으로 데이터를 추가하는 환경에 최종 마이그레이션을 적용하기 전에, 해당 계층에서 새 브랜치를 생성하여 마이그레이션을 테스트하도록 워크플로를 구성할 수 있습니다.

이러한 워크플로가 함께 작동하면 개발자의 규율에 의존하는 것이 아니라 파이프라인의 속성으로서 모든 PR이 자체 데이터베이스를 갖고 브랜치가 임시로 유지되도록 강제할 수 있습니다.

진화적 데이터베이스 개발을 위한 새로운 플레이북

프랙티스 #1: DBA와 개발자의 긴밀한 협업

규칙. DBA는 최종 검토(gate-review) 시점뿐만 아니라 기능 개발 전반에 걸쳐 개발자와 협업합니다. 이 협업은 다른 코드 리뷰어가 참여하는 방식과 마찬가지로 PR 내에서 비동기식으로 진행됩니다.

이것이 이제 지속 가능한 습관이 된 이유는 무엇일까요? 스키마 diff 및 마이그레이션 테스트 결과가 모든 PR에 자동으로 표시됩니다(위의 CI에서 워크플로가 실행되는 방식 참조). DBA는 본인의 일정에 맞춰 구체적인 아티팩트를 검토합니다. 마이그레이션이 실제 데이터가 있는 CI 브랜치에서 이미 실행되었으므로, DBA가 머릿속으로 변경 사항을 시뮬레이션해 볼 필요가 없습니다.

작동 방식:

  • DBA는 스키마에 영향을 주는 경로(migrations/, db/, 스키마 테스트 디렉터리)의 CODEOWNER입니다.
  • DBA는 다른 리뷰어와 마찬가지로 PR에서 비동기식으로 리뷰를 진행합니다.
  • 리뷰의 초점이 이것이 데이터베이스를 망가뜨릴 것인가에서 이것이 올바른 설계인가? 올바른 방식으로 구현되었는가?로 이동합니다. 주요 주제: 데이터 무결성 규칙, 인덱싱 전략, 설계의 일관성, 향후 확장성, 장기적인 유지 관리성.

안티패턴. 검토할 명확한 아티팩트가 있음에도 불구하고 PR 흐름에 DBA를 포함하지 않는 것.

또한 DBA 역할에는 팀 규모의 정책 관리 및 거버넌스에 대한 새로운 책임이 추가됩니다. 3부에서 이 내용을 다룹니다.

프랙티스 #2: 모든 데이터베이스 아티팩트가 애플리케이션 코드와 함께 버전 관리됨

규칙. 모든 SQL 파일, 마이그레이션 스크립트, 스키마 테스트는 애플리케이션 코드와 동일한 리포지토리에 위치합니다. 스키마 diff 및 마이그레이션 테스트 결과는 PR 시점의 출력으로 아티팩트 세트에 추가됩니다.

왜 이것이 지금 지속 가능한 습관이 되었을까요? 브랜칭을 통해 세트에 두 개의 새로운 아티팩트가 추가됩니다. 바로 PR별 스키마 diff와 PR별 스키마 마이그레이션 테스트 결과입니다. 둘 다 실제 브랜치 상태를 기반으로 CI에서 생성됩니다. 둘 다 무엇이 변경되었고 변경 마이그레이션 스크립트가 어떻게 수행되었는지에 대한 구체적인 증거로서 PR에 남게 됩니다.

작동 방식:

  • 버전 관리되는 디렉터리 내의 마이그레이션 파일 (migrations/, db/migration/, alembic/versions/, 프레임워크에 따라 다름).
  • 애플리케이션 테스트와 함께 테스트 트리에 위치하는 스키마 영향 테스트.
  • CI에 의해 PR별로 생성되어 PR 댓글로 게시되는 스키마 diff.
  • CI 실행 요약 및 PR 댓글에 포함되는 마이그레이션 테스트 결과.

안티패턴. PR 흐름 외부에서 스키마 diff를 생성하는 것 (리뷰어가 별도로 열어야 하는 대시보드). 아티팩트는 리뷰가 진행되는 곳에 있어야 합니다. 스키마 변경 사항은 코드 변경 사항과 연결되어 있으며, 이 종속성을 깨뜨리면 배포 시 다운스트림 문제가 발생하기 때문입니다.

실천법 #3: 모든 데이터베이스 변경은 마이그레이션입니다

규칙. 어떤 환경에서도 수동 ALTER TABLE을 수행하지 않습니다. 모든 스키마 변경은 버전이 관리되고 체크인된 마이그레이션 스크립트입니다. 마이그레이션은 멱등성을 가집니다.

왜 이것이 지금 지속 가능한 습관이 되었을까요? 아티팩트로서의 마이그레이션 규칙은 2003년 이후로 변하지 않았습니다. 새로운 점은 멱등성이라는 작성 규율입니다. 전환 과정 동안 동일한 마이그레이션이 여러 브랜치에서 실행되므로 매번 동일하게 작동해야 합니다. 재적용 시 실패하는 마이그레이션은 버그입니다.

작동 방식:

  • flyway, liquibase, Knex, Alembic 등과 같은 마이그레이션 프레임워크를 사용하세요. 이러한 프레임워크는 어떤 마이그레이션이 실행되었고 실행되지 않았는지 추적하므로, 팀은 메타데이터 테이블에서 변경 사항을 추적하여 아직 적용되지 않은 변경 사항만 적용하는 flyway migrate와 같은 명령을 적용할 수 있습니다.
  • 되돌릴 수 없는 작업은 여러 마이그레이션으로 나누는 것이 좋습니다. 예를 들어 새 열을 추가하고 원본 열을 한 번에 삭제하는 마이그레이션은 롤백을 불필요하게 어렵게 만듭니다. 따라서 먼저 확장하고 나중에 축소(expand first and contract later)하는 전략을 사용하면, 배포 주기 후에 활성 리더가 이를 참조하지 않는다는 것을 확인한 후 훨씬 더 많은 옵션을 제공합니다.
  • 2006년 데이터베이스 리팩터링 카탈로그에는 어떤 리팩터링이 가역적이고 어떤 것이 비가역적인지 명시되어 있습니다. 이를 활용하세요.

안티패턴. 브랜치에서 발생한 로컬 변경 사항 때문에 스키마가 특정 중간 상태에 있어야만 작동하는 마이그레이션. 마이그레이션은 이전 마이그레이션을 포함하는 모든 상위 브랜치에 대해 올바르게 적용되어야 합니다.

실천법 #4: 모든 사람이 자신만의 데이터베이스 인스턴스를 가집니다

규칙. 모든 개발자, 모든 PR, 모든 실험, 모든 테스트 실행은 자신만의 Lakebase 브랜치를 가집니다.

왜 이것이 지금 지속 가능한 습관이 되었을까요? Docker 컨테이너를 생성하고, 로컬 데이터베이스 서버를 설치하고, 라이선스를 획득하고, 기존 스키마와 테스트 데이터로 빈 데이터베이스를 채우는 추가적인 노력이 더 이상 필요하지 않습니다. 간단한 create-branch Lakebase 명령만으로 1TB 데이터베이스를 1MB 데이터베이스와 마찬가지로 단 1초 만에 브랜칭할 수 있습니다. 생성 시 데이터가 복사되지 않으며, 수정된 페이지만 스토리지를 소비합니다. 개발자별, PR별, 실험별 인스턴스 생성이 일상화됩니다.

작동 방식:

  • 개발자별 브랜치: databricks postgres create-branch 또는 SCM 확장의 branch-create 흐름을 통해 필요에 따라 생성됩니다.
  • PR별 브랜치: PR이 열릴 때 CI에 의해 자동으로 생성되고(pr.yml), 병합되거나 닫힐 때 삭제됩니다(merge.yml). PR 및 병합 코드 조각은 위의 CI에서 워크플로가 실행되는 방식 을 참조하세요.
  • 실험별 브랜치: 디자인 탐색을 위해 스테이징 또는 프로덕션에서 포크되며, 실험이 끝나면 폐기됩니다.

안티패턴. "편의상" 팀 전체가 개발 데이터베이스를 공유하는 것. 브랜치가 병합되는 순간 파트 1에서 언급한 경합 중심의 직렬화 문제가 다시 발생합니다.

Jen의 사례가 확장되는 부분입니다. 그녀의 개발자별 브랜치는 기능 개발 시작 시 스테이징에서 포크되었습니다. CI 브랜치는 PR이 열릴 때 스테이징에서 포크되었습니다. 그녀의 A/B 탐색 브랜치(실천법 #9)는 스테이징에서 병렬로 포크되었습니다. 하나의 기능에 대해 4개의 브랜치가 단 몇 초 만에 모두 격리된 상태로 생성되었습니다.

실천법 #5: 개발자가 데이터베이스 변경 사항을 지속적으로 통합합니다

규칙. 모든 PR은 마이그레이션이 적용되고 실제 Postgres를 대상으로 테스트가 실행되는 새로운 Lakebase 브랜치에 대해 CI를 거칩니다.

왜 이것이 지금 지속 가능한 습관이 되었을까요? CI 파이프라인은 2010년부터 마이그레이션 규율을 유지해 왔습니다. 새로운 점은 파이프라인별 격리입니다. 각 PR이 고유한 브랜치를 가지므로 경합 없이 실제 형태의 데이터를 대상으로 통합이 실행됩니다.

작동 방식:

  • CI는 PR이 열릴 때 브랜치를 생성합니다. PR 코드 조각은 위의 CI에서 워크플로가 실행되는 방식을 참조하세요.
  • lakebase-migrate apply를 통해 브랜치에 마이그레이션이 적용됩니다.
  • 모의 객체(mock) 없이 ORM을 통해 마이그레이션된 브랜치를 대상으로 애플리케이션 테스트가 실행됩니다.
  • 스키마 diff가 PR에 게시됩니다.
  • 병합되거나 닫힐 때 브랜치가 삭제됩니다.

안티패턴. 공유 스테이징을 대상으로 PR 검증을 실행하는 것. 직렬화 문제가 다시 발생하며 PR별 격리 특성이 손실됩니다.

실천법 #6: 모든 데이터베이스 변경은 데이터베이스 리팩터링입니다

규칙. 스키마 변경은 Split Column, Rename Column, Move Column, Replace Type 등 명명된 리팩터링 패턴을 따릅니다. 각 패턴에는 명시적인 전환 메커니즘이 있습니다 (기존 항목과 새 항목을 병렬로 유지, 기존 항목에서 데이터 채우기, 리더 전환, 기존 항목 삭제).

왜 이것이 지금 지속 가능한 습관이 되었을까요? databaserefactoring.com의 2006년 카탈로그에는 실제 예제와 함께 70개 이상의 리팩터링이 명시되어 있습니다. 2026년에 새로워진 점은 전환 메커니즘을 저렴하게 연습할 수 있는 공간이 생겼다는 것입니다. 개발자 브랜치에서 연습을 진행하고, CI 브랜치에서 검증하며, 프로덕션에는 검증된 결과만 반영됩니다.

작동 방식:

  • 이름으로 리팩터링을 식별합니다. 카탈로그에서 찾아보세요.
  • 개발자별 브랜치에 명명된 전환 메커니즘을 적용합니다. 프로덕션 형태의 데이터를 대상으로 검증합니다.
  • PR을 엽니다. CI가 자체 브랜치에서 마이그레이션을 실행하고 diff를 게시합니다.
  • diff 및 테스트 결과가 승인되면 병합합니다.

안티패턴. 명명된 리팩터링에 매핑되지 않는 일회성 스키마 변경. 70개 이상의 카탈로그가 일반적인 사례를 다룹니다. 만약 여기에 해당하지 않는다면 여러 리팩터링을 하나의 마이그레이션으로 결합하고 있을 가능성이 높으므로 분할해야 합니다.

Jen의 예시가 확장되는 부분. 그녀의 V87 마이그레이션은 열 분할(Split Column) 리팩터링입니다. 즉, inventory_code을(를) location_code, batch_number, 그리고 serial_number(으)로 분할하는 것입니다. databaserefactoring.com/SplitColumns.html의 카탈로그 페이지에 전환 메커니즘이 명시되어 있습니다. 그녀의 브랜치는 연습 공간이었고, PR의 CI 실행은 검증 과정이었습니다.

실천법 #7: 개발자가 필요할 때 언제든지 데이터베이스를 업데이트할 수 있음

규칙. 개발자는 필요할 때 언제든지 브랜치의 데이터베이스 상태를 새로 고칠 수 있습니다. 상위 브랜치의 현재 상태로 재설정하거나, 프로덕션에서 새 브랜치를 포크하거나, 실험용 브랜치를 폐기하거나, 팀원과 브랜치를 공유하는 등의 작업을 모두 몇 초 만에 수행할 수 있습니다.

이것이 왜 이제 지속 가능한 습관이 되었을까요? 2026년의 '온디맨드(필요할 때 언제든지)'는 프로덕션 형태의 데이터를 대상으로 격리된 환경에서 1초 만에 수행됨을 의미합니다. 이러한 작업은 운영 일정이나 DBA 대기열을 확인할 필요가 전혀 없습니다.

작동 방식:

  • 재설정: 상위 브랜치에서 브랜치를 삭제하고 다시 생성합니다.
  • 프로덕션에서 포크: databricks postgres create-branch --source production.
  • 폐기: databricks postgres delete-branch.
  • 공유: 페어링 세션을 위해 팀원에게 브랜치 엔드포인트를 전달합니다.

안티패턴. 브랜치를 목적 이상으로 오랫동안 유지하려는 태도입니다. 마이그레이션 결과물이 영구적인 아티팩트이며, 브랜치는 임시 작업 공간일 뿐입니다.

실천법 #8: 파괴적 테스트를 기본 옵션으로 활용

규칙. 파괴적인 작업의 영향 범위(blast radius)가 0일 때, 파괴적 테스트는 분기별 행사가 아닌 일상적인 옵션이 됩니다.

이것이 왜 이제 지속 가능한 습관이 되었을까요? 브랜치는 1초 만에 재설정됩니다. 브랜치에 수행한 모든 작업은 동일한 상위 브랜치에서 새 브랜치를 생성하여 되돌릴 수 있습니다. 파괴적 테스트를 위해 더 이상 운영 일정이나 승인 절차를 거칠 필요가 없습니다.

이제 일반적인 기능 개발 주기에 포함될 수 있는 작업들:

  • "UPDATE 문 실행 도중에 마이그레이션이 실패하면 어떻게 될까?" 실행해 봅니다. 50% 진행되었을 때 프로세스를 강제 종료합니다. 롤백이 잘 작동하는지 확인합니다. 재설정합니다.
  • "백업 복구가 진행 중일 때 장애 조치(failover)가 트리거되면 어떻게 될까?" 부분적인 상태를 시뮬레이션합니다. 애플리케이션의 동작을 확인합니다. 재설정합니다.
  • "우리 DR 런북의 실제 복구 시간(time-to-recover)은 얼마나 될까?" 런북을 실행합니다. 측정합니다. 재설정합니다.
  • “이 마이그레이션이 프로덕션 형태의 데이터나 크기에서 성공적으로 실행되는가?” 완료하기 전에 검증합니다.

문화적 효과. 재설정 비용이 전혀 들지 않으면, 팀은 테스트 데이터베이스를 애지중지해야 할 리소스로 취급하지 않게 됩니다. 테스트를 과감하게 진행할 수 있습니다. 다음 브랜치는 깨끗한 상태로 시작되므로 정리 작업을 건너뛰어도 괜찮습니다.

Jen의 예시가 확장되는 부분. PR을 생성하기 전에, 그녀는 자신의 브랜치에 있는 프로덕션 형태의 데이터를 가져와 일부러 inventory_code 값의 약 1%를 누락된 숫자, 공백 포함, 뒤에 붙은 공백 등 에지 케이스처럼 보이도록 손상시켰습니다. 이는 과거 데이터가 쌓이면서 흔히 발생하는 형태의 아티팩트입니다. 그녀는 마이그레이션을 실행했습니다. 두 개의 행이 그녀의 하위 문자열(substring) 연산에서 실패했습니다. 그녀는 스크립트를 수정하고 다시 실행했습니다. 브랜치는 이 파괴적인 테스트를 무사히 수용했습니다. 프로덕션 환경에는 전혀 영향을 주지 않았습니다.

실천법 #9: 데이터베이스 수준에서의 A/B 변형 프로토타이핑

규칙. 두 가지 설계안이 대립할 때는 병렬 브랜치에 각각 구축하고, 프로덕션 형태의 데이터와 비교한 후 더 나은 솔루션을 선택합니다.

이것이 왜 이제 지속 가능한 습관이 되었을까요? 브랜치당 비용이 거의 제로에 가깝기 때문입니다. 두 가지 스키마 설계를 탐색할 때 더 이상 사전에 하나를 선택할 필요가 없으며, 대부분의 팀이 탐색적인 질문을 위해 기꺼이 감수하지 않았을 프로비저닝 프로세스도 필요하지 않습니다.

작동 방식:

  • 동일한 상위 브랜치에서 두 개의 브랜치를 생성합니다.
  • 한 브랜치에는 설계안 A의 마이그레이션을 적용하고, 다른 브랜치에는 설계안 B의 마이그레이션을 적용합니다.
  • 각 브랜치를 대상으로 애플리케이션을 실행합니다. 일반적인 읽기 경로의 쿼리 대기 시간, 프로덕션 볼륨에서의 마이그레이션 시간, 인덱스 공간 차지 크기, 시뮬레이션된 부하 하에서의 락 경합(lock contention) 등 중요한 지표를 측정합니다.
  • 더 나은 솔루션을 선택합니다. 최적이 아닌 솔루션은 폐기합니다. 다음번에 스키마를 확장해야 하는 사람이 어떤 점이 고려되었고 왜 이 설계가 선택되었는지 알 수 있도록 PR 설명에 결정을 기록해 둡니다.

안티패턴. 결정 사항과 그 이유를 기록하지 않고 A/B 프로토타입을 실행하는 것입니다. 브랜치는 순식간에 사라지지만, 설계 결정은 영구적이어야 합니다.

Jen의 예시가 확장되는 부분. 그녀는 위치/배치/일련번호 기능에 대해 두 가지 설계안을 고민했습니다. 기존 inventory 테이블에 3개의 새 열을 추가하는 방안과, 나중에 더 많은 속성이 추가될 것을 예상하여 inventory_id을(를) 키로 하는 별도의 inventory_attributes 조회(lookup) 테이블을 만드는 방안이었습니다. 그녀는 스테이징에서 갈라진 병렬 브랜치에 두 가지 방안을 모두 구축했습니다. 각 브랜치에 대해 애플리케이션의 읽기 경로를 실행하고, 프로덕션 형태의 데이터를 대상으로 쿼리 성능을 측정했으며, 각 마이그레이션이 프로덕션 볼륨으로 어떻게 확장될지 살펴보았습니다. 조회 테이블 버전은 인벤토리를 표시할 때마다 조인(join)이 필요했기 때문에 일반적인 읽기 경로에서 성능이 더 떨어졌습니다. 그녀는 열 추가 버전을 배포하고 조회 테이블 브랜치는 버린 후, PR 설명에 다음과 같은 메모를 남겼습니다. 조회 테이블 버전을 고려했으나, 일반적인 읽기 경로가 조인이 되므로 거부함. 속성이 5개 이상 누적되면 재검토할 것.

Jen의 새로운 플레이북이 보여주는 것

우리는 2003년의 7가지 실천법과 그 중 5가지를 이상으로만 남겨두었던 한계점을 짚어보고, 브랜칭 기능이 도입된 2026년에 맞춰 이를 재구성했으며, 브랜칭 덕분에 가능해진 4가지 새로운 실천법을 추가했습니다. 점진적 데이터베이스 개발(Evolutionary Database Development)을 위한 새로운 플레이북에는 총 11가지 실천법이 포함되어 있으며, 그 중 9가지가 위에 설명되어 있습니다.

In 파트 1 Jen의 이야기: 하나의 기능, 하나의 데이터베이스 에서 우리는 Jen이 하나의 기능을 해결해 나가는 과정을 보았습니다. 그녀는 코드 브랜치와 Lakebase 브랜치를 쌍으로 연결하고, 프로덕션 형태의 데이터를 대상으로 실제 마이그레이션을 몇 초 만에 실행했으며, 모의 객체(mock) 없이 테스트하고, 스키마 차이점(diff)이 인라인으로 표시된 PR을 생성한 후, 마이그레이션이 적용되고 임시 브랜치가 정리된 상태로 병합을 완료했습니다. 데이터베이스 변경이 일반적인 개발 프로세스의 일부가 되었습니다.

In 파트 3 – 규모가 확장된 Jen의 팀, 에서는 개발자가 50명인 환경에서의 플레이북, 정책 관리 및 거버넌스 분야로 진화한 DBA의 역할, 그리고 Jen과 함께 브랜치를 생성하는 에이전트들에 대해 살펴봅니다. 실천법 #10과 #11은 그곳에서 자세히 다뤄집니다.

부록인 가이드: 플러그인 둘러보기에서는 VS Code 및 Cursor용 Lakebase SCM 확장을 다룹니다.

에이전트를 위한 Lakebase App Dev Kit와 인간 실무자를 위한 동반 전자책(e-book)이 후속으로 출시될 예정입니다.

(이 글은 AI의 도움을 받아 번역되었습니다. 원문이 궁금하시다면 여기를 클릭해 주세요)

최신 게시물을 이메일로 받아보세요

블로그를 구독하고 최신 게시물을 이메일로 받아보세요.