스키마 설계 기초
스키마는 당신 데이터의 청사진이다: 어떤 테이블이 존재하고, 어떤 컬럼을 가지며, 어떻게 연관되는지. 좋은 스키마 설계는 대부분 상식에 몇 가지 습관을 더한 것이다.
- "것" 하나당 테이블 하나. 사용자, 게시물, 주문 — 각각 자기 테이블을 갖는다.
- 모든 행에는 고유 ID가 필요하다 (기본 키).
- 테이블은 외래 키로 연결하라, 데이터를 복사해 다니지 말고.
- 정직한 타입을 골라라. 돈은
float가 아니라decimal이다. 날짜는 텍스트가 아니라 타임스탬프다. - 중복하지 말라. 사용자의 이메일이 다섯 테이블에 살면, 결국 다섯 개의 다른 이메일을 갖게 된다.
다음은 블로그를 위한 간단한 스키마로, AI가 당신을 위해 생성해줄 종류다:
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE posts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
author_id UUID NOT NULL REFERENCES users(id),
title TEXT NOT NULL,
body TEXT NOT NULL,
published BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_posts_author ON posts(author_id);
REFERENCES(게시물을 실제 사용자에 묶는 외래 키)와 NOT NULL, UNIQUE 제약에 주목하라. 이것들은 데이터베이스가 당신을 위해 강제하는 가드레일이라, 당신 코드에 버그가 있어도 잘못된 데이터가 몰래 들어올 수 없다.
의도적으로 추가할 가치가 있는 제약은 부모가 사라질 때 무슨 일이 일어나느냐다. 기본적으로, 게시물이 여전히 참조하는 사용자를 삭제하려 하면 실패한다 — 종종 그것이 당신이 원하는 바다. 하지만 명시적으로 정할 수 있다: REFERENCES users(id) ON DELETE CASCADE는 게시물도 함께 삭제하고, ON DELETE RESTRICT는 삭제를 막는다. 의도를 가지고 고르는 것이, 프로덕션에서 기본값을 호되게 깨닫는 것보다 낫다. 똑같은 "데이터베이스가 당신을 지키게 하라"는 본능은 CHECK 제약(CHECK (price >= 0))에도 적용된다 — 모든 코드 경로가 검증하리라 믿는 대신, 말도 안 되는 데이터를 원천에서 거부한다.