Sqldef: MySQL, PostgreSQL, SQLite용 멱등적 스키마 관리 도구
(sqldef.github.io)- SQL 스키마 간 차이(diff) 를 비교해 데이터베이스 마이그레이션을 관리하는 CLI 기반 도구
- 일반적인 SQL DDL 문법을 사용해 RDBMS 스키마를 관리할 수 있음
- MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, SQLite3 등 주요 데이터베이스를 지원
- 웹사이트에서는 WebAssembly 빌드를 활용한 온라인 데모를 통해 스키마 비교 및 DDL 생성 기능을 체험 가능
- 데이터베이스 변경 작업을 멱등적(idempotent) 으로 관리할 수 있어, 안정적인 스키마 동기화에 유용함
sqldef 개요
-
sqldef는 두 개의 SQL 스키마를 비교(diff)해 차이를 분석하고, 이를 기반으로 DDL 명령문을 생성하는 CLI 도구
- 사용자는 기존 스키마와 목표 스키마를 비교해 필요한 변경 사항을 자동으로 도출 가능
- 일반적인 SQL DDL 구문을 그대로 사용해 마이그레이션을 수행할 수 있음
- 지원 데이터베이스는 MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, SQLite3로 명시됨
온라인 데모 기능
- 웹사이트에는 Online Demo가 제공되어, 스키마 변경을 시각적으로 확인 가능
- “Enable DROP” 옵션을 통해 삭제 명령 포함 여부를 제어할 수 있음
- “Up (current → desired)” 섹션에서는 새 컬럼 추가, 인덱스 생성, 제약조건 추가 등의 예시 DDL을 표시
- “Down (desired → current)” 섹션에서는 제약조건 삭제 등의 역방향 변경 예시를 제공
작동 방식
- 온라인 데모는 sqldef의 WebAssembly 빌드를 사용해 브라우저 내에서 SQL 스키마 비교(diff)를 수행
- 두 스키마 간 차이를 계산하고, 그 결과로 필요한 DDL 명령문을 자동 생성
- GitHub 저장소 링크를 통해 WebAssembly 빌드 소스 확인 가능
Hacker News 의견들
-
Postgres용으로 더 포괄적인 커버리지를 원한다면 내가 만든 pgschema를 참고해볼 만함
작년 여름에 꽤 완성됐다고 생각했지만, 6개월 동안 사용자들이 제보한 100여 개의 이슈를 해결하면서 내가 얼마나 순진했는지 깨달았음- 정말 멋진 도구임. 우리 팀과 함께 PoC를 만들어볼 예정임
여러 데이터베이스 클러스터에서 불일치를 점검하는 기능도 지원되는지 궁금함 - Migra를 떠올리게 함
- 스키마 마이그레이션에는 좋아 보이는데, 실제 데이터를 옮겨야 할 때 update/insert 처리는 어떻게 되는지 궁금함
- Xata의 pg_roll도 고려해볼 만한 대안임
- 정말 멋진 도구임. 우리 팀과 함께 PoC를 만들어볼 예정임
-
SQLite로 테스트해봤는데, 외래 키 제약을 기존 테이블에 추가하는 어려운 마이그레이션에서는 유효하지 않은 SQL을 생성함
예를 들어ALTER TABLE books ADD CONSTRAINT fk_books_author FOREIGN KEY (author_id) REFERENCES authors (id)같은 구문은 SQLite에서 허용되지 않음
관련 문서는 SQLite ALTER TABLE 참고- 결국 외래 키를 추가하려면 컬럼을 드롭하고 다시 추가해야 하는 상황임?
-
나는 Atlas를 사용함
마이그레이션 기반과 스키마 기반 모두 장단점이 있어서, 한 프로젝트 안에서도 두 방식을 병행함
스키마 기반은 개발 속도를 높이고, 마이그레이션 기반은 더 신뢰감 있는 배포를 가능하게 함- Atlas 팀의 Ariel임. 로컬에서는 선언적 방식, 실제 환경에서는 버전 관리된 방식으로 병행하는 구성이 흔함
Atlas가 PR에서 자동으로 마이그레이션을 생성하기 때문에 대부분의 개발자는 직접 버전 워크플로를 다루지 않음
관련 문서: Declarative vs Versioned Workflows, Atlas Action - 나도 sqldef와 다른 대안들을 살펴보다가 Atlas를 발견했음
명시적인 migration flow 지원이 마음에 들었음. 실제 배포 전에 어떤 변경이 적용될지 정확히 알고 싶음
- Atlas 팀의 Ariel임. 로컬에서는 선언적 방식, 실제 환경에서는 버전 관리된 방식으로 병행하는 구성이 흔함
-
백그라운드 마이그레이션을 지원하는 좋은 도구가 있는지 궁금함
예를 들어, 대규모 테이블에 임시 nullable 컬럼을 추가하고, 새 코드가 그 컬럼에 데이터를 쓰기 시작한 뒤, 백그라운드에서 기존 데이터를 배치로 채우고 마지막에 non-nullable로 바꾸는 식의 작업임
이런 절차적 변경을 선언적으로 표현하고 코드와 함께 리뷰·테스트할 수 있는 도구가 있으면 좋겠음
지금은 대부분 임시 스크립트와 수동 배포 지침으로 처리함- 나는 직접 스키마 마이그레이션을 작성하는 편이지만, 주로 grate를 사용함
개발 환경에서 설정이 간단하고, FastEndpoints-SqlJobQueues 같은 예시도 있음
- 나는 직접 스키마 마이그레이션을 작성하는 편이지만, 주로 grate를 사용함
-
이 도구 정말 멋짐
덕분에 같은 기능을 만들려던 내 취미 프로젝트를 접을 수 있게 됨
대신 다른 이미 100번쯤 해결된 문제를 다루는 새 프로젝트를 시작할 예정임 — 예를 들어 systemd 로그를 모니터링하고 에러를 이메일로 보내는 간단한 툴 같은 것임 -
또 다른 마이그레이션 매니저가 아니라, 작고 유용한 도구라는 점이 반가웠음
SQL의 약점을 잘 보완해주는 느낌임. Spanner DDL처럼 선언적이었으면 좋겠다는 생각도 듦
Postgres에서는 스키마 스크립트를 idempotent하게 유지하려고 함.CREATE TABLE IF NOT EXISTS로 시작하고, 새 컬럼을 추가할 때는ALTER를 별도로 둠
하지만 시간이 지나면 스크립트가 복잡해지고, 안정화되면 ALTER 구문을 정리함
만약 이전 백업을 복원해야 할 때 이런 도구가 호환성을 빠르게 맞춰줄 수 있을 것 같음 -
Entity Framework나 sqitch/liquibase와 비교하면 어떤지 궁금함
선언적 접근은 이해하지만, 대규모 프로덕션 DB에서는 마이그레이션이 단순히 선언적이지 않음
이상적인 스키마 관리자는 쿼리 비용과 다운타임 최소화 전략을 이해해야 함
컬럼 추가나 인덱스 변경은 전체 테이블 스캔을 유발할 수 있음- 더 큰 문제는 데이터 자체가 마이그레이션의 일부일 수 있다는 점임
예를 들어 Fullname을 FirstName과 LastName으로 나누면 단순 diff로는 절반만 표현됨
EF Core에서는 Up/Down 메서드로 가역적 변환을 처리함
이런 개념 없이 데이터 변환을 어떻게 다루는지 궁금함
- 더 큰 문제는 데이터 자체가 마이그레이션의 일부일 수 있다는 점임
-
우리는 자체적으로 XML 기반의 변형 도구를 만들었음
XML이 SQL보다 파싱이 쉬워서, XML에 정의된 스키마와 DB를 비교해 필요한 변경만 적용함
Sybase SQLAnywhere를 사용했는데, materialized view가 얽혀 있을 때 컬럼 추가·삭제 시 뷰와 인덱스를 다시 만들어야 하는 복잡함이 있었음
그래서 안전장치를 넣어 컬럼 삭제는 명시적으로만 허용하고, 타입 변경도 안전한 경우에만 수행함
수백 개의 온프레미스 설치 환경에서 마이그레이션을 매우 간단하게 만들어줌
XML만 수정하면 도구가 알아서 처리하고, 필요할 때 기능을 추가할 수 있음 -
SQLite에서는 컬럼 삭제 처리가 잘 안 됨
최근 버전에서야 DROP COLUMN이 추가됐지만, 대부분의 기기에서는 여전히 지원되지 않음
예시에서x integer not null을 추가하고 DROP을 시도했지만, “-- Skipped” 메시지만 나옴
표준적인 방법은 임시 테이블을 만들어 데이터 복사 후 교체하는 것인데, 이 도구는 자동화하지 않음
제약 조건이 얽혀 있으면 실수하기 쉬운 부분이라 아쉬움
결국 쉬운 작업만 처리한다면 수동으로 하는 게 낫다는 생각임 -
이 도구는 빈 데이터베이스에서만 유용해 보임
데이터 마이그레이션은 다루지 못하고, 예를 들어 JSONB 컬럼을 구조화된 형태로 바꾸는 경우나 컬럼 삭제 후 역마이그레이션 시ADD COLUMN … NOT NULL을 생성하는 식으로 현실적인 데이터가 있는 테이블에서는 사용할 수 없음