TIL - 20260823

juni·2026년 8월 23일

TIL

목록 보기
437/468

0823 데이터베이스 실무 심화 (10/N): 1인 개발자 DB 운영 체크리스트와 성장 전략


✅ 1. 데이터베이스 실무 심화 마무리

  • 데이터베이스 실무 심화에서는 단순히 SQL 문법을 배우는 것이 아니라, 실제 운영 서비스에서 데이터를 안전하게 저장하고, 빠르게 조회하고, 장애 상황에서 복구할 수 있는 기준을 정리했습니다.
  • 웹서비스에서 DB는 가장 마지막에 남는 기록입니다.
  • 화면은 바꿀 수 있고, API도 수정할 수 있지만, 데이터가 꼬이거나 사라지면 복구 난이도가 급격히 올라갑니다.
테이블/관계 설계
  ↓
Prisma Schema / Migration
  ↓
Index / 검색 성능
  ↓
Transaction / 동시성
  ↓
상태 이력 / Audit Log
  ↓
Pagination / 관리자 목록 최적화
  ↓
Soft Delete / 보존 정책
  ↓
Backup / Restore
  ↓
EXPLAIN / 느린 쿼리 개선
  ↓
DB 운영 체크리스트

➕ 1-1. DB를 잘 다룬다는 것

단순히:
쿼리를 작성할 수 있다

실무적으로:
데이터 구조를 설계할 수 있다
운영 중 데이터 정합성을 지킬 수 있다
느린 쿼리를 분석할 수 있다
장애 시 복구 절차를 설명할 수 있다
개인정보와 이력을 안전하게 관리할 수 있다
  • 실무에서는 “SELECT를 잘 쓴다”보다 “데이터가 깨지지 않게 설계하고 운영한다”가 더 중요합니다.
  • 특히 1인 개발자는 DB 설계자, 백엔드 개발자, 운영자 역할을 동시에 하게 됩니다.

✅ 2. 지금까지 다룬 DB 주제 요약

➕ 2-1. 0813 PostgreSQL 기본 구조, 테이블과 관계 설계

  • 테이블, row, column, primary key, foreign key, 관계 설계, 상태값, snapshot, 제약조건, ERD를 정리했습니다.
핵심:
테이블은 책임이 명확해야 함
관계는 FK로 정합성 관리
상담/상품/관리자/유입 데이터를 연결
상담 당시 조건은 snapshot으로 보존

➕ 2-2. 0814 Prisma Schema 설계와 Migration 전략

  • Prisma Schema를 실제 DB 구조로 옮기는 기준, migration 파일 관리, 운영 migration 주의점을 정리하는 흐름이었습니다.
핵심:
schema.prisma는 DB 설계 문서에 가까움
migration은 운영 DB 변경 기록
운영에서 reset 금지
destructive migration은 단계적으로 처리

➕ 2-3. 0815 Index 기본, 검색/필터 성능 최적화

  • 관리자 검색, 필터, 정렬 성능을 위해 인덱스 후보와 복합 인덱스 기준을 정리하는 흐름이었습니다.
핵심:
인덱스는 조회 패턴 기준으로 추가
status + createdAt
productId + createdAt
source + createdAt
phoneNormalized

➕ 2-4. 0816 Transaction, 동시성 문제와 데이터 정합성

  • transaction, commit, rollback, optimistic lock, unique constraint, 상태 전이, idempotency, 외부 API 분리 기준을 정리했습니다.
핵심:
상태 변경 + 이력 저장은 transaction
중복 신청은 DB constraint까지 필요
외부 API는 transaction 안에 넣지 않기
Job/Outbox 구조 고려

➕ 2-5. 0817 상담/주문 상태 변경 이력과 Audit Log 설계

  • 상태 변경 이력, Audit Log, before/after, 관리자 작업 추적, 개인정보 마스킹, 정합성 점검 쿼리를 정리했습니다.
핵심:
현재 상태와 이력은 분리
누가/언제/무엇을 바꿨는지 기록
중요 변경은 Audit Log
개인정보는 로그에 무분별하게 저장 금지

➕ 2-6. 0818 Pagination, Sorting, 관리자 목록 조회 최적화

  • offset/cursor pagination, 안정적 정렬, 검색 조건, 목록/상세 API 분리, TanStack Query와 목록 캐시 전략을 정리했습니다.
핵심:
목록은 가볍게
상세는 별도 API
createdAt + id 정렬
limit 최대값 제한
엑셀은 ExportJob으로 분리

➕ 2-7. 0819 Soft Delete, 복구, 데이터 보존 정책

  • hard delete와 soft delete, deletedAt, 복구, 익명화, 보존 기간, cleanup job, dry run, cascade delete 주의점을 정리했습니다.
핵심:
운영 데이터 hard delete는 신중히
상품/관리자 계정은 soft delete 또는 비활성화
상담 데이터는 개인정보 보존/익명화 기준 필요
삭제/복구는 Audit Log 대상

➕ 2-8. 0820 DB Backup, Restore와 운영 장애 대응

  • pg_dump, pg_restore, RDS snapshot, PITR, 전체 복구, 일부 복구, sequence 복구, DB와 S3 정합성을 정리했습니다.
핵심:
백업보다 복구 가능성이 중요
운영 DB에 바로 restore 금지
migration 전 snapshot 확인
부분 복구는 현재 운영 데이터와 비교
백업 파일은 개인정보 덩어리

➕ 2-9. 0821 Query 분석, EXPLAIN과 느린 쿼리 개선

  • EXPLAIN, EXPLAIN ANALYZE, Seq Scan, Index Scan, 복합 인덱스, contains 검색, count, offset 한계, slow query log를 정리했습니다.
핵심:
감으로 인덱스 추가 금지
실제 SQL과 EXPLAIN 확인
SELECT * 줄이기
include 최소화
성능 개선 전후 기록

✅ 3. 현재 프로젝트 기준 핵심 DB 도메인

  • 온라인 휴대폰 판매몰에서 DB 핵심은 단순 상품 저장이 아닙니다.
  • 상담 신청, 상품/옵션, 관리자 처리, 상태 이력, 유입 분석, 알림/엑셀 작업이 연결됩니다.
상품 도메인:
products
product_options
banners
promotions

상담 도메인:
consults
consult_status_histories
consult_memos

운영 도메인:
admin_users
roles
permissions
audit_logs

유입 도메인:
visit_logs
lead_sources
utm_logs

작업 도메인:
export_jobs
notification_logs
job_logs

➕ 3-1. 가장 중요한 3개

1. consults
고객 리드와 매출의 시작점

2. products / product_options
고객 화면, 상담 조건, 마케팅 자산의 기준

3. audit_logs / status_histories
운영 추적성과 관리자 신뢰도의 기준
  • 모든 테이블을 같은 비중으로 볼 필요는 없습니다.
  • 먼저 상담, 상품, 상태 이력부터 안정화하는 것이 가장 효과적입니다.

✅ 4. 1인 개발자 DB 운영 원칙

➕ 4-1. 원칙 1: 운영 DB에서 감으로 작업하지 않는다

운영 DB 작업 전:
SELECT로 대상 확인
count 확인
sample 확인
transaction 준비
backup/snapshot 여부 확인
  • 운영 DB에서 직접 SQL을 실행해야 한다면, 작업 전후 확인 쿼리가 반드시 있어야 합니다.

➕ 4-2. 원칙 2: 데이터 변경은 이력을 남긴다

상담 상태 변경:
status_history

상품 가격/지원금 변경:
audit_log

관리자 권한 변경:
audit_log

삭제/복구:
audit_log
  • “누가 바꿨는지 모르는 데이터”는 운영 신뢰도를 떨어뜨립니다.
  • 핵심 변경은 반드시 추적 가능해야 합니다.

➕ 4-3. 원칙 3: 삭제보다 숨김/비활성화를 먼저 고려한다

상품:
isActive=false 또는 deletedAt

관리자:
isActive=false 또는 disabledAt

상담:
삭제보다 보존/익명화 정책

엑셀 파일:
만료 후 삭제
  • 삭제는 복구가 어렵습니다.
  • 운영 데이터는 대부분 “삭제”보다 “상태 변경”으로 관리하는 편이 안전합니다.

➕ 4-4. 원칙 4: 느리면 먼저 측정한다

느린 API
  ↓
실제 SQL 확인
  ↓
EXPLAIN 확인
  ↓
병목 파악
  ↓
개선
  ↓
전후 비교
  • 성능 문제는 감이 아니라 숫자로 확인해야 합니다.
  • 인덱스 추가도 근거가 있어야 합니다.

➕ 4-5. 원칙 5: 백업은 복구 테스트까지 해야 한다

백업 있음:
안심 X

복구 테스트 완료:
안심 가능
  • 백업 파일을 만들어둔 것만으로는 부족합니다.
  • 새 DB에 복구하고 앱이 정상 동작하는지 확인해야 합니다.

✅ 5. DB 설계 체크리스트

➕ 5-1. 테이블 설계

  • 테이블 이름만 봐도 의미가 명확한가?
  • 각 테이블의 책임이 하나로 정리되어 있는가?
  • data, info, etc, temp 같은 모호한 이름을 피했는가?
  • Primary Key가 명확한가?
  • 외부에 노출되는 ID와 내부 ID를 구분할 필요가 있는가?
  • Foreign Key 관계가 필요한 곳에 적용되어 있는가?
  • 관계 삭제 정책이 명확한가?
  • ERD로 핵심 관계를 설명할 수 있는가?

➕ 5-2. 컬럼 설계

  • 필수값에 NOT NULL 기준이 있는가?
  • 기본값이 필요한 컬럼에 DEFAULT가 있는가?
  • 상태값은 enum 또는 코드표로 관리되는가?
  • 개인정보 컬럼이 식별되어 있는가?
  • 검색용 정규화 컬럼이 필요한가?
  • snapshot 컬럼이 필요한 도메인인가?
  • createdAt, updatedAt이 필요한가?
  • deletedAt이 필요한 테이블인가?

➕ 5-3. 관계 설계

  • 1:N 관계와 N:M 관계가 구분되어 있는가?
  • 중간 테이블이 필요한 관계인가?
  • 상품과 상담 관계가 명확한가?
  • 상담 상태 변경 이력이 별도 테이블로 관리되는가?
  • 관리자 작업 이력과 상태 이력의 역할이 구분되어 있는가?
  • 삭제된 상품을 과거 상담에서 참조할 수 있는가?
  • 신규 상담에서 삭제된 상품 선택이 차단되는가?
  • 관계가 너무 과하게 복잡해지지 않았는가?

✅ 6. Prisma Schema 체크리스트

➕ 6-1. Schema 작성

  • model 이름과 실제 도메인 이름이 일치하는가?
  • relation 이름이 이해하기 쉬운가?
  • enum 이름이 운영 상태 코드와 일치하는가?
  • nullable 여부가 실제 비즈니스 규칙과 맞는가?
  • @default(now()), @updatedAt을 적절히 사용했는가?
  • @@index, @@unique가 조회/정합성 기준과 맞는가?
  • Json 타입을 남용하지 않는가?
  • 개인정보 컬럼에 접근 기준이 있는가?

➕ 6-2. Migration

  • migration 파일을 직접 확인했는가?
  • destructive change가 있는가?
  • 컬럼 삭제/rename이 포함되어 있는가?
  • not null 추가 시 기존 데이터가 문제 없는가?
  • unique constraint 추가 시 중복 데이터가 없는가?
  • 운영 DB에 적용 전 staging에서 테스트했는가?
  • migration 전 backup/snapshot 기준을 확인했는가?
  • 운영에서 migrate reset을 절대 사용하지 않는가?

➕ 6-3. 안전한 변경 순서

1. nullable 컬럼 추가
2. 코드에서 새 컬럼 사용 시작
3. 기존 데이터 backfill
4. not null 또는 unique 제약 추가
5. 구 컬럼 사용 제거
6. 충분한 기간 후 구 컬럼 삭제
  • DB 변경은 한 번에 크게 하는 것보다 여러 단계로 나누는 것이 안전합니다.
  • 특히 운영 데이터가 이미 있는 상태에서는 단계적 migration이 중요합니다.

✅ 7. 상담 신청 DB 체크리스트

➕ 7-1. 상담 원본 데이터

  • 상담 신청 ID가 명확한가?
  • 고객명, 전화번호, 선택 상품이 저장되는가?
  • 전화번호는 정규화 컬럼이 있는가?
  • 전화번호 원본 보관 기준이 있는가?
  • phoneMasked 또는 phoneLast4가 필요한가?
  • 유입 source, utm, visitorId가 저장되는가?
  • IP/userAgent 저장 필요성과 보존 기준이 있는가?
  • 상담 메모에 개인정보가 들어갈 수 있음을 고려했는가?

➕ 7-2. 중복 신청

  • 중복 기준이 정의되어 있는가?
  • 전화번호만 기준인지, 상품/날짜/캠페인까지 보는가?
  • 프론트 중복 클릭 방지가 있는가?
  • 백엔드 중복 검사가 있는가?
  • DB unique constraint가 필요한가?
  • 중복 신청을 거절할지, 이력으로 남길지 정했는가?
  • 중복 시 409 Conflict 응답 기준이 있는가?
  • 관리자에게 중복 여부를 표시하는가?

➕ 7-3. 상담 snapshot

  • 상담 당시 상품명을 저장하는가?
  • 상담 당시 통신사를 저장하는가?
  • 상담 당시 요금제/지원금을 저장하는가?
  • 상품 정보가 나중에 바뀌어도 과거 상담 조건이 유지되는가?
  • snapshot과 원본 product의 역할이 구분되어 있는가?
  • snapshot 값이 개인정보는 아닌지 확인했는가?
  • 상담 상세에서 snapshot을 보여주는가?
  • 엑셀 Export에도 snapshot이 필요한가?

✅ 8. 상태 변경 이력 체크리스트

➕ 8-1. 상태값 설계

  • 상태 enum이 운영 언어와 맞는가?
  • 신규/진행/완료/취소/중복 상태가 구분되어 있는가?
  • 최종 상태가 무엇인지 정해져 있는가?
  • 되돌릴 수 있는 상태와 없는 상태가 구분되어 있는가?
  • 상태 전이 규칙이 있는가?
  • 관리자 권한별 상태 변경 제한이 필요한가?
  • 상태 변경 사유 코드가 필요한가?
  • 상태 코드표가 문서화되어 있는가?

➕ 8-2. 이력 저장

  • fromStatus와 toStatus를 모두 저장하는가?
  • 변경한 관리자 ID를 저장하는가?
  • 시스템 자동 변경도 표현 가능한가?
  • 변경 사유와 메모가 필요한가?
  • 상태 변경과 이력 저장이 transaction으로 묶여 있는가?
  • 이력 생성 실패 시 상태 변경도 rollback되는가?
  • 상담 상세에서 이력을 볼 수 있는가?
  • 현재 상태와 마지막 이력 정합성을 점검할 수 있는가?

➕ 8-3. 상태 변경 동시성

  • 관리자 여러 명이 같은 상담을 동시에 수정할 수 있는가?
  • 현재 상태 조건을 update where에 포함하는가?
  • version 기반 optimistic lock이 필요한가?
  • 충돌 시 409 Conflict를 반환하는가?
  • 사용자가 “이미 수정된 상담”임을 알 수 있는가?
  • 상태 변경 후 목록 캐시를 갱신하는가?
  • 상태 필터에 따라 row가 사라지는 UX를 고려했는가?
  • 상태 변경 후 이력과 audit log가 함께 남는가?

✅ 9. Audit Log 체크리스트

➕ 9-1. 대상 작업

  • 상담 상태 변경이 기록되는가?
  • 상담 메모 수정이 기록되는가?
  • 상품 등록/수정/삭제가 기록되는가?
  • 가격/지원금 변경이 기록되는가?
  • 배너 노출 변경이 기록되는가?
  • 관리자 계정/권한 변경이 기록되는가?
  • 엑셀 다운로드 요청이 기록되는가?
  • 알림톡 재발송이 기록되는가?

➕ 9-2. 로그 구조

  • actorType이 있는가?
  • actorId가 있는가?
  • action이 명확한가?
  • targetType/targetId가 있는가?
  • beforeValue/afterValue가 필요한 필드만 담는가?
  • requestId가 저장되는가?
  • ipAddress/userAgent 저장 기준이 있는가?
  • createdAt 기준 조회가 가능한가?

➕ 9-3. 개인정보/보안

  • 전화번호 원본을 audit log에 저장하지 않는가?
  • 고객 이름 원본 저장을 피하거나 마스킹하는가?
  • 상담 메모 전체를 before/after에 넣지 않는가?
  • 토큰, 쿠키, Authorization header를 절대 저장하지 않는가?
  • DATABASE_URL, Secret이 로그에 남지 않는가?
  • audit log 조회 권한이 제한되어 있는가?
  • 로그 보존 기간 기준이 있는가?
  • audit log 자체도 백업/보존 대상인지 정했는가?

✅ 10. 관리자 목록 조회 체크리스트

➕ 10-1. Pagination

  • page/limit 기반 조회가 있는가?
  • limit 최대값이 제한되어 있는가?
  • 기본 limit가 적절한가?
  • 전체 count가 꼭 필요한 화면인가?
  • 큰 offset 문제가 발생할 가능성이 있는가?
  • 로그성 데이터는 cursor pagination을 고려했는가?
  • 필터 변경 시 page를 1로 초기화하는가?
  • 페이지가 비었을 때 이전 페이지로 이동하는가?

➕ 10-2. Sorting

  • 기본 정렬이 정해져 있는가?
  • createdAt desc, id desc처럼 안정적 정렬인가?
  • sortBy 화이트리스트가 있는가?
  • 허용하지 않은 컬럼으로 정렬할 수 없게 막는가?
  • 정렬 기준과 인덱스가 맞는가?
  • 상태별 우선순위 정렬이 필요한가?
  • 프론트와 백엔드 정렬 기준이 일치하는가?
  • 정렬 변경 시 캐시 key가 바뀌는가?

➕ 10-3. Search / Filter

  • 전화번호 검색 기준이 정해져 있는가?
  • 고객명 검색이 꼭 필요한가?
  • 상태 필터가 enum과 연결되어 있는가?
  • 상품/통신사/유입 source 필터가 있는가?
  • 날짜 범위 검색이 가능한가?
  • 한국 시간 기준 날짜 검색 처리가 명확한가?
  • contains 검색이 과도하지 않은가?
  • 검색어가 로그/URL에 남는 위험을 고려했는가?

➕ 10-4. 목록/상세 분리

  • 목록 API에서 필요한 최소 필드만 내려주는가?
  • 상세 정보는 상세 API로 분리되어 있는가?
  • 상태 이력은 별도 API 또는 상세에서 조회하는가?
  • 알림 발송 이력은 필요할 때만 조회하는가?
  • 목록에서 불필요한 include를 하지 않는가?
  • N+1 쿼리가 발생하지 않는가?
  • 응답 payload 크기를 확인했는가?
  • 프론트 렌더링 성능도 함께 봤는가?

✅ 11. 인덱스 운영 체크리스트

➕ 11-1. 인덱스 후보

consults:
status + createdAt + id
productId + createdAt
source + createdAt
phoneNormalized
phoneLast4 + createdAt

products:
isActive + displayOrder
deletedAt
carrier + createdAt

audit_logs:
actorType + actorId + createdAt
targetType + targetId + createdAt
action + createdAt
requestId

status_histories:
consultId + createdAt
changedByAdminId + createdAt

➕ 11-2. 추가 전 확인

  • 실제로 자주 쓰는 쿼리인가?
  • 데이터가 충분히 많아졌는가?
  • EXPLAIN에서 병목이 확인되었는가?
  • 기존 인덱스로 커버되지 않는가?
  • where/orderBy 컬럼 순서가 맞는가?
  • 쓰기 성능 비용을 감수할 수 있는가?
  • migration 적용 시간이 괜찮은가?
  • 추가 후 성능을 비교할 수 있는가?

➕ 11-3. Soft Delete와 인덱스

  • deletedAt IS NULL 조건이 자주 쓰이는가?
  • partial index가 필요한가?
  • 활성 데이터만 조회하는 쿼리에 맞는가?
  • Prisma migration에서 raw SQL이 필요한가?
  • unique constraint와 soft delete가 충돌하지 않는가?
  • partial unique index가 필요한가?
  • 삭제된 데이터 조회용 인덱스가 필요한가?
  • 인덱스가 너무 많아지지 않았는가?

✅ 12. Transaction/동시성 체크리스트

➕ 12-1. Transaction이 필요한 작업

  • 상담 상태 변경 + 이력 저장
  • 주문 상태 변경 + 이력 저장
  • 상품 가격 변경 + audit log
  • 관리자 권한 변경 + audit log
  • export job 생성 + audit log
  • 알림 발송 job 생성
  • soft delete + audit log
  • restore + audit log

➕ 12-2. Transaction 안에서 피할 작업

알림톡/SMS 실제 발송
S3 업로드
엑셀 파일 생성
외부 API 호출
긴 파일 처리
사용자 입력 대기
대량 데이터 처리

➕ 12-3. 동시성 방어

  • 중복 신청 방지가 프론트에만 의존하지 않는가?
  • 백엔드 중복 검사가 있는가?
  • DB unique constraint가 필요한가?
  • 관리자 동시 수정 충돌을 처리하는가?
  • optimistic lock이 필요한 화면인가?
  • 상태 변경 where에 현재 상태 조건이 있는가?
  • idempotency key가 필요한 API인가?
  • 중복 요청 시 같은 결과를 반환하거나 409로 처리하는가?

✅ 13. Soft Delete/보존 정책 체크리스트

➕ 13-1. Soft Delete

  • Soft Delete 대상 테이블이 정해져 있는가?
  • deletedAt 컬럼이 있는가?
  • deletedByAdminId가 필요한가?
  • deleteReason이 필요한가?
  • 일반 조회에서 deletedAt: null 조건이 빠지지 않는가?
  • 삭제함 조회가 필요한가?
  • 복구 API가 필요한가?
  • 삭제와 복구가 Audit Log에 남는가?

➕ 13-2. Hard Delete

  • Hard Delete 가능한 데이터가 따로 분류되어 있는가?
  • 임시 인증 코드/세션/토큰은 정리 대상인가?
  • Debug log 보존 기간이 있는가?
  • Export 파일 만료 후 삭제 기준이 있는가?
  • 운영 핵심 데이터 hard delete를 막는가?
  • Cascade Delete가 위험하게 설정되어 있지 않은가?
  • 대량 삭제 전 dry run을 지원하는가?
  • 삭제 전 백업/snapshot을 고려하는가?

➕ 13-3. 개인정보 보존

  • 상담 데이터 보존 기간 기준이 있는가?
  • 전화번호 원본 보관 필요성이 명확한가?
  • 상담 메모 보존 기준이 있는가?
  • 익명화 대상 컬럼이 정리되어 있는가?
  • 익명화 후 복구 불가능성을 인지하는가?
  • 통계용 데이터와 개인정보 원본을 분리하는가?
  • Export 파일에 만료 시간이 있는가?
  • 개인정보 포함 로그가 장기 보관되지 않는가?

✅ 14. 백업/복구 체크리스트

➕ 14-1. 백업

  • RDS 자동 백업이 켜져 있는가?
  • 백업 보존 기간이 정해져 있는가?
  • 수동 snapshot 생성 기준이 있는가?
  • migration 전 snapshot 기준이 있는가?
  • 대량 update/delete 전 백업 기준이 있는가?
  • pg_dump 사용 방법을 알고 있는가?
  • 백업 파일 보관 위치와 권한이 정해져 있는가?
  • 백업 파일이 개인정보를 포함함을 인지하는가?

➕ 14-2. 복구

  • snapshot에서 새 DB를 복구해본 적 있는가?
  • pg_restore로 로컬/스테이징 복구 테스트를 해본 적 있는가?
  • 전체 DB 복구 Runbook이 있는가?
  • 일부 데이터 복구 Runbook이 있는가?
  • 복구 후 sequence 점검 방법을 아는가?
  • 복구 후 DB/S3 파일 정합성을 확인하는가?
  • 복구 후 Smoke Test 항목이 있는가?
  • 복구 작업 기록/Postmortem을 남기는가?

➕ 14-3. 운영 dump 보안

  • 운영 dump를 Git에 올리지 않는가?
  • 운영 dump를 AI 도구에 업로드하지 않는가?
  • 운영 dump를 개인 Mac에 오래 보관하지 않는가?
  • 익명화 dump를 만들 수 있는가?
  • dump 파일 접근 권한이 제한되어 있는가?
  • dump 다운로드/복구 작업 기록을 남기는가?
  • 테스트 후 dump 파일을 안전하게 삭제하는가?
  • 로컬 개발에 운영 원본 데이터가 꼭 필요한지 검토하는가?

✅ 15. 느린 쿼리 분석 체크리스트

➕ 15-1. 원인 파악

  • 느린 API가 정확히 무엇인가?
  • 어떤 query parameter에서 느려지는가?
  • 실제 SQL을 확인했는가?
  • EXPLAIN을 확인했는가?
  • Seq Scan이 발생하는가?
  • Sort 비용이 큰가?
  • Rows Removed by Filter가 많은가?
  • count 쿼리가 병목인가?

➕ 15-2. 개선 후보

  • SELECT *를 제거했는가?
  • select로 필요한 필드만 조회하는가?
  • 불필요한 include를 제거했는가?
  • N+1 쿼리가 없는가?
  • where/orderBy에 맞는 인덱스가 있는가?
  • contains 검색을 줄일 수 있는가?
  • 큰 offset 문제가 있는가?
  • cursor pagination이나 날짜 필터가 필요한가?

➕ 15-3. 개선 기록

  • 개선 전 API 응답 시간을 기록했는가?
  • 개선 전 EXPLAIN 결과를 저장했는가?
  • 어떤 인덱스를 추가했는지 기록했는가?
  • 개선 후 Execution Time을 비교했는가?
  • payload 크기 변화를 확인했는가?
  • 프론트 렌더링 병목이 아닌지 확인했는가?
  • 배포 후 실제 운영 로그를 확인했는가?
  • 결과를 작업 기록/릴리즈 노트에 남겼는가?

✅ 16. DB 운영 문서 구조 추천

  • DB 운영 지식은 코드에만 있으면 안 됩니다.
  • 1인 개발자라도 문서로 남겨야 나중에 장애, 이직, 연봉협상, 인수인계에 도움이 됩니다.
docs/
  db/
    README.md
    erd.md
    schema-design.md
    prisma-migration-guide.md
    indexes.md
    status-codes.md
    audit-log.md
    soft-delete-retention.md
    backup-restore.md
    query-optimization.md
    db-runbook.md

➕ 16-1. docs/db/README.md

DB 구조 개요
핵심 테이블 목록
운영 주의사항
관련 문서 링크

➕ 16-2. docs/db/status-codes.md

상담 상태 코드
주문 상태 코드
상태 전이 규칙
상태 변경 사유 코드
최종 상태 정의

➕ 16-3. docs/db/indexes.md

주요 인덱스 목록
인덱스 추가 이유
관련 API
EXPLAIN 개선 결과
주의사항

➕ 16-4. docs/db/backup-restore.md

백업 방식
RDS snapshot 기준
pg_dump/pg_restore 명령어
전체 복구 Runbook
일부 복구 Runbook
복구 테스트 기록
  • 문서는 처음부터 완벽할 필요 없습니다.
  • 중요한 것은 실제 운영할 때 열어서 따라 할 수 있어야 한다는 점입니다.

✅ 17. 현재 프로젝트 기준 우선 적용 순서

➕ 17-1. 1순위: 상담/상품/관리자 핵심 구조 안정화

consults 구조 점검
products/product_options 구조 점검
admin_users 구조 점검
상담 상태 enum 정리
상담 상태 이력 테이블 확인

완료 기준:

상담 신청이 상품과 정확히 연결됨
상태 변경 이력이 남음
관리자 작업자 추적 가능
상품 정보 변경 시 과거 상담 조건이 흔들리지 않음

➕ 17-2. 2순위: 관리자 목록 성능 안정화

page/limit 정리
sortBy 화이트리스트
createdAt + id 정렬
목록/상세 API 분리
select 최소화
기본 인덱스 점검

완료 기준:

상담 목록 조회가 안정적으로 동작
상태/날짜/전화번호 검색이 느리지 않음
엑셀 다운로드가 목록 API와 분리됨

➕ 17-3. 3순위: Audit Log와 운영 추적성

CONSULT_STATUS_UPDATE
PRODUCT_UPDATE
PRODUCT_SOFT_DELETE
EXPORT_DOWNLOAD_REQUEST
ADMIN_PERMISSION_UPDATE

완료 기준:

누가 어떤 작업을 했는지 추적 가능
상품/지원금 변경 이력 확인 가능
삭제/복구 작업 기록 확인 가능

➕ 17-4. 4순위: 백업/복구 체계

RDS 자동 백업 확인
migration 전 snapshot 기준
pg_dump/pg_restore 테스트
부분 복구 Runbook
복구 후 Smoke Test

완료 기준:

백업 위치와 복구 절차를 설명 가능
새 DB에 복구 테스트 가능
운영 실수 발생 시 대응 순서가 있음

➕ 17-5. 5순위: 쿼리 분석과 성능 기록

Prisma query log 개발 환경 확인
EXPLAIN 분석 연습
느린 상담 목록 API 분석
인덱스 추가 전후 기록
성능 개선 문서화

완료 기준:

느린 쿼리를 감이 아니라 실행 계획으로 설명 가능
인덱스 추가 이유와 효과를 기록 가능
관리자 목록 성능 개선을 성과로 표현 가능

✅ 18. 4주 DB 운영 개선 계획

➕ 18-1. 1주차: 핵심 테이블 점검

목표:
상담/상품/관리자 핵심 구조 안정화

작업:
- consults 테이블 구조 점검
- products/product_options 구조 점검
- 상담 상태 enum 정리
- status history 구조 확인
- snapshot 컬럼 필요 여부 정리

완료 기준:

핵심 테이블과 관계를 설명할 수 있음
상담 상태 변경 흐름이 문서화됨
과거 상담 조건 보존 기준이 있음

➕ 18-2. 2주차: 관리자 목록 최적화

목표:
관리자 상담 목록 성능과 사용성 개선

작업:
- page/limit/sort DTO 정리
- sortBy 화이트리스트
- 목록/상세 API 분리
- select 최소화
- 전화번호 검색 정규화 확인
- 기본 인덱스 후보 정리

완료 기준:

상담 목록 API 응답 구조 통일
불필요한 include 제거
상태/날짜/전화번호 검색 기준 정리

➕ 18-3. 3주차: Audit Log와 Soft Delete

목표:
운영 추적성과 삭제 복구 가능성 확보

작업:
- Audit Log action 목록 정리
- 상태 변경 audit log 연결
- 상품 soft delete 기준 정리
- 삭제/복구 API 기준 정리
- 개인정보 로그 마스킹 확인

완료 기준:

주요 관리자 작업 추적 가능
삭제/복구 작업 기록 가능
상품 삭제와 노출 중지 구분 가능

➕ 18-4. 4주차: 백업/복구와 성능 분석

목표:
장애 대응과 성능 분석 기본 체계 확보

작업:
- RDS 백업 설정 확인
- pg_dump/pg_restore 테스트
- 복구 Runbook 작성
- 상담 목록 EXPLAIN 분석
- 인덱스 추가 전후 기록 템플릿 작성

완료 기준:

복구 절차를 문서로 설명 가능
느린 쿼리 분석 흐름을 수행 가능
DB 운영 개선을 성과 문장으로 정리 가능

✅ 19. DB 작업을 성과로 표현하는 방법

  • DB 작업은 겉으로 잘 보이지 않지만, 실제로는 운영 안정성과 생산성에 큰 영향을 줍니다.
  • 연봉협상이나 경력기술서에서는 “테이블 수정”보다 “운영 안정성 개선”으로 표현해야 합니다.

➕ 19-1. 약한 표현

DB 테이블 수정
인덱스 추가
Prisma migration 작성
상태 이력 추가
백업 문서 작성

➕ 19-2. 강한 표현

상담 상태 변경 이력과 Audit Log 구조를 설계해 관리자 작업 추적성과 운영 데이터 정합성을 개선했습니다.

관리자 상담 목록의 검색/필터/정렬 기준을 정리하고 목록/상세 API를 분리해 대량 데이터 증가에 대비한 조회 구조를 개선했습니다.

상담 신청 중복 처리 기준과 transaction 범위를 정리해 중복 접수 및 상태 변경 누락 가능성을 줄였습니다.

상품 삭제와 노출 비활성화, Soft Delete, 복구 기준을 분리해 과거 상담 참조를 유지하면서 운영 실수 복구가 가능한 구조를 마련했습니다.

DB migration 전 백업 기준과 복구 Runbook을 정리해 운영 DB 변경 작업의 안정성을 높였습니다.

EXPLAIN 기반으로 관리자 목록 쿼리 병목을 분석하고 조회 패턴에 맞는 인덱스 후보를 정리해 성능 개선 근거를 마련했습니다.
  • 핵심은 “무엇을 만들었다”보다 “운영 문제가 어떻게 줄었다”입니다.
  • DB는 성과 표현에서 안정성, 추적성, 정합성, 성능이라는 단어로 정리하면 좋습니다.

✅ 20. DB 운영에서 피해야 할 습관

운영 DB에서 감으로 update/delete
SELECT 확인 없이 대량 변경
Prisma migration 파일 확인 안 함
migrate reset을 운영에서 실행
상태 변경 이력 없이 status만 update
삭제를 hard delete로 처리
백업 확인 없이 migration
EXPLAIN 없이 인덱스 추가
SELECT *와 과한 include 방치
개인정보를 로그에 그대로 저장
운영 dump를 로컬에 오래 보관

➕ 20-1. 특히 위험한 행동

운영 DB:
where 없는 UPDATE/DELETE

운영 migration:
reset 또는 데이터 삭제 migration

로그:
전화번호/토큰/Secret 출력

백업:
dump 파일을 Git 또는 AI에 업로드
  • 이 네 가지는 실제 사고로 이어질 수 있습니다.
  • 1인 개발자는 자기 자신이 마지막 방어선이라는 생각으로 움직여야 합니다.

✅ 21. DB 운영 자동화 후보

➕ 21-1. 자동화하면 좋은 것

migration 전 체크리스트 생성
schema diff 리뷰
Prisma migration 파일 위험도 분석
느린 쿼리 로그 요약
EXPLAIN 결과 요약
백업 테스트 기록 템플릿 생성
상담 상태 코드 문서 생성
Audit Log action 목록 문서화

➕ 21-2. 자동화하면 위험한 것

운영 DB 자동 update
운영 DB 자동 delete
운영 migration 자동 승인
운영 restore 자동 실행
개인정보 포함 dump 자동 업로드
AI에게 원본 DB 제공
  • DB 자동화는 검토와 기록 중심으로 시작해야 합니다.
  • 운영 데이터를 직접 바꾸는 자동화는 안전장치가 충분히 생긴 뒤에만 고려해야 합니다.

✅ 22. AI/Codex에게 DB 작업을 맡길 때 규칙

1. 운영 DB 접속 정보 제공 금지
2. 실제 개인정보 제공 금지
3. schema.prisma 변경 전 요구사항 명확히 전달
4. migration 파일을 반드시 사람이 확인
5. destructive change 여부를 AI에게 따로 점검 요청
6. seed/test data와 운영 data를 구분
7. transaction 범위와 rollback 기준 확인
8. 변경 후 EXPLAIN/QA 체크리스트 요청

➕ 22-1. 좋은 요청 예시

schema.prisma에서 상담 상태 변경 이력 테이블을 추가하려고 해.

조건:
1. 기존 Consult 모델의 status는 유지
2. ConsultStatusHistory 모델을 추가
3. fromStatus, toStatus, changedByAdminId, reason, memo, createdAt 포함
4. AdminUser와 relation 연결
5. consultId + createdAt index 추가
6. changedByAdminId + createdAt index 추가
7. 기존 데이터 삭제나 reset은 절대 하지 않음
8. migration 생성 후 위험 요소를 설명

출력:
- 수정할 Prisma schema
- migration 시 주의사항
- transaction service 예시
- QA 체크리스트

➕ 22-2. 검토 기준

기존 데이터 삭제가 없는가?
nullable/default가 안전한가?
인덱스가 과하지 않은가?
relation cascade가 위험하지 않은가?
개인정보가 로그에 남지 않는가?
운영 migration 순서가 안전한가?
  • AI는 DB 설계 보조로 매우 유용합니다.
  • 하지만 운영 DB에 반영하는 최종 판단은 반드시 사람이 해야 합니다.

✅ 23. 다음 학습 방향

  • 데이터베이스 실무 심화를 마무리했다면 다음은 실제 백엔드 구조와 연결하는 것이 좋습니다.
  • 특히 현재 프로젝트에서는 3사 확장, 상담/주문 상태, 엑셀 Export, 알림톡, 권한, 유입 분석이 중요합니다.

➕ 23-1. 추천 다음 시리즈

0824 백엔드 아키텍처 고도화 (1/N): Domain Service, Use Case와 비즈니스 로직 분리

➕ 23-2. 이어갈 주제 후보

0824:
Domain Service, Use Case와 비즈니스 로직 분리

0825:
Repository Pattern과 Prisma 의존성 관리

0826:
Transaction Boundary와 상태 변경 Use Case 설계

0827:
Queue/Worker, ExportJob과 알림톡 발송 구조

0828:
Webhook, 외부 API 연동과 재시도 전략

0829:
Permission Policy, 관리자 권한과 접근 제어

0830:
Audit Log, Event Log와 운영 추적성

0831:
Error Handling, Exception Filter와 표준 응답 구조

0901:
테스트 가능한 백엔드 구조와 Mock 전략

0902:
백엔드 아키텍처 운영 체크리스트
  • 이 흐름은 DB에서 다룬 내용을 실제 NestJS 코드 구조로 옮기는 단계입니다.
  • 지금 프로젝트에는 이 방향이 가장 실무적입니다.

✅ 24. 최종 DB 운영 체크리스트

➕ 24-1. 매일/수시

  • 상담 신청이 정상 저장되는가?
  • 관리자 상담 목록 조회가 정상인가?
  • 상태 변경 후 이력이 남는가?
  • 최근 에러 로그에 DB 오류가 없는가?
  • 상담 신청 실패율이 비정상적으로 높지 않은가?
  • 알림/ExportJob 실패가 쌓이지 않는가?
  • DB connection 오류가 없는가?
  • 주요 API 응답 시간이 급격히 늘지 않았는가?

➕ 24-2. 배포 전

  • migration이 있는가?
  • migration 파일을 직접 확인했는가?
  • destructive change가 있는가?
  • staging에서 migration을 테스트했는가?
  • snapshot/backup 필요 여부를 확인했는가?
  • 상태 변경/상담 신청 흐름에 영향이 있는가?
  • rollback 또는 forward fix 계획이 있는가?
  • 배포 후 Smoke Test 항목이 준비되었는가?

➕ 24-3. 주간

  • 느린 관리자 목록 API가 있는가?
  • 자주 쓰는 검색 조건이 느리지 않은가?
  • ExportJob 실패가 누적되지 않는가?
  • Audit Log가 정상적으로 쌓이는가?
  • 상태 이력 정합성 문제가 없는가?
  • Soft Delete 데이터가 의도대로 숨겨지는가?
  • 백업 상태를 확인했는가?
  • DB 관련 TODO가 문서화되어 있는가?

➕ 24-4. 월간

  • RDS 비용/스토리지 증가를 확인했는가?
  • 백업 보존 정책을 확인했는가?
  • 복구 테스트가 필요한 시점인가?
  • 오래된 Export 파일이 정리되는가?
  • 로그 보존 기간이 적절한가?
  • 인덱스 추가/삭제 후보가 있는가?
  • 개인정보 보존/익명화 기준을 점검했는가?
  • DB 문서가 최신 상태인가?

✅ 25. AI에게 DB 운영 전체 점검을 맡길 때 좋은 질문법

NestJS + Prisma + PostgreSQL/RDS 기반 온라인 휴대폰 판매몰의 DB 운영 상태를 점검하고 싶어.

서비스 상황:
1. 고객 상담 신청, 상품/옵션, 관리자 계정, 상담 상태 이력, Audit Log, ExportJob, 알림 발송 로그가 있음
2. 상담 신청에는 이름, 전화번호, 상품, 유입 source, visitorId, IP가 포함될 수 있음
3. 관리자는 상담 목록에서 검색/필터/정렬/페이지네이션을 사용하고 상태를 변경함
4. 상품 정보가 바뀌어도 상담 당시 조건은 snapshot으로 보존하고 싶음
5. 상태 변경과 이력 저장은 transaction으로 묶어야 함
6. 상품/배너/관리자 계정은 soft delete 또는 비활성화가 필요함
7. RDS 백업, pg_dump/pg_restore, 일부 데이터 복구 Runbook이 필요함
8. 관리자 목록 조회 성능을 EXPLAIN 기반으로 개선하고 싶음
9. 개인정보와 Secret은 로그/백업/AI 도구에 노출되면 안 됨

요청:
- DB 설계 체크리스트
- Prisma schema/migration 체크리스트
- 상담/상품/상태 이력/Audit Log 점검 항목
- 관리자 목록 조회 성능 체크리스트
- 인덱스 후보와 주의사항
- Soft Delete/보존 정책 점검
- 백업/복구 Runbook 점검
- 느린 쿼리 분석 순서
- 운영 DB 작업 시 금지할 행동
- 4주 개선 로드맵
- 경력기술서에 쓸 수 있는 성과 표현
을 실무 기준으로 정리해줘.

➕ 25-1. AI 답변 검증 기준

상담 신청과 관리자 상태 변경을 핵심으로 보는가?
운영 DB reset/delete 위험을 강하게 경고하는가?
상태 변경 이력과 Audit Log를 구분하는가?
개인정보와 백업 파일 보안을 강조하는가?
EXPLAIN 기반 분석을 우선하는가?
인덱스를 무작정 많이 만들라고 하지 않는가?
Soft Delete와 Hard Delete 기준을 구분하는가?
복구 테스트와 Runbook을 강조하는가?
현재 규모에 비해 과한 구조를 강요하지 않는가?

📌 요약

  • 데이터베이스 실무 심화의 핵심은 SQL 문법을 많이 아는 것이 아니라, 운영 데이터의 정합성, 추적성, 성능, 복구 가능성을 지키는 것입니다.
  • 현재 프로젝트에서는 consults, products/product_options, admin_users, consult_status_histories, audit_logs, export_jobs, notification_logs가 핵심 DB 도메인입니다.
  • 상담 신청 데이터는 고객 리드와 직접 연결되므로 중복 신청 방지, 전화번호 정규화, 유입 source, 상품 snapshot, 개인정보 보존 기준을 함께 설계해야 합니다.
  • 상태 변경은 현재 상태만 바꾸면 안 되고, fromStatus, toStatus, changedByAdminId, reason, createdAt을 가진 이력 테이블과 transaction으로 묶어야 합니다.
  • Audit Log는 관리자 주요 작업을 추적하기 위한 공통 로그이며, 상품 가격/지원금 변경, 삭제/복구, 권한 변경, 엑셀 다운로드 같은 작업을 기록하는 데 필요합니다.
  • 관리자 목록 조회는 page/limit, 안정적 정렬, sortBy 화이트리스트, 목록/상세 API 분리, select 최소화, 적절한 인덱스가 핵심입니다.
  • 인덱스는 감으로 추가하지 말고 실제 조회 패턴과 EXPLAIN 결과를 기준으로 추가해야 하며, 너무 많은 인덱스는 쓰기 성능과 저장공간 비용을 증가시킵니다.
  • Soft Delete는 상품, 배너, 관리자 계정처럼 복구 가능성과 과거 참조가 필요한 데이터에 적합하며, 상담 데이터는 개인정보 보존/익명화 정책과 함께 봐야 합니다.
  • 백업은 존재보다 복구 가능성이 중요하며, RDS snapshot, pg_dump/pg_restore, 전체 복구, 일부 복구, sequence 점검, DB/S3 정합성 확인까지 Runbook으로 정리해야 합니다.
  • 느린 쿼리는 실제 SQL 확인, EXPLAIN 분석, select/include 최소화, 인덱스 검토, count/offset 개선 순서로 접근해야 합니다.
  • 다음 흐름으로는 DB 설계를 실제 코드 구조와 연결하는 백엔드 아키텍처 고도화 시리즈가 가장 자연스럽습니다.

0개의 댓글