C.W.K.
Stream
Lesson 02 of 10 · published

JSONB 가 도울 때와 게으름일 때

~12 min · extensions, jsonb

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

JSONB 잡는 좋은 이유 셋

  1. 진짜 가변 모양: 여러 소스에서 오는 이벤트 payload, audit log, 외부 API 스냅샷.
  2. 희소, 선택 필드: 가능한 50 속성, 어떤 행이든 5-10 개 사용.
  3. 설정 또는 flag bag: 키 집합이 시간에 따라 진화하는 유저 설정.

나쁜 이유 셋 (하지 마)

  1. "스키마 마이그레이션 회피." 마이그레이션 비용은 진짜지만 schema-less 비용이 더 큼 — 데이터 모든 소비자에게 검증 문제 떠넘김.
  2. "유연하니까." 유연성은 OK; 제어 안 된 유연성이 기술 부채.
  3. "ORM 이 쉽게 해서." ORM 이 데이터에 쿼리 안 함 — 미래 자기가 함.

하이브리드 접근

맞는 패턴은 보통: 안정 필드 진짜 컬럼에 (NOT NULL, CHECK, FK 와), 가변 부분 JSONB sidecar 에. Relational 정합성 + JSON 유연성 둘 다, 어느 쪽도 타협 없이.

Code

Anti-pattern: 다 JSONB 에·sql
-- 이거 하지 마
CREATE TABLE everything (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    data JSONB NOT NULL  -- 어깨 으쓱
);
-- 필수 필드 NOT NULL 없음, FK 없음, 타입 안전 없음, 제약 없음.
하이브리드: 안정 + 유연·sql
CREATE TABLE events (
    id          INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    user_id     INTEGER NOT NULL REFERENCES users(id),
    event_type  TEXT NOT NULL CHECK (event_type IN ('click','view','signup','purchase')),
    occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    payload     JSONB NOT NULL DEFAULT '{}'::jsonb  -- 타입별 추가
);

CREATE INDEX events_user_id_idx ON events (user_id);
CREATE INDEX events_payload_gin ON events USING gin (payload);

External links

Exercise

제어하는 JSONB 컬럼 잡기. 키 중 90% 행에 있는 거 나열. 진짜 컬럼으로 승격; 진짜 희소한 거만 JSONB 유지.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.