master-project
CHAPTER 7 / 50
읽기 약 2분
FUNCTION
ERD: 데이터베이스 스키마 설계
핵심 개념
엔터티·관계·정규화·인덱스 — Supabase PostgreSQL 기반 ERD를 코드로 작성하고 마이그레이션 준비.
본문
ERD 핵심 6엔터티 (AI SaaS)
users (사용자)
├── id (UUID, PK)
├── email (UNIQUE)
├── name
├── created_at
subscriptions (구독)
├── id (UUID, PK)
├── user_id (FK → users)
├── plan (free/pro/team)
├── stripe_customer_id
├── current_period_end
generations (AI 생성 이력)
├── id (UUID, PK)
├── user_id (FK → users)
├── prompt
├── result
├── tokens_used
├── created_at
templates (템플릿)
├── id (UUID, PK)
├── name
├── category
├── prompt_template
├── is_premium
usages (사용량)
├── id (UUID, PK)
├── user_id (FK → users)
├── month (yyyy-mm)
├── count
projects (프로젝트 그룹화)
├── id (UUID, PK)
├── user_id (FK → users)
├── name
└── settings (JSONB)관계도
users 1—N subscriptions
users 1—N generations
users 1—N usages
users 1—N projects
projects 1—N generations
templates N—M generations (사용 이력)SQL 스키마 (Supabase)
-- users (Supabase Auth가 자동 생성하는 auth.users 확장)
create table public.users (
id uuid primary key references auth.users(id) on delete cascade,
email text unique not null,
name text,
created_at timestamptz default now()
);
create table public.subscriptions (
id uuid primary key default gen_random_uuid(),
user_id uuid references public.users(id) on delete cascade,
plan text not null check (plan in ('free','pro','team')),
stripe_customer_id text,
stripe_subscription_id text,
current_period_end timestamptz,
created_at timestamptz default now()
);
create table public.generations (
id uuid primary key default gen_random_uuid(),
user_id uuid references public.users(id) on delete cascade,
template_id uuid references public.templates(id),
prompt text not null,
result text,
tokens_used int,
created_at timestamptz default now()
);
-- 인덱스 (성능)
create index idx_generations_user on public.generations(user_id, created_at desc);
create index idx_subscriptions_user on public.subscriptions(user_id);RLS (Row Level Security)
alter table public.generations enable row level security;
create policy "users see own generations"
on public.generations for select
using (auth.uid() = user_id);
create policy "users insert own"
on public.generations for insert
with check (auth.uid() = user_id);정규화 vs 비정규화
정규화 (3NF)
- 데이터 무결성 ↑
- 조인 많음 → 느림 가능
- AI SaaS 6엔터티는 정규화로 충분
비정규화 (성능)
- usage_count를 users 테이블에 캐싱
- 트레이드오프: 동기화 비용 vs 빠른 조회인덱스 전략
- PK는 자동 인덱스
- FK 컬럼 → 인덱스 (조인 빠름)
- WHERE 자주 쓰는 컬럼 → 인덱스
- 너무 많으면 INSERT 느림 (균형)
EXPLAIN ANALYZE
SELECT * FROM generations
WHERE user_id = $1
ORDER BY created_at DESC
LIMIT 20;
→ Index Scan 확인다음 챕터
CH.8 "기술 스택 결정" — 프론트+백+DB+AI+배포.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 마스터 프로젝트의 ERD 설계 부분을 분석해서 실전 적용 + 개선 우선순위 3가지를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
ERD 설계 관련 모범 사례·안티패턴 5개를 비교 분석해서 실전 적용를 위한 추천 방안을 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 ERD 설계 최적화 가능 위치와 리스크를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 1인 개발자 시장의 ERD 설계 트렌드와 차별화 포인트를 정리해줘.
⭐ 이것만 기억하세요
ERD: 데이터베이스 스키마 설계는 이 3가지만 확실히 잡으세요
1.6엔터티 = MVP 데이터 모델 충분
2.RLS + 인덱스 = Supabase 보안·성능 기본
3.다음 챕터에서 전체 기술 스택 결정
공유하기
진행도 7 / 50