[DB-010][실무] 데이터 잃지 않고 표 구조 바꾸기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[DB-010][실무] 데이터 잃지 않고 표 구조 바꾸기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 116회 작성일 26-09-04 21:36

본문

[이번 수업]
운영 데이터베이스의 표 구조를 버전 순서대로 바꾸는 스키마 마이그레이션을 배웁니다. 애플리케이션과 데이터가 함께 이동하도록 계획합니다.

[선수지식]
CREATE TABLE, ALTER TABLE, 트랜잭션을 알아야 합니다. 스키마는 표·열·키·제약조건을 정의한 설계입니다.

[학습목표]
1. 마이그레이션 버전과 적용 상태를 관리합니다.
2. 확장→전환→정리 순서로 호환성을 유지합니다.
3. 잠금·실행 시간·복구 방법을 미리 확인합니다.

[핵심개념]
마이그레이션은 스키마 변경을 번호가 붙은 코드로 기록해 순서대로 한 번씩 적용하는 방식입니다. 운영에서 직접 명령을 실행하면 다른 환경에 재현하기 어렵습니다. 변경 파일, 적용 버전, 검증 쿼리, 예상 시간과 실패 대응을 함께 검토합니다.

서비스를 계속 운영하려면 확장과 정리를 나눕니다. 먼저 기존 코드가 무시할 수 있는 새 열을 추가합니다. 새 코드가 옛 구조와 새 구조를 함께 다루게 배포하고 데이터를 작은 묶음으로 채웁니다. 검증 뒤 읽기를 새 구조로 바꾸고 이전 코드가 사라진 다음 옛 열을 제거합니다. 변경과 삭제를 한 배포에 묶으면 이전 버전이 실패할 수 있습니다.

DDL은 표 구조를 바꾸는 SQL입니다. 제품과 명령에 따라 강한 잠금, 표 재작성, 긴 트랜잭션이 생깁니다. 같은 제품·버전과 비슷한 데이터 양에서 잠금 시간과 디스크 여유를 측정합니다. 큰 인덱스와 데이터 채우기는 지원되는 온라인 방식과 작은 배치를 검토합니다.

지원되는 변경은 트랜잭션으로 묶되 제품별 예외를 확인합니다. 모든 변경이 쉽게 역방향으로 돌아가지는 않아 앞으로 고치는 롤포워드가 더 안전할 수 있습니다. 배포 전 백업과 실제 복원을 확인합니다.

[따라하기]
SQLite로 두 버전을 적용합니다. migrate.py로 저장하세요.

```python
import sqlite3

MIGRATIONS = {
    1: ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)"],
    2: ["ALTER TABLE users ADD COLUMN email TEXT"],
}

conn = sqlite3.connect("demo.db")
current = conn.execute("PRAGMA user_version").fetchone()[0]

for version, statements in MIGRATIONS.items():
    if version <= current:
        continue
    with conn:
        for statement in statements:
            conn.execute(statement)
        conn.execute(f"PRAGMA user_version = {version}")
    current = version

columns = [row[1] for row in conn.execute("PRAGMA table_info(users)")]
print(f"schema_version={current}")
print("columns=" + ",".join(columns))
conn.close()
```

macOS/Linux는 `python3 migrate.py`, Windows PowerShell은 `py migrate.py`로 실행합니다. 예상 결과입니다.

```text
schema_version=2
columns=id,name,email
```

다시 실행해도 ALTER TABLE을 반복하지 않습니다. `user_version`은 애플리케이션이 쓰는 정수이며 자동으로 오르지 않습니다. f-string에는 코드에 고정한 정수만 들어갑니다. 사용자 입력은 SQL 문자열에 붙이지 말고 매개변수로 전달합니다.

[흔한 실수]
운영에서 먼저 실행하거나 구조 변경과 대량 수정을 한 트랜잭션에 묶기 쉽습니다. 새 코드 전에 NOT NULL을 강제하거나 옛 열을 지우지 않습니다. 적용 뒤 열·제약조건·행 수와 앱 동작을 확인합니다.

[보안 주의]
마이그레이션 계정에는 필요한 객체 변경 권한만 주고 앱 계정과 분리합니다. 파일에 비밀번호나 개인정보를 넣지 않고 데이터 보정은 매개변수화합니다. 백업 접근과 보존 기간도 제한합니다. 실습은 본인 소유의 로컬 또는 허가된 격리 환경에서만 수행합니다.

[직접 해볼 과제]
버전 3에 `ALTER TABLE users ADD COLUMN status TEXT DEFAULT 'active'`를 추가하세요. 실행 뒤 버전과 열을 보고 다시 실행해 중복 오류가 없는지 확인합니다.

[확인문제]
1. 스키마 변경을 버전 파일로 관리하는 이유는 무엇인가요?
2. 새 열 추가와 옛 열 삭제를 다른 배포로 나누는 이유는 무엇인가요?
3. 운영 적용 전에 잠금 시간과 복원을 확인해야 하는 이유는 무엇인가요?

[다음 학습]
다음 과정 OS-010에서는 systemd와 launchd 자동 실행을 배웁니다. DB-011에서는 백업·복원을 다룹니다.

[공식 참고 자료]
- SQLite ALTER TABLE: https://www.sqlite.org/lang_altertable.html
- SQLite user_version PRAGMA: https://www.sqlite.org/pragma.html#pragma_user_version
- PostgreSQL ALTER TABLE: https://www.postgresql.org/docs/current/sql-altertable.html
- PostgreSQL 명시적 잠금: https://www.postgresql.org/docs/current/explicit-locking.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
4,006
어제
6,862
최대
16,772
전체
769,957
Copyright © 소유하신 도메인. All rights reserved.