- Published on
DB 마이그레이션 도구 2026 — Atlas·Bytebase·Skeema·Liquibase·Flyway·Prisma·Drizzle·gh-ost·pg-osc 심층 비교 (선언형 vs 명령형, 리뷰 워크플로, 온라인 DDL)
- Authors

- Name
- Youngju Kim
- @fjvbn20031
프롤로그 — 마이그레이션 도구는 왜 여전히 어려운가
DB 스키마 변경은 소프트웨어에서 가장 위험한 작업 중 하나다. 코드 배포는 롤백이 쉽지만, ALTER TABLE은 한 번 실행되면 디스크 위의 사실이 된다. 큰 테이블에 잘못 락이 걸리면 서비스가 멈춘다.
그래서 마이그레이션 도구가 존재한다. 하지만 2026년 5월 현재 이 카테고리는 어느 때보다 분열되어 있다.
- Liquibase와 Flyway는 2010년대부터 자바 진영의 사실상 표준이었고, 지금도 엔터프라이즈에서는 디폴트다.
- Prisma Migrate·Drizzle Kit은 TypeScript 앱의 디폴트로 자리 잡았다. ORM과 한 묶음으로 와서 가장 매끄럽다.
- **Atlas (Ariga)**는 HCL 기반 declarative schema-as-code로 급속히 점유율을 늘리고 있다. Schema Monitoring·Schema Lint·Versioned Migrations 모두를 한 도구로.
- Bytebase는 리뷰 워크플로를 1급 시민으로 만들었다. 다중 DB·GitOps·AI 어시스턴트까지.
- Skeema는 MySQL 진영에서 가장 가벼운 declarative 도구로 살아남았고 Postgres도 들어왔다.
- 그리고 살아있는 큰 테이블에는 여전히 gh-ost·pt-online-schema-change·pg-online-schema-change 같은 온라인 DDL 도구가 필요하다.
이 글은 이 도구들을 선언형 vs 명령형, 리뷰 워크플로, 드리프트 감지, 다중 DB, AI 어시스턴스, 온라인 DDL 안전성의 축으로 비교한다. 실전 시나리오 — 칼럼 추가, NOT NULL 도입, 대형 테이블 백필, 롤링 리네임 — 를 각 도구로 풀어보고, 팀별 결정 프레임워크를 제시한다.
이 글은 패턴 가이드가 아니라 도구 비교다. 무중단 expand-contract 패턴 자체는 이미 별도 글에서 다뤘다(
2026-04-15 zero-downtime database migration참고). 여기서는 그 패턴을 어느 도구로 어떻게 굴리는지가 핵심이다.
1장 · 풍경 — 도구 지도
먼저 도구를 분류한다. 한 줄에 다 들어가지 않는다.
| 분류 | 도구 | 한 줄 요약 |
|---|---|---|
| 선언형 schema-as-code | Atlas, Skeema, Drizzle Kit | "있어야 할 상태"를 적으면 diff를 만든다 |
| 명령형 migration-files | Liquibase, Flyway, Prisma Migrate, dbmate, Sqitch | "무엇을 바꿀지" 한 파일씩 직접 적는다 |
| 리뷰 워크플로 중심 | Bytebase, Atlas Cloud | PR·승인·롤백·실행을 한 화면에서 |
| 온라인 DDL (큰 테이블 전용) | gh-ost, pt-online-schema-change, pg-online-schema-change | 쉐도우 테이블 + 트리거 + cutover |
| 클라우드 매니지드 | Atlas Cloud, Bytebase Hub, Liquibase Hub | 실행 로그·승인·드리프트 감지 SaaS |
이 글의 초점은 굵게 표시된 도구들이다. Atlas·Bytebase·Skeema·Liquibase·Flyway·Prisma Migrate·Drizzle Kit, 그리고 온라인 DDL 도구들.
왜 이 도구들인가
- Atlas — 2024~2026 사이 가장 빠르게 자란 도구. HCL DSL + Go 단일 바이너리 + Schema Monitoring이 묶음. Terraform이 인프라에 한 일을 DB에 하고 있다는 평가.
- Bytebase — 리뷰 워크플로·승인·다중 DB의 사실상 표준. 2025년부터 AI 어시스턴트(SQL Review·자연어→SQL)가 합쳐졌다.
- Skeema — MySQL의 declarative 도구. 가볍고 빠르다. 2025년 들어 Postgres 지원 정식 도입.
- Liquibase — XML/YAML/JSON/SQL 모두 지원. 변경 로그·롤백 SQL을 명시적으로 적는 전통. 엔터프라이즈·은행권 사실상 표준.
- Flyway — 단순함의 미학. SQL 파일에 버전 번호 붙이고 끝. 2025년부터 polyglot 지원 확대.
- Prisma Migrate·Drizzle Kit — 각 ORM의 한 식구. 가장 매끄러운 통합.
- gh-ost·pt-osc·pg-osc — 위 도구들이 못 하는 일을 한다. 큰 테이블의 무중단 DDL.
2장 · 선언형 vs 명령형 — 가장 큰 분기점
DB 마이그레이션 도구 선택의 첫 분기점이다. 무엇을 적는가가 다르다.
선언형 (declarative, schema-as-code)
"있어야 할 상태"를 적는다. 도구가 현재 DB와 비교해 diff를 만들고, 그 diff에 해당하는 DDL을 실행한다.
# Atlas: schema.hcl — 있어야 할 상태
table "users" {
schema = schema.public
column "id" { type = bigint, null = false }
column "email" { type = varchar(255), null = false }
column "name" { type = varchar(100), null = true }
primary_key { columns = [column.id] }
index "users_email_uniq" {
unique = true
columns = [column.email]
}
}
- 장점: 스키마가 한 곳에 모인다. 코드 리뷰가 "스키마 자체"를 본다.
- 단점: 자동 diff가 안전하지 않을 수 있다. 도구가 만든 DDL을 사람이 다시 본다.
명령형 (imperative, migration-files)
"무엇을 바꿀지"를 한 파일씩 적는다. 각 파일은 한 번 실행되면 끝.
-- Flyway: V001__add_users_table.sql
CREATE TABLE users (
id BIGINT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(100)
);
-- V002__add_users_created_at.sql
ALTER TABLE users ADD COLUMN created_at TIMESTAMPTZ DEFAULT now();
- 장점: 무엇이 도는지 사람이 정확히 안다. 롤백 SQL을 별도로 적을 수 있다.
- 단점: 스키마 전체 모양은 N개 파일을 머리로 합쳐야 안다. 충돌 머지·리네임이 어렵다.
어느 쪽이 우월한가
둘 다 우월하지 않다. 다만 2026년의 분위기는 분명하다:
- 신규 풀스택 팀은 선언형으로 시작하는 비율이 늘었다(Drizzle Kit·Atlas·Prisma
db push). - 엔터프라이즈·은행·관리 감독이 있는 곳은 여전히 명령형이 우세하다(Liquibase·Flyway). 감사 추적, 명시적 롤백 SQL이 컴플라이언스에 직결된다.
- Atlas는 두 진영을 한 도구에 넣었다. declarative
atlas schema apply도, versionedatlas migrate apply도 있다.
3장 · Atlas — 부상하는 강자
3.1 무엇이 다른가
Atlas는 이스라엘의 Ariga 사가 만든 오픈 소스 DB 스키마 도구다. Go로 작성됐고, 단일 바이너리, HCL DSL, 그리고 cloud SaaS(Atlas Cloud)가 따라온다.
핵심은 세 가지.
- 선언형과 명령형을 모두 지원한다.
atlas schema apply는 선언형,atlas migrate diff+atlas migrate apply는 명령형. - Schema Monitoring(2024년 도입) — production DB를 주기적으로 스냅숏 뜨고, 코드의 schema와 비교해 드리프트를 감지한다.
- Schema Lint·Schema Versioning —
atlas migrate lint로 위험 DDL(예: 비조건적 NOT NULL 도입)을 사전에 잡는다.
3.2 HCL 스키마
# schema.hcl
schema "public" {
comment = "core application"
}
table "users" {
schema = schema.public
column "id" {
type = bigint
null = false
}
column "email" {
type = varchar(255)
null = false
}
column "created_at" {
type = timestamptz
null = false
default = sql("now()")
}
primary_key {
columns = [column.id]
}
index "users_email_uniq" {
unique = true
columns = [column.email]
}
}
atlas schema apply --url "postgres://..." --to "file://schema.hcl" 한 줄로 현재 DB를 이 상태로 맞춘다. 미리 보고 싶다면 atlas schema diff.
3.3 Schema Monitoring — 새 카테고리
Atlas Cloud의 가장 큰 차별점은 드리프트 감지의 자동화다. 누군가 production에서 직접 ALTER TABLE을 친 사실, 또는 hotfix migration이 staging에는 적용되고 production에는 적용 안 된 사실을 도구가 알려준다.
# 주기적으로 production을 스냅숏
atlas schema monitor \
--url "postgres://prod.../app" \
--token "$ATLAS_TOKEN" \
--interval 1h
드리프트가 있으면 Slack·이메일로 알림. 이건 Flyway·Liquibase·Prisma Migrate에는 없는 카테고리다.
3.4 Versioned Migrations + Lint
명령형 워크플로를 선호한다면 Atlas의 versioned mode를 쓴다.
# 1) 코드의 schema.hcl과 현재 migration history를 비교해 새 SQL 파일 생성
atlas migrate diff add_user_table \
--dir "file://migrations" \
--to "file://schema.hcl" \
--dev-url "docker://postgres/16/dev"
# 2) 위험 DDL이 있는지 lint
atlas migrate lint --dir "file://migrations" --latest 1
# 3) 적용
atlas migrate apply --dir "file://migrations" --url "$DB_URL"
atlas migrate lint는 다음 같은 패턴을 잡는다.
- 큰 테이블에 비조건적
NOT NULL도입 (락 위험). - 락을 길게 유지하는 인덱스 생성 (
CREATE INDEX비-CONCURRENTLY). - 데이터 손실 위험 변경 (column drop, type narrowing).
3.5 누가 Atlas를 쓰면 좋은가
- HCL/Terraform 친화적이고, infra-as-code 멘탈 모델에 익숙한 팀.
- 다중 DB(Postgres, MySQL, MariaDB, SQLite, MS SQL, ClickHouse 일부) 한 도구로.
- 드리프트 감지가 필요한 멀티 환경(staging·prod)·멀티 인스턴스 팀.
- ORM과 무관하게 DB 진실의 원천을 코드에 두고 싶은 팀.
4장 · Bytebase — 리뷰 워크플로 1급 시민
4.1 무엇이 다른가
Bytebase는 중국 출신의 오픈 소스 + 상용 회사. 다른 도구들이 CLI를 중심에 두는 반면, Bytebase는 GUI + 승인 워크플로를 중심에 둔다.
개발자 → 변경 제안(PR-like Issue) → SQL Review(자동·사람)
→ DBA 승인 → 단계적 환경 적용(dev → staging → prod)
→ 자동 백업·롤백 스크립트 보존
- 다중 DB: MySQL·Postgres·TiDB·Snowflake·MongoDB·ClickHouse·SQL Server·Oracle·Spanner 등 25종 이상.
- GitOps 모드: GitHub/GitLab PR 머지로 트리거.
- 자동 SQL Review: 룰 기반(컬럼 명명·인덱스·길이 제한 등) + 2025년부터 LLM 기반.
4.2 AI 어시스턴트 (2025~2026)
Bytebase 3.x부터 추가된 기능.
- 자연어 → SQL: "지난주 가입자 일별로 보여줘" 같은 요청을 SQL로.
- SQL Review: LLM이 위험 패턴(인덱스 없는 join, full scan, 락 위험)을 사람보다 빠르게 잡는다.
- 변경 영향 분석: 이 마이그레이션이 영향 주는 쿼리·뷰·앱 코드 추정.
이 카테고리는 다른 도구들이 아직 깊게 못 따라왔다. Atlas도 자체 AI를 붙이고는 있지만 Bytebase가 가장 성숙하다.
4.3 누가 Bytebase를 쓰면 좋은가
- 다중 DB·다중 환경·여러 팀이 같이 쓰는 큰 조직.
- DBA가 정식으로 승인·리뷰하는 프로세스가 필요한 곳(금융·헬스케어).
- GUI를 통한 비-개발자 접근(데이터 분석가 등)이 필요한 곳.
- "마이그레이션 PR을 누가 머지했는가"를 감사 추적해야 하는 곳.
누가 쓰지 말 것: 1인 또는 소규모 팀. 오버킬이다. Drizzle Kit + Atlas migrate가 충분.
5장 · Skeema — MySQL 진영의 가벼운 declarative
Skeema는 단순함의 화신이다. MySQL용으로 시작했고 2025년에 Postgres 정식 지원.
schemas/
├─ app/
│ ├─ users.sql # CREATE TABLE users (...)
│ ├─ posts.sql
│ └─ .skeema # connection info
*.sql 파일에 CREATE TABLE 문 그대로 적는다. skeema diff·skeema push로 DB와 동기화.
- 장점: 다른 도구를 안 배워도 된다. SQL을 그대로 적는다. 빠르다. CI 친화적.
- 단점: Postgres 지원이 Atlas만큼 풍부하진 않다. enum·partial index·function·trigger 등 일부 객체 지원에 격차.
MySQL을 쓰면서 가벼운 도구를 원하면 가장 먼저 검토할 후보. Atlas와 비교해 학습 곡선이 거의 0이다.
6장 · Liquibase — 엔터프라이즈의 지속 가능한 선택
6.1 무엇이 다른가
Liquibase는 2006년부터 있다. 자바 진영의 표준이지만 자바 앱이 아닌 곳에서도 잘 쓰인다.
핵심 개념: ChangeSet. 변경 하나가 하나의 ChangeSet이고, 각각이 id·author·rollback SQL을 명시적으로 갖는다.
# changelog.yaml
databaseChangeLog:
- changeSet:
id: 001-create-users
author: alice
changes:
- createTable:
tableName: users
columns:
- column: { name: id, type: BIGINT, constraints: { primaryKey: true } }
- column: { name: email, type: VARCHAR(255), constraints: { nullable: false, unique: true } }
- column: { name: name, type: VARCHAR(100) }
rollback:
- dropTable: { tableName: users }
liquibase update로 적용, liquibase rollback으로 되돌림. 명시적인 rollback SQL이 큰 차이점이다.
6.2 2025~2026의 변화
- Liquibase 5.x(2025): 더 빠른 changelog 파싱, 새 reporting CLI.
- Liquibase AI Advisor: Liquibase Hub에서 LLM 기반 리뷰. Atlas Lint·Bytebase Review와 비슷한 방향.
- PostgreSQL extension 지원 확대: pg_partman·TimescaleDB·pgvector 등 익스텐션 친화 변경 지원.
6.3 누가 Liquibase를 쓰면 좋은가
- 자바·코틀린 백엔드 + Spring Boot.
spring-boot-starter-liquibase한 줄. - 엔터프라이즈·은행·헬스케어 — 명시적 rollback과 감사 추적이 컴플라이언스 요건.
- 멀티 DB(Oracle·DB2 포함) — Atlas·Bytebase보다 Oracle·DB2 친화도가 높음.
- 변경 로그를 XML/YAML로 가지고 싶은 팀.
약점: XML/YAML은 SQL을 직접 쓸 때보다 장황하다. Drizzle Kit·Atlas와 비교해 신규 팀에는 무거울 수 있다.
7장 · Flyway — 단순함의 미학
Flyway는 더 단순하다. 파일 이름으로 버전을 매기고, SQL을 그대로 적는다.
db/migration/
├─ V1__create_users.sql
├─ V2__add_users_created_at.sql
└─ V3__add_users_email_index.sql
-- V2__add_users_created_at.sql
ALTER TABLE users ADD COLUMN created_at TIMESTAMPTZ DEFAULT now();
flyway migrate로 적용. rollback은 별도 down 파일(U2__...) 또는 새 forward migration으로 푼다.
7.1 2025~2026 변화
- Flyway 11.x(2025년 후반): Native compiled CLI(GraalVM), 더 빠른 startup.
- Polyglot 친화 확대: Node/Python 진영을 위한 공식 도커 이미지 정리·CI 가이드.
- Flyway Teams/Enterprise의 새 features: 대규모 마이그레이션 dry-run, undo 자동화.
7.2 누가 Flyway를 쓰면 좋은가
- 자바·Spring Boot의 디폴트.
spring-boot-starter-flyway한 줄. - "SQL 그대로, 도구는 가볍게" 원하는 팀.
- 단순한 단일 DB(주로 Postgres·MySQL) 운영.
약점: rollback이 1급 시민이 아니다(community edition). 복잡한 변경에는 Liquibase가 더 강하다.
8장 · Prisma Migrate · Drizzle Kit — ORM과 한 묶음
8.1 Prisma Migrate
schema.prisma(declarative)와 prisma migrate(versioned)의 조합.
// schema.prisma
model User {
id Int @id @default(autoincrement())
email String @unique @db.VarChar(255)
name String? @db.VarChar(100)
createdAt DateTime @default(now()) @map("created_at")
@@map("users")
}
# 새 마이그레이션 생성 + 적용 (개발용)
npx prisma migrate dev --name add_user_table
# 프로덕션 적용
npx prisma migrate deploy
- 장점: ORM의 모델 정의가 곧 스키마. 한 곳에서 본다. 셰도우 DB로 안전한 diff 생성.
- 단점: 복잡한 객체(partial index, exclusion constraint, generated column 일부, custom domain)는 Prisma 모델로 표현 못 함 —
migration.sql을 직접 편집해야 함.
8.2 Drizzle Kit
// schema.ts (드리즐 스키마)
import { pgTable, bigserial, varchar, timestamp, uniqueIndex } from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
id: bigserial('id', { mode: 'bigint' }).primaryKey(),
email: varchar('email', { length: 255 }).notNull(),
name: varchar('name', { length: 100 }),
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
}, (t) => ({
emailUniq: uniqueIndex('users_email_uniq').on(t.email),
}))
# 스키마와 DB를 비교해 SQL 파일 생성
npx drizzle-kit generate
# 적용
npx drizzle-kit migrate
- 장점: ORM과 분리된 가벼운 CLI. SQL 파일이 보수적이고 읽기 쉽다.
- 단점: 자동 diff가 100%는 아님 — 컬럼 리네임 등은 사람 보정 필요. 일부 객체(enum 변화, 복합 PK 변경) 가장자리.
8.3 ORM 마이그레이션 vs Atlas/Liquibase
- ORM 도구가 가장 매끄럽다 — 모델과 스키마가 한 곳.
- 그러나 DB가 ORM의 시야 밖 객체(extension, materialized view, custom function)를 많이 쓰면 ORM 마이그레이션만으로 부족.
- 그런 팀은 ORM은 read/write 타입용으로만 쓰고, 스키마는 Atlas/Liquibase로 따로 운영하는 패턴이 늘었다.
9장 · 온라인 DDL — 큰 테이블의 무중단
위 도구들의 공통점: DB가 직접 ALTER TABLE을 실행한다는 가정. 작은 테이블이면 문제없다. 그러나 1억 row 테이블에 새 컬럼을 추가하면? 대부분의 DDL이 메타데이터 락을 잡는다. MySQL은 8.0 이후 많은 DDL이 online이지만, 여전히 락 위험이 있는 변경이 있다. Postgres는 12+ 이후 많이 좋아졌지만 일부 변경은 여전히 ACCESS EXCLUSIVE 락.
그래서 온라인 DDL 도구가 필요하다.
9.1 gh-ost (MySQL)
GitHub이 만든 도구. 트리거를 쓰지 않고 binlog만 본다. 부하가 낮다.
gh-ost \
--user=admin --password=*** --host=mysql.prod \
--database=app --table=users \
--alter="ADD COLUMN status VARCHAR(20) DEFAULT 'active'" \
--max-load=Threads_running=25 \
--critical-load=Threads_running=1000 \
--chunk-size=2000 \
--execute
작동: 쉐도우 테이블 생성 → 청크 단위 복사 → binlog로 누락 변경 따라잡기 → 짧은 락으로 cutover.
9.2 pt-online-schema-change (MySQL)
Percona Toolkit의 일부. gh-ost보다 오래됐고, 트리거 기반이다.
pt-online-schema-change \
--alter="ADD COLUMN status VARCHAR(20) DEFAULT 'active'" \
--execute \
D=app,t=users,h=mysql.prod
장점: 더 오래 검증됐고 더 다양한 환경에서 돈다. 단점: 트리거가 INSERT/UPDATE/DELETE에 매번 따라붙어 부하가 있다.
9.3 pg-online-schema-change (Postgres)
상대적으로 후발 주자. shadow table + 트리거 + cutover 패턴을 Postgres에 맞췄다. Shopify·Stripe 등이 만든 도구들이 있고 (pg-osc·pg_squeeze·pg_repack), 활용도가 늘고 있다.
pg-osc run \
--dbname=app --table=users \
--alter="ADD COLUMN status TEXT DEFAULT 'active'" \
--copy-batch-size=10000
Postgres 자체가 ALTER TABLE ... ADD COLUMN(기본값 있는)을 12+에서 빠르게 처리하긴 하지만, type change·NOT NULL 도입·인덱스 재구성 같은 변경에는 여전히 도움이 된다.
9.4 Atlas/Bytebase + 온라인 DDL
도구 통합이 막 시작됐다.
- Atlas:
migrate lint가 큰 테이블 변경을 경고. 실행은 여전히 외부 도구. - Bytebase: 일부 변경을 자동으로 gh-ost로 라우팅하는 모드(엔터프라이즈).
- 대부분의 팀은 여전히 'Atlas/Liquibase가 만든 SQL을 사람이 보고, 큰 테이블이면 gh-ost로 직접 실행' 패턴.
10장 · 실전 시나리오 — 도구별 풀이
같은 변경을 도구별로 보면 차이가 극명하다. 시나리오 셋.
10.1 시나리오 A — 새 컬럼 추가 (status, 기본값 'active')
Flyway
-- V012__add_users_status.sql
ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'active' NOT NULL;
Liquibase
- changeSet:
id: 012-add-users-status
author: bob
changes:
- addColumn:
tableName: users
columns:
- column:
name: status
type: VARCHAR(20)
defaultValue: 'active'
constraints: { nullable: false }
rollback:
- dropColumn: { tableName: users, columnName: status }
Prisma Migrate — schema.prisma에 status String @default("active") 추가 후 prisma migrate dev.
Drizzle Kit — schema.ts에 status: varchar('status', { length: 20 }).default('active').notNull() 추가 후 drizzle-kit generate.
Atlas (declarative) — schema.hcl에 column "status" 블록 추가, atlas schema apply.
Atlas (versioned) — 위와 같이 schema.hcl 수정 후 atlas migrate diff add_status → SQL 파일 자동 생성.
큰 테이블이라면 — Postgres 12+는 기본값 있는 컬럼 추가도 빠르지만, MySQL 8.0 이전이거나 매우 큰 테이블이면 gh-ost로 실행한다. Atlas Lint가 사전 경고.
10.2 시나리오 B — 기존 컬럼에 NOT NULL 도입 (백필 후)
가장 위험한 패턴 중 하나. 잘못하면 락이 길게 걸린다.
안전한 순서 (expand-contract 패턴 변형):
- 컬럼은 이미 있고 nullable. 백필 SQL을 batch로 실행 (
UPDATE ... WHERE id BETWEEN ... AND ...). - application 코드가 더 이상 NULL을 쓰지 않게 수정·배포.
NOT NULLconstraint를 추가 — Postgres 12+에서는NOT VALID+VALIDATE CONSTRAINT패턴으로 락 시간 최소화.
Flyway — 위 1~3을 각각 V-파일로 나누어 적는다.
Liquibase — addNotNullConstraint. 백필은 sql change 또는 별도 ChangeSet.
Atlas — schema.hcl에서 null = true를 null = false로 바꾼다. atlas migrate lint가 데이터가 있다면 경고한다(unsafe DDL).
Prisma/Drizzle Kit — 자동 diff는 ALTER TABLE ... ALTER COLUMN ... SET NOT NULL만 만든다. 백필은 사람이 별도 migration SQL로 추가해야 안전.
Bytebase — 자동 SQL Review가 "백필 없이 NOT NULL을 도입하려고 함"을 잡는다(룰을 켰다면).
10.3 시나리오 C — 컬럼 리네임 (name → display_name)
가장 골치 아픈 패턴. 자동 diff 도구들이 잘 못 잡는다 — drop + add로 인식한다.
모든 도구의 공통 안전한 순서 (롤링 리네임):
display_name추가. 트리거 또는 dual-write로name↔display_name동기화.- application을
display_name만 읽고 쓰게 변경·배포. - 한참 후 —
name컬럼 제거.
Flyway·Liquibase — 위 1~3을 각각 명시적으로 적는다.
Atlas (declarative) — schema.hcl에서 컬럼 이름을 바꾸면 도구는 기본적으로 drop + add로 본다. rename hint를 명시적으로 적어야 함:
column "display_name" {
type = varchar(100)
null = true
comment = "renamed from name"
}
# 그리고 atlas migrate diff 시 --rename old_to_new 같은 힌트 필요
Prisma/Drizzle — 자동으로 drop + add를 만든다. 데이터 손실 위험. 반드시 마이그레이션 SQL을 손으로 수정해 ALTER TABLE ... RENAME COLUMN으로 바꾼다. ORM의 @map/varchar('display_name') 매핑으로 코드 이름은 따로 유지.
교훈: 리네임은 어떤 도구든 자동 diff에 100% 맡기지 않는다. 사람의 확인이 필수.
11장 · 7축 비교 — 한눈에
11.1 선언형 vs 명령형
| 도구 | 선언형 | 명령형 |
|---|---|---|
| Atlas | O (schema apply) | O (migrate diff/apply) |
| Skeema | O | X |
| Drizzle Kit | O (스키마) | O (생성된 SQL) |
| Prisma Migrate | O (db push, dev) | O (migrate deploy) |
| Liquibase | X | O |
| Flyway | X | O |
| Bytebase | 일부 | O |
11.2 다중 DB 지원
| 도구 | Postgres | MySQL | SQLite | Oracle | SQL Server | 기타 |
|---|---|---|---|---|---|---|
| Atlas | O | O | O | 일부 | O | ClickHouse 일부 |
| Bytebase | O | O | O | O | O | 25종 이상 |
| Liquibase | O | O | O | O | O | DB2·Snowflake 등 |
| Flyway | O | O | O | O | O | 다수 |
| Skeema | O | O | X | X | X | - |
| Prisma | O | O | O | X | O | MongoDB 제한 |
| Drizzle | O | O | O | X | X | D1·LibSQL 등 |
11.3 리뷰 워크플로
| 도구 | 빌트인 리뷰 | 자동 lint | LLM 리뷰 |
|---|---|---|---|
| Bytebase | O (GUI) | O | O |
| Atlas Cloud | O | O | 일부 |
| Liquibase Hub | O | O | O (Advisor) |
| Flyway Enterprise | 일부 | 일부 | 도입 중 |
| 나머지 (CLI) | X (Git PR로 대체) | X | X |
11.4 드리프트 감지
| 도구 | 자동 드리프트 감지 | 비고 |
|---|---|---|
| Atlas (Cloud) | O | 가장 성숙 |
| Bytebase | O | GUI에서 |
| Liquibase | 일부 | history table 기반 |
| Flyway | 일부 | history table 기반 |
| Skeema·Prisma·Drizzle | 제한 | 도구 실행 시점에만 |
11.5 AI 어시스턴스 (2026)
| 도구 | AI 기능 |
|---|---|
| Bytebase | 자연어→SQL, SQL Review, 변경 영향 분석 |
| Atlas | Migration lint + 일부 AI 추천 |
| Liquibase | Hub Advisor (LLM 리뷰) |
| 나머지 | 외부 도구(Copilot, Cursor)에 의존 |
11.6 온라인 DDL 통합
| 도구 | 직접 지원 | 안전한 lint | gh-ost 라우팅 |
|---|---|---|---|
| gh-ost·pt-osc·pg-osc | (도구 본인) | - | - |
| Atlas | X | O (Lint) | X (수동) |
| Bytebase Enterprise | 일부 | O | O |
| Liquibase | X | 일부 | X |
| 나머지 | X | X | X |
11.7 ORM 통합 매끄러움
| 도구 | TypeScript ORM | Java/Kotlin | Python | Go |
|---|---|---|---|---|
| Prisma Migrate | 최고(자체) | - | - | - |
| Drizzle Kit | 최고(자체) | - | - | - |
| Atlas | 좋음(Atlas + ORM) | 좋음(Atlas + JPA) | 좋음(Atlas + SQLAlchemy) | 최고 (Atlas 본가) |
| Liquibase | 보통 | 최고 (Spring) | 좋음 | 보통 |
| Flyway | 보통 | 최고 (Spring) | 좋음 | 보통 |
| Skeema | 보통 | 보통 | 보통 | 보통 |
12장 · 팀별 결정 프레임워크
도구 결정의 첫 번째는 도구의 우월성이 아니라 팀의 모양이다.
12.1 1~3인 풀스택 팀 (TS/Next.js)
- Prisma Migrate 또는 Drizzle Kit 단독으로 충분.
- ORM과 마이그레이션이 한 묶음이라 학습·운영 비용 최소.
- 셰도우 DB가 필요한 Prisma의 dev 워크플로가 부담이면 Drizzle Kit.
- 추가 안전망 — Atlas Cloud free tier로 드리프트 감지만 붙이는 정도.
12.2 10~30인 다중 팀, TS 메인 (스타트업)
- Drizzle Kit + Atlas (lint + 드리프트 감지) 조합이 늘었다.
- Bytebase는 아직 오버킬.
- GitOps 모드: PR에
drizzle-kit generate결과 SQL이 들어가고, CI에서atlas migrate lint.
12.3 50인+ 다중 DB 다중 서비스 (mid-stage 스타트업)
- Bytebase + Atlas 또는 Bytebase + Liquibase.
- 다중 DB 지원·승인 워크플로가 필요한 단계.
- DBA 또는 platform 팀이 정식으로 마이그레이션 게이트키퍼.
12.4 자바·Spring Boot 위주 엔터프라이즈
- Flyway (단순한 변경 위주) 또는 Liquibase (롤백·감사 중요).
- 추가로 Atlas 또는 Bytebase를 멀티 DB·드리프트 감지용으로 얹는 패턴도 늘었다.
12.5 큰 테이블이 핵심 (10억 row+)
- 어떤 마이그레이션 도구를 쓰든, 큰 테이블 변경은 gh-ost·pt-osc·pg-osc로 분리.
- Bytebase Enterprise의 자동 라우팅 또는 수동 실행.
- 마이그레이션 도구는 lint·dry-run에서 큰 테이블 변경을 미리 잡아 경고해야 함.
12.6 멀티 클라우드·멀티 DB 엔진 (Postgres + MySQL + Snowflake 등)
- Bytebase 또는 Liquibase — 가장 폭넓은 엔진 지원.
- Atlas도 멀티 DB 지원이지만 Oracle·DB2·Snowflake 같은 곳은 Liquibase가 더 성숙.
13장 · 안티 체크리스트
피해야 할 패턴들.
- 두 개의 마이그레이션 도구를 한 DB에 동시에 운영 — Prisma Migrate가 만든
_prisma_migrations과 Flyway의flyway_schema_history가 동시에 존재. 진실의 원천이 둘. - 자동 diff를 100% 신뢰 — 컬럼 리네임은 drop + add로 인식된다. 사람이 본다.
- rollback 없이 destructive change —
DROP COLUMN을 production 직전에 머지하고, 문제 생기면 백업에서 복원? 안 된다. expand-contract로 풀어야. - 큰 테이블에 비조건적 DDL — 락이 길게 걸린다.
NOT NULL도입 전 백필 +NOT VALID패턴. - 드리프트를 감지 안 하는 production — 누군가
ALTER TABLE을 직접 친 사실을 1년 뒤에 알면 늦다. - CI에서 마이그레이션 lint 없음 —
atlas migrate lint또는 Liquibase/Bytebase 룰. 사람 리뷰가 만능이 아니다. - dev/staging/prod 사이 스키마 불일치 방치 — 한 환경에서만 hotfix 적용. 다음 마이그레이션이 어디서 깨질지 모름.
14장 · 실전 권장 워크플로 (참고용)
작은 팀, TS 스택을 가정한 한 가지 권장 워크플로.
- 스키마는 Drizzle 코드 (또는 Prisma schema). ORM과 한 묶음.
- 마이그레이션 SQL은 자동 생성 + 사람 리뷰.
drizzle-kit generate또는prisma migrate dev로 생성된 SQL 파일을 PR로. - CI에서
atlas migrate lint또는 비슷한 lint — 위험 DDL 사전 차단. - production은
migrate deploy(Prisma) 또는drizzle-kit migrate. 셰도우 DB 사용. - Atlas Cloud(또는 동등)로 드리프트 감지 — 누가 직접 친 ALTER를 잡는다.
- 큰 테이블 변경은 gh-ost/pg-osc로 분리 — 마이그레이션 파일은 placeholder만 남기고, 실제 변경은 runbook에 적힌 외부 도구로.
- expand-contract 패턴 의무화 — destructive change는 절대 한 PR로 가지 않는다.
엔터프라이즈라면 위에 Bytebase의 승인 게이트가 추가된다. 자바 진영이라면 Liquibase가 1, 2번을 대체한다.
에필로그 — 도구는 정책의 표현이지 정책 자체가 아니다
DB 마이그레이션 도구 선택은 "declarative냐 imperative냐"의 종교 전쟁이 아니다. 팀이 무엇을 보호하려고 하는지의 함수다.
- 작은 팀, 빠른 반복 — declarative·ORM 통합(Drizzle Kit·Prisma·Atlas).
- 엔터프라이즈·감사 — imperative·명시적 rollback(Liquibase·Flyway).
- 다중 DB·다중 팀 — 리뷰 워크플로(Bytebase) + lint(Atlas).
- 큰 테이블 — 마이그레이션 도구와 별도로 온라인 DDL 도구(gh-ost·pg-osc).
2026년 5월의 풍경에서 가장 큰 변화는 두 가지다.
- Atlas의 부상 — declarative + lint + 드리프트 감지를 한 도구로 묶어 점유율을 빠르게 늘리고 있다. Terraform이 인프라에 한 일을 DB에 하고 있다는 평가가 과장은 아니다.
- AI 어시스턴스가 카테고리 — Bytebase·Liquibase Hub·Atlas 모두 LLM 기반 리뷰·자연어 변환을 붙였다. 마이그레이션 lint는 더 이상 룰 기반만이 아니다.
결정 체크리스트
- 팀 규모는? — 1~3인이면 ORM 마이그레이션, 50인+면 Bytebase.
- 멀티 DB·멀티 환경인가? — Yes면 Atlas·Bytebase·Liquibase.
- 자바/스프링 위주인가? — Yes면 Flyway·Liquibase.
- 큰 테이블이 있는가? — Yes면 어떤 도구든 gh-ost·pg-osc 추가.
- 드리프트 감지가 필요한가? — Yes면 Atlas Cloud 또는 Bytebase.
- 컴플라이언스(감사·rollback)가 핵심인가? — Yes면 Liquibase.
- 학습 곡선 최소화? — ORM의 자체 마이그레이션 도구.
안티 패턴 요약
- 자동 diff를 100% 신뢰.
- 한 DB에 두 마이그레이션 도구 공존.
- rollback 없이 destructive change.
- 큰 테이블에 비조건적 NOT NULL.
- CI에서 마이그레이션 lint 없음.
- 드리프트 감지 없는 production.
- 환경 간 스키마 불일치 방치.
다음 글 예고
다음 글 후보: Atlas 한 달 써본 후기 — HCL이 정말 SQL보다 좋은가, gh-ost vs pt-online-schema-change 실측 — 1억 row 테이블에서, Bytebase + GitHub Actions로 만드는 DB 변경 자동화 파이프라인.
"스키마는 사실이고, 마이그레이션은 그 사실을 옮기는 길이다. 도구는 길을 안전하게 만들어 줄 뿐, 길 자체를 대신 걸어주진 않는다."
— DB 마이그레이션 도구 2026, 끝.
참고 / References
- Atlas — Modern DB Migration
- Atlas GitHub — ariga/atlas
- Atlas Schema Monitoring
- Atlas Migrate Lint
- Bytebase 공식
- Bytebase GitHub
- Bytebase SQL Review Rules
- Skeema — Declarative MySQL/Postgres schema management
- Skeema GitHub
- Liquibase 공식
- Liquibase GitHub
- Flyway 공식
- Flyway GitHub
- Prisma Migrate Documentation
- Drizzle Kit Documentation
- gh-ost — GitHub's online schema migration for MySQL
- pt-online-schema-change — Percona Toolkit
- pg-osc — Postgres online schema change
- pg_repack — Reorganize tables in PostgreSQL
- Sqitch — Sane database change management
- dbmate — Database migration tool
- PostgreSQL Wiki — Locking
- GitHub Engineering — gh-ost: triggerless schema changes