본문 바로가기
C.W.K.
Stream
Lesson 01 of 10 · published

Normalization — 데이터 중복 피하기

~12 min · normalization, schema, writes

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

각 사실은 한 자리에만

Normalization은 데이터를 여러 테이블로 쪼개서 사실 하나가 딱 한 번만 저장되게 만드는 일이야. 반대쪽인 denormalized 데이터는 같은 사실을 여러 row에 복사해두니까, 뭘 고칠 때마다 사본을 전부 찾아 바꿔야 해.

blog post와 author를 두 방식으로 놓고 비교해보자.

  • Denormalizedposts 테이블에 author_name, author_email, author_bio가 직접 들어가. Alice가 글을 100개 썼으면 그 정보가 100번 저장돼. 이메일을 바꾸려면 row 100개를 건드려야 하고, 하나라도 빠뜨리면 데이터가 어긋나.
  • Normalizedposts에는 author_id FK만 두고 authors 테이블에 author마다 row 하나를 둬. 이메일 바꾸기는 row 하나 고치면 끝이야.

Normalization의 대가는 join이야. 다음 lesson들에서 실컷 보게 될 거고. Denormalization의 대가는 업데이트가 어긋나는 사고낭비되는 저장 공간이지. 앱 데이터는 대개 먼저 normalize하고, read 쪽 병목을 실제로 측정한 다음에만 골라서 denormalize해.

Principle: write를 위해 normalize하고, read를 위해 denormalize해. 단 측정한 뒤에만. SQLite 앱에서 미리 denormalize해둔 건 대개 query 시간을 아낀 것보다 update 버그 값이 더 비싸게 나와.

Code

Denormalized — 돌아가긴 하는데 나빠·sql
CREATE TABLE posts_bad (
  id INTEGER PRIMARY KEY,
  title TEXT NOT NULL,
  author_name  TEXT NOT NULL,    -- 모든 post 마다 반복
  author_email TEXT NOT NULL,    -- 또 반복
  author_bio   TEXT              -- 또
) STRICT;
Normalized — join되고, 출처는 하나·sql
CREATE TABLE authors (
  id    INTEGER PRIMARY KEY,
  name  TEXT NOT NULL,
  email TEXT NOT NULL UNIQUE,
  bio   TEXT
) STRICT;

CREATE TABLE posts (
  id        INTEGER PRIMARY KEY,
  author_id INTEGER NOT NULL REFERENCES authors(id),
  title     TEXT NOT NULL,
  body      TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
) STRICT;

External links

Exercise

필드가 반복되는 denormalized CSV를 하나 골라. 연락처 목록이나 주문 export 같은 거면 돼. 테이블 두세 개짜리 normalized schema를 스케치해봐. 엔티티가 뭐고 PK와 FK 관계가 어떻게 되는지 짚고, 어디까지는 통제된 denormalization을 받아들일지도 정해. 주문 시점 가격을 스냅샷으로 박아두는 것 같은 자리 말이야.

Progress

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

댓글 0

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

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