데이터베이스 스키마를 손으로 직접 수정하면 어느 순간 "내 로컬에서는 되는데 서버에서는 안 된다"는 상황이 생긴다. Migration은 스키마 변경 이력을 SQL 파일로 남겨 코드처럼 버전 관리하는 방식이다. Supabase CLI는 이 흐름을 프로젝트 초기부터 자연스럽게 강제한다.
Migration은 데이터베이스의 상태를 한 버전에서 다음 버전으로 전환하는 SQL 스크립트다. 각 파일은 타임스탬프로 정렬되며, 순서대로 실행되어 스키마를 재현할 수 있다.
supabase/
└── migrations/
├── 20261001120000_create_users.sql
├── 20261010093000_add_profile_table.sql
└── 20261028150000_add_index_on_email.sql
Migration 파일명의 숫자 접두사는 YYYYMMDDHHmmss 형식의 타임스탬프로, 실행 순서를 보장한다.
supabase migration new add_profile_table
이 명령은 supabase/migrations/ 아래에 빈 SQL 파일을 생성한다. 파일 안에 스키마 변경 SQL을 직접 작성한다.
-- supabase/migrations/20261010093000_add_profile_table.sql
create table public.profiles (
id uuid primary key references auth.users(id) on delete cascade,
username text unique not null,
bio text,
created_at timestamptz default now()
);
alter table public.profiles enable row level security;
RLS(Row Level Security): Supabase에서 테이블별로 접근 권한을 행 단위로 제어하는 PostgreSQL 기능.
로컬 Supabase 인스턴스에 Migration을 반영할 때는 db push를 사용한다.
supabase db push
원격 프로젝트(Production)에 직접 적용할 경우에는 --linked 플래그와 함께 실행한다.
supabase db push --linked
로컬 DB를 깨끗하게 초기화하고 Migration을 처음부터 다시 실행하려면 db reset을 쓴다.
supabase db reset
이 명령은 로컬 DB를 드롭하고 모든 Migration을 순서대로 재실행한다. 프로덕션에는 절대 사용하지 않는다.
Migration 파일은 Git으로 관리한다. 아래는 전형적인 팀 협업 흐름이다.
[개발자 A] [개발자 B]
│ │
├─ migration new add_posts │
├─ SQL 작성 │
├─ git commit & push │
│ │
│ git pull ──┤
│ supabase db push┤
│ │
supabase/migrations/ 디렉터리를 Git에 포함시키는 것만으로 팀 전체가 동일한 스키마 이력을 공유한다. PR 리뷰 시 SQL 변경 내용도 diff로 검토할 수 있다.
| 명령어 | 용도 |
|---|---|
supabase migration new <name> | 새 Migration 파일 생성 |
supabase db push | 로컬 DB에 Migration 적용 |
supabase db push --linked | 원격(Production) DB에 적용 |
supabase db reset | 로컬 DB 초기화 후 전체 재실행 |
supabase migration list | 적용된 Migration 목록 확인 |
Migration을 도입하면 스키마 변경이 코드 리뷰의 일부가 된다. 데이터베이스 상태가 Git 히스토리로 추적되기 때문에 롤백 시점도 명확해진다.