**Normalization(정규화)**이란 깊이 중첩된 객체/배열 대신, id로 키를 매긴 룩업 테이블의 평평한 관계형 구조로 데이터를 저장하는 것을 의미합니다. 데이터베이스 정규화와 같은 아이디어를 클라이언트 state에 적용한 것으로, 갱신과 조회를 효율적이고 일관되게 만듭니다.
중첩/비정규화 state의 문제
js
: [
{ : , : , : { : , : } },
{ : , : , : { : , : } },
]
중복된 중첩 데이터는 여러 곳에서 갱신해야 하고(불일치 위험), 항목을 찾으려면 배열을 스캔해야 합니다(O(n)).
// ✅ id로 키를 매긴 평평한 룩업 테이블, 참조는 id로
{
posts: {
byId: { 1: { id: 1, title: "A", authorId: 10 }, // author를 id로 참조
2: { id: 2, title: "B", authorId: 10 } },
allIds: [1, 2], // 순서/순회
},
users: {
byId: { 10: { id: 10, name: "Ann" } }, // 각 user는 한 번만 저장
},
}
각 엔터티는 id로 키를 매겨 한 번만 저장되며, 관계는 그냥 id 참조입니다.
state.users.byId[10]; // ✅ id로 O(1) 조회
state.users.byId[10] = { ...u, name: "Bob" }; // ✅ Ann을 한 번 갱신 → 모든 곳에 반영
state.posts.allIds.map(id => state.posts.byId[id]); // id 목록으로 순회
✓ 엔터티당 single source of truth → 중복 없음, 어긋남 없음
✓ id로 O(1) 조회/갱신(배열 스캔 대비)
✓ 하나의 엔터티를 갱신하면 모든 참조에 반영하기 쉬움
✓ 관계 관리와 새 데이터 병합이 더 단순함
Redux Toolkit의 createEntityAdapter는 정규화된 { ids, entities } 구조와
CRUD reducer를 자동 생성합니다. normalizr는 API 응답을 정규화할 수 있습니다.
Normalization은 클라이언트 state에서 관계형/컬렉션 데이터를 관리하는 표준 패턴입니다(특히 Redux에서).
엔터티당 single source of truth를 강제하고(한 번 갱신하면 모든 곳에 반영), 빠른 id 기반 조회를 제공하며, 깊이 중첩된 중복 데이터의 버그와 성능 문제를 피합니다.
갱신되고 상호 참조되는 관련 엔터티 목록(사용자, 게시물, 댓글)이 있는 앱의 경우, store를 정규화하는 것 — 흔히 createEntityAdapter를 통해 — 은 state를 일관되고 효율적으로 유지하는 핵심 기법입니다.