개인정보처리방침© 2026 DEV BAK - 기술블로그. All rights reserved.
DEV BAK - 기술블로그
포스트 검색
Database

PostgreSQL 스키마를 Git처럼 관리하기 — Atlas와 GitHub Actions로 선언적 Diff, 린팅, Drift 감지, 자동 롤백까지

"야, 누가 프로덕션 DB에서 컬럼 직접 지웠어?" — 팀 슬랙에 이런 메시지가 뜨는 순간, 그날의 배포 계획은 전부 날아갑니다. 마이그레이션 파일은 충실히 쌓여 있는데, 누군가 핫픽스랍시고 프로덕션 DB에서 직접 ALTER TABLE을 날리면 파일과 실제 스키마가 조용히 어긋나기 시작합니다. 그 어긋남은 다음 배포 때까지 모르다가 폭탄이 됩니다.

이 문제의 본질은 스키마의 "의도된 상태"와 "실제 상태"를 추적하는 단일 소스가 없다는 것입니다. Atlas는 바로 이 지점을 파고듭니다. Terraform이 인프라를 선언적으로 관리하듯, Atlas는 데이터베이스 스키마를 선언적으로 관리합니다. 개발자가 원하는 스키마 상태를 정의하면 Atlas가 현재 DB 상태와 비교해 실행할 SQL을 자동으로 계산합니다.

이 글에서는 Atlas를 GitHub Actions와 연결해 PR 단계의 마이그레이션 린팅, 프로덕션 Drift 감지, 배포 실패 시 자동 롤백까지 이어지는 파이프라인을 어떻게 구성하는지 살펴봅니다. 도구 소개보다는 "왜 이 구조인가"에 더 집중해서, 현업에서 실제로 판단이 필요한 지점들을 함께 짚어봅니다.


핵심 개념

이 글에서 다루는 방식: 버전드 마이그레이션

Atlas는 두 가지 워크플로우를 지원합니다. 선언적 방식은 atlas schema apply를 사용해 schema.hcl에 정의된 목표 상태를 현재 DB와 직접 비교·적용합니다. 별도의 마이그레이션 파일 없이 Atlas가 diff를 계산해 바로 실행합니다. 버전드 방식은 atlas migrate diff로 변경을 감지해 번호가 붙은 마이그레이션 파일을 생성하고, atlas migrate apply로 순서대로 실행합니다.

이 글은 버전드 방식을 기준으로 설명합니다. 변경 이력이 Git 히스토리에 남아 감사 추적이 가능하고, PR 리뷰에서 정확히 어떤 SQL이 실행될지 검토할 수 있으며, 특정 버전으로 정확하게 롤백할 수 있기 때문입니다. 기존 Flyway·Liquibase 팀이 Atlas로 이전하는 경우에도 자연스러운 중간 지점이 됩니다.

선언적 스키마 vs 버전 기반 마이그레이션

핵심 차이는 "현재 스키마가 무엇인가"를 누가, 어떻게 알고 있느냐입니다. 버전 기반 도구는 V001__init.sql, V002__add_column.sql처럼 변경 이력을 파일로 쌓습니다. 현재 스키마를 알려면 이 파일들을 처음부터 재생(replay)해야 하고, 누군가 중간에 직접 DB를 건드렸다면 파일과 실제 DB가 어긋나도 도구가 감지하지 못합니다.

Atlas는 스키마 자체를 소스 오브 트루스(source of truth)로 삼습니다. schema.hcl에 원하는 최종 상태를 정의하면, Atlas가 현재 DB를 직접 인트로스펙트해서 diff를 계산하고 필요한 SQL만 생성합니다.

다이어그램 1

버전드 방식에서도 Atlas의 diff 계산 능력을 활용할 수 있습니다. schema.hcl에 목표 상태를 정의하고 atlas migrate diff를 실행하면 변경 사항을 자동으로 감지해 번호가 붙은 마이그레이션 파일을 생성합니다. 이렇게 schema.hcl은 "의도된 최종 상태"를, migrations/ 디렉토리는 "변경 이력"을 담당하는 구조가 됩니다.


마이그레이션 린팅

atlas migrate lint는 마이그레이션 파일에 대한 정적 분석 도구입니다. 파괴적 변경·락 위험·보안 패턴 등을 탐지하는 다수의 내장 분석기가 포함되어 있습니다(전체 분석기 목록 참조).

분석기 카테고리 탐지 예시
파괴적 변경 테이블·컬럼·인덱스 삭제
데이터 의존 수정 기본값 없는 NOT NULL 컬럼 추가
락 위험 테이블 재작성을 유발하는 ALTER
SQL 인젝션 패턴 동적 쿼리 내 인젝션 취약점
트랜잭션 중첩 오류 잘못된 BEGIN/COMMIT 중첩

GitHub Actions와 연동하면 PR이 열릴 때 린팅이 자동으로 실행되고 결과가 PR 코멘트로 달립니다. 코드 리뷰에서 사람이 놓치기 쉬운 DB 레벨 위험을 CI가 대신 잡아주는 역할입니다.

팀 컨벤션을 강제하는 커스텀 린트 규칙도 정의할 수 있습니다 — "외래 키에는 반드시 ON DELETE 옵션을 명시", "인덱스 없는 FK 컬럼 금지" 같은 규칙이요. 다만 이 기능은 현재 엔터프라이즈·유료 플랜 전용입니다. 내장 분석기는 무료 티어에서도 계속 쓸 수 있으니, 팀 예산에 따라 판단이 필요한 부분입니다.


Drift 감지

Drift(드리프트)는 표준 마이그레이션 프로세스 바깥에서 스키마가 변경되는 현상입니다. "누가 핫픽스로 직접 ALTER TABLE을 날렸다"가 대표적인 케이스입니다. 이 변경은 Git에 없고, 마이그레이션 이력에도 없습니다.

Atlas의 Drift 감지는 주기적으로 실제 DB 스키마를 인트로스펙트해서 의도된 상태(스키마 파일)와 비교합니다. 차이가 발견되면 HCL/SQL 형식의 diff를 출력합니다.

다이어그램 2

ERD 시각화 대시보드 등 고급 드리프트 모니터링 기능은 Atlas Cloud(SaaS) 연동이 필요합니다. CLI만으로도 지속적인 드리프트 감지 파이프라인을 구성할 수 있고, 이 글에서는 그 방법을 다룹니다.


롤백: 동적 역방향 SQL 계산

전통적인 도구에서 롤백하려면 미리 down 파일을 작성해둬야 합니다. V003__add_column.sql을 만들면 V003__add_column_down.sql도 같이 만들어야 하는 식이죠. 이걸 깜빡하거나 잘못 작성하면 롤백 자체가 실패합니다.

Atlas는 다른 방향으로 접근합니다. atlas migrate down이 실행될 때 현재 DB 상태를 기반으로 역방향 SQL을 동적으로 계산합니다. 미리 작성된 down 파일이 필요 없습니다. 이 동적 계산 능력을 GitHub Actions의 if: failure() 조건과 결합하면, 배포 실패 시 자동으로 롤백이 트리거되는 파이프라인을 만들 수 있습니다.

PostgreSQL은 트랜잭션 DDL을 지원하기 때문에 Atlas가 전체 롤백을 단일 트랜잭션으로 감쌉니다. 중간에 실패하면 전체가 롤백되므로, 반쯤 적용된 스키마 변경이 남는 상황을 피할 수 있습니다.

단, 롤백은 구조적으로 복잡합니다. 특히 데이터 변환(backfill)이 포함된 마이그레이션이라면 스키마 롤백만으로는 부족하고, 데이터 복구 로직도 함께 설계해야 합니다. Atlas 공식 블로그의 "The Myth of Down Migrations"와 "GitOps 롤백의 현실적 고려사항"을 참고하면 도움이 됩니다.


실전 적용

1단계: atlas.hcl 설정

프로젝트 루트에 atlas.hcl 설정 파일을 만들어 데이터 소스와 환경을 정의합니다.

hcl
# atlas.hcl
variable "db_url" {
  type    = string
  default = getenv("DATABASE_URL")
}
 
env "local" {
  src = "file://schema.hcl"
  url = var.db_url
  dev = "docker://postgres/15/dev"
  migration {
    dir = "file://migrations"
  }
}
 
env "production" {
  url = var.db_url
  migration {
    dir = "file://migrations"
  }
}

dev에 Docker URL을 지정하면 Atlas가 린팅이나 diff 계산 시 임시 컨테이너를 스핀업해서 사용합니다. 실제 개발 DB를 건드리지 않고 안전하게 계산할 수 있는 설정입니다.


2단계: 스키마 정의

스키마 변경은 schema.hcl로 정의하고 atlas migrate diff로 마이그레이션 파일을 자동 생성하는 흐름입니다.

hcl
# schema.hcl
table "users" {
  schema = schema.public
  column "id" {
    type = bigserial
  }
  column "email" {
    type = varchar(255)
    null = false
  }
  column "created_at" {
    type    = timestamptz
    default = sql("now()")
  }
  primary_key {
    columns = [column.id]
  }
  index "users_email_idx" {
    columns = [column.email]
    unique  = true
  }
}

이 파일을 수정하고 아래 명령을 실행하면 migrations/ 디렉토리에 타임스탬프가 붙은 SQL 파일이 자동으로 생성됩니다.

bash
atlas migrate diff --env local --name add_users_table

3단계: GitHub Actions 파이프라인 구성

PR 오픈부터 머지 후 배포, 실패 시 자동 롤백까지의 전체 흐름입니다. 여기서 중요한 아키텍처 포인트가 하나 있습니다. GitHub Actions Runner가 린팅과 마이그레이션 적용을 직접 실행하며, Atlas Cloud는 마이그레이션 버전의 레지스트리 역할만 담당합니다. 프로덕션 DB에는 Runner가 직접 접속하는 것이지, Atlas Cloud가 중개하는 구조가 아닙니다.

다이어그램 3

이 흐름을 구현하는 워크플로우는 두 파일로 분리합니다.

PR 검증용 워크플로우:

yaml
# .github/workflows/atlas-ci.yml
name: Atlas CI
 
on:
  pull_request:
    paths:
      - 'migrations/**'
      - 'schema.hcl'
 
jobs:
  lint:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: dev
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
 
    steps:
      - uses: actions/checkout@v4
 
      - uses: ariga/setup-atlas@v0
        with:
          cloud-token: ${{ secrets.ATLAS_CLOUD_TOKEN }}
 
      - uses: ariga/atlas-action/migrate/lint@v1
        with:
          dir: 'file://migrations'
          dev-url: 'postgres://postgres:postgres@localhost:5432/dev?sslmode=disable'
          config: './atlas.hcl'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

GITHUB_TOKEN을 전달해야 린팅 결과가 PR 코멘트로 자동으로 달립니다.

배포 워크플로우 (자동 롤백 포함):

yaml
# .github/workflows/atlas-deploy.yml
name: Atlas Deploy
 
on:
  push:
    branches:
      - main
    paths:
      - 'migrations/**'
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - uses: ariga/setup-atlas@v0
        with:
          cloud-token: ${{ secrets.ATLAS_CLOUD_TOKEN }}
 
      - name: Push migration to Atlas Cloud
        uses: ariga/atlas-action/migrate/push@v1
        with:
          dir: 'file://migrations'
          dir-name: 'myapp'
          config: './atlas.hcl'
 
      - name: Apply to production
        id: apply
        uses: ariga/atlas-action/migrate/apply@v1
        with:
          url: ${{ secrets.DATABASE_URL }}
          dir-name: 'myapp'
          config: './atlas.hcl'
 
      - name: Auto rollback on failure
        if: failure() && steps.apply.outcome == 'failure'
        run: |
          echo "배포 실패 감지 — 마지막 마이그레이션을 롤백합니다"
          atlas migrate down \
            --url "${{ secrets.DATABASE_URL }}" \
            --dir "file://migrations" \
            --amount 1

apply 스텝이 실패하면 if: failure() 조건이 충족되어 롤백 스텝이 자동으로 실행됩니다. 다만 이 롤백은 스키마 변경만 되돌리므로, 데이터 변환(backfill)이 포함된 마이그레이션에서는 별도의 데이터 복구 절차도 함께 준비해야 합니다.


4단계: Drift 감지 스케줄 설정

atlas schema diff는 diff가 존재해도 기본적으로 exit code 0으로 종료합니다. 즉, 아무 처리 없이 이 명령만 실행하면 드리프트가 있어도 워크플로우가 실패하지 않습니다. 드리프트 발견 시 실제로 파이프라인이 실패하도록 만들려면, 출력값을 캡처해서 비어 있지 않을 때 직접 exit 1을 호출해야 합니다.

또한 atlas schema diff --to "file://schema.hcl" 형식으로 HCL 파일과 비교할 때는 HCL 스키마를 정규화할 dev DB가 필요합니다. 아래 예시는 서비스 컨테이너를 띄워 이 역할을 맡깁니다.

yaml
# .github/workflows/atlas-drift.yml
name: Drift Detection
 
on:
  schedule:
    - cron: '0 * * * *'  # 매 시간 실행
 
jobs:
  detect:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: dev
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432
 
    steps:
      - uses: actions/checkout@v4
 
      - uses: ariga/setup-atlas@v0
        with:
          cloud-token: ${{ secrets.ATLAS_CLOUD_TOKEN }}
 
      - name: Run drift detection
        run: |
          DIFF=$(atlas schema diff \
            --config ./atlas.hcl \
            --from "${{ secrets.DATABASE_URL }}" \
            --to "file://schema.hcl" \
            --dev-url "postgres://postgres:postgres@localhost:5432/dev?sslmode=disable")
          if [ -n "$DIFF" ]; then
            echo "스키마 드리프트가 감지되었습니다:"
            echo "$DIFF"
            exit 1
          fi

드리프트가 발견되면 exit 1로 워크플로우가 실패하고 GitHub에서 알림이 옵니다. Slack 연동 스텝을 추가하면 팀 채널로 바로 메시지를 보낼 수도 있습니다.


5단계: 롤백 시나리오

배포 파이프라인 밖에서 수동으로 롤백이 필요한 경우에는 atlas migrate down을 직접 실행합니다.

bash
# 실행 전 어떤 SQL이 적용될지 먼저 확인
atlas migrate down --dry-run \
  --url "$DATABASE_URL" \
  --dir "file://migrations" \
  --amount 1
 
# 확인 후 실제 롤백 실행
atlas migrate down \
  --url "$DATABASE_URL" \
  --dir "file://migrations" \
  --amount 1
 
# 특정 버전까지 롤백
atlas migrate down \
  --url "$DATABASE_URL" \
  --dir "file://migrations" \
  --to-version "20250601120000"

--dry-run으로 계획을 먼저 확인한 뒤 진행하는 것을 권장합니다. Atlas는 현재 DB 상태를 기반으로 역방향 SQL을 동적으로 계산하므로, 미리 작성해둔 down 파일이 없어도 됩니다.


장단점 분석

장점

항목 설명
선언적 워크플로우 목표 상태만 정의하면 마이그레이션 SQL 자동 생성
동적 롤백 미리 작성된 down 파일 없이 역방향 SQL 자동 계산
내장 분석기 파괴적 변경·락 위험·보안 패턴 등 CI에서 자동 탐지
GitHub Actions 네이티브 PR 코멘트 자동화, pre-approval 플로우 내장
PostgreSQL 트랜잭션 DDL 실패 시 전체 마이그레이션 자동 롤백 보장
다중 ORM 지원 Ent, GORM, SQLAlchemy 스키마에서 직접 diff 계산
Drift 감지 의도치 않은 스키마 변경 즉각 알림
pgvector 지원 LLM 생태계 벡터 컬럼 네이티브 관리

단점 및 고려사항

항목 설명
현재 유료 전용 기능 커스텀 린트 규칙, 고급 드리프트 모니터링은 엔터프라이즈·유료 플랜 전용
학습 곡선 HCL DSL과 선언적 사고방식 전환에 초기 비용 필요
데이터 마이그레이션 미지원 스키마 변경은 자동화되지만 backfill 로직은 직접 작성 필요
Atlas Cloud 의존성 드리프트 대시보드, Registry 등 고급 기능은 SaaS 연동 필요
프로덕션 롤백의 현실 데이터 변환 포함 시 스키마 롤백만으로 불충분한 경우 있음

실무에서 자주 보이는 실수

1. dev-url 없이 린팅 시도

atlas migrate lint는 마이그레이션 계획을 검증하기 위해 임시 DB가 필요합니다. dev-url을 지정하지 않으면 일부 분석기가 동작하지 않습니다. CI에서 PostgreSQL 서비스 컨테이너를 띄우거나 docker://postgres/15/dev 형식의 Docker URL을 넘겨주는 것이 안정적입니다.

2. Atlas가 생성한 마이그레이션 파일을 직접 수동 편집

수동으로 내용을 바꾸면 migrations/atlas.sum 체크섬 파일과 불일치가 발생해 검증이 실패합니다. 변경이 필요하다면 해당 마이그레이션 파일과 이후 파일을 모두 삭제하고 atlas migrate diff로 새로 생성하는 것이 가장 안전합니다.

불가피하게 수동 편집을 했다면 atlas migrate hash --force를 실행하면 됩니다. 이 명령은 현재 파일 상태를 기준으로 migrations/atlas.sum 파일을 강제로 재작성합니다. --force 없이 atlas migrate hash만 실행하면 불일치 여부만 확인하고 파일은 변경하지 않습니다. 단, --force로 체크섬을 덮어쓰면 이전 상태 검증이 불가능해지므로, 팀 전체가 변경 사실을 인지한 상태에서 사용해야 합니다.

3. schema.hcl과 마이그레이션 파일의 동기화 실패

schema.hcl을 수정하고 atlas migrate diff를 실행하지 않으면 두 소스가 어긋납니다. CI에서 atlas migrate diff로 신규 변경사항이 없는지 검증하는 스텝을 추가해두면 이 문제를 예방할 수 있습니다.


마치며

**Atlas + GitHub Actions 조합의 핵심 가치는 "스키마 변경을 코드 변경과 동일한 검증 프로세스로 통과시키는 것"**입니다. PR이 열리면 린터가 파괴적 변경을 잡고, 머지되면 버전이 Atlas Cloud에 등록되고, 배포되면 프로덕션에 적용됩니다. 배포가 실패하면 자동으로 롤백이 트리거됩니다. 그리고 누군가 몰래 DB를 건드리면 Drift 감지가 팀에 알려줍니다.

모든 기능을 한 번에 도입할 필요는 없습니다. 린팅 파이프라인부터 시작해서 안정화되면 Drift 감지를 추가하고, 그다음에 자동 롤백 스텝을 연결하는 단계적 접근이 현실적입니다. 가장 빠른 시작점은 atlas schema inspect --url "$DATABASE_URL" > schema.hcl로 현재 스키마를 파일로 가져오는 것입니다. 이 한 줄이 모든 자동화의 출발점이 됩니다.


참고 자료

  • Atlas 공식 문서
  • GitHub Actions 통합 공식 가이드
  • 선언적 방식 CI/CD 단계별 가이드
  • Schema Drift Detection 공식 문서
  • Down Migrations 공식 문서
  • 마이그레이션 린트 공식 문서
  • Migration Analyzers 목록
  • v0.31 릴리스 노트: Custom schema rules, pgvector
  • v0.38 릴리스 노트: Linting Analyzers, PII Detection, Migration Hooks
  • 동적 롤백 설계 배경: The Myth of Down Migrations
  • GitOps 롤백의 현실적 고려사항
  • PR 사전 승인 워크플로우
  • Atlas vs Flyway, Liquibase, ORM 도구 비교
  • GitHub — ariga/atlas
  • Palark의 실제 운영 사례 리뷰
  • 2026년 데이터베이스 CI/CD 도구 트렌드
#PostgreSQL#Atlas#GitHub Actions#Database Migration#Drift Detection#Schema Management
공유하기

목차

핵심 개념이 글에서 다루는 방식: 버전드 마이그레이션선언적 스키마 vs 버전 기반 마이그레이션마이그레이션 린팅Drift 감지롤백: 동적 역방향 SQL 계산실전 적용1단계: atlas.hcl 설정2단계: 스키마 정의3단계: GitHub Actions 파이프라인 구성4단계: Drift 감지 스케줄 설정5단계: 롤백 시나리오장단점 분석장점단점 및 고려사항실무에서 자주 보이는 실수마치며참고 자료

추천 포스트

ClickHouse를 Node.js 백엔드에 연결하기 — 수억 건 이벤트 실시간 집계 API 실전 가이드
Database

ClickHouse를 Node.js 백엔드에 연결하기 — 수억 건 이벤트 실시간 집계 API 실전 가이드

어느 날 팀 채널에 알림이 울립니다. "대시보드 로딩이 30초 넘어요." 이벤트 테이블에 쌓인 행이 5억을 넘어가면서 PostgreSQL의 GROUP BY 쿼리가 타임아웃을 내기 시작한 겁니다. 인덱스도 달아보고, 파티셔닝도 해봤지만 데이터는 계속 쌓이고 쿼리는 점점…

2026년 07월 13일읽는 데 21분
Kafka 이벤트를 서브초 쿼리로 — ClickHouse Materialized View·Projections로 초당 수만 건 집계 파이프라인 설계하기
Database

Kafka 이벤트를 서브초 쿼리로 — ClickHouse Materialized View·Projections로 초당 수만 건 집계 파이프라인 설계하기

실시간 대시보드를 처음 붙였을 때 가장 많이 듣는 말이 있습니다. "쿼리가 왜 이렇게 느려요?" 초당 수만 건의 이벤트를 Kafka에서 받아 저장해두고 보니, 대시보드 SELECT 한 번에 10초가 걸리는 현실을 마주하게 되죠. 인덱스를 더 추가하고 집계 쿼리를 최적화…

2026년 07월 13일읽는 데 23분
PostgreSQL 분석 집계 병목, ClickHouse + Node.js 파이프라인으로 최대 100배 빠르게 해소하기
Database

PostgreSQL 분석 집계 병목, ClickHouse + Node.js 파이프라인으로 최대 100배 빠르게 해소하기

페이지뷰·버튼 클릭·구매 퍼널을 PostgreSQL RDS에 쌓다 보면, 일 단위 집계 쿼리가 30초를 넘기는 시점이 반드시 옵니다. 인덱스를 추가하고 파티셔닝을 적용해도, 행이 수억 건을 넘어서면 GROUP BY 쿼리의 응답 시간은 단순 최적화로는 더 이상 눌러지지…

2026년 07월 13일읽는 데 22분
브라우저 속 PostgreSQL: PGlite 실전 가이드
Database

브라우저 속 PostgreSQL: PGlite 실전 가이드

인터넷 연결 없이도 데이터를 온전히 다루는 앱을 만들고 싶었던 적이 있으신가요? 저도 처음엔 서버 API 호출 실패를 어떻게 처리할까 고민하다가, 결국 복잡한 캐싱 레이어를 끼워 넣고 "오프라인 지원"이라는 이름을 붙인 적이 있습니다. 그 방식의 문제는, 네트워크가 끊…

2026년 07월 12일읽는 데 22분
Drizzle ORM으로 타입 안전한 복잡 쿼리 작성하기 — 관계형 쿼리, 마이그레이션, Edge 런타임 대응까지
Database

Drizzle ORM으로 타입 안전한 복잡 쿼리 작성하기 — 관계형 쿼리, 마이그레이션, Edge 런타임 대응까지

Prisma를 쓰다 보면 불편함이 생기는 지점이 있습니다. 여러 테이블에 걸친 복잡한 include 체인을 쓸 때 N+1 쿼리 문제나 비효율적인 JOIN 전략이 발생해도 Prisma가 생성하는 SQL을 직접 조정하기 어렵고, Cloudflare Workers 같은 Ed…

2026년 07월 12일읽는 데 19분
SQLite를 글로벌 분산 DB로 — Turso + libSQL이 서버리스 엣지 아키텍처를 바꾸는 방식
Database

SQLite를 글로벌 분산 DB로 — Turso + libSQL이 서버리스 엣지 아키텍처를 바꾸는 방식

"SQLite? 그거 로컬 개발용 아니야?" — 솔직히 저도 작년까지 그렇게 생각했습니다. 프로덕션에서 SQLite를 쓴다고 하면 은근히 무시당하던 시절이 있었죠. 그런데 2024년을 기점으로 상황이 완전히 뒤집혔습니다. Cloudflare D1과 Turso가 프로덕션…

2026년 07월 12일읽는 데 24분