Normalisation
What It Is
Normalisation is the process of organizing data to reduce duplication and improve data integrity.
In frontend state management, it means flattening nested data, storing entities separately, and connecting related entities using unique IDs.
Normalisation = Store each entity once and connect data using IDs
Why It Matters
Frontend applications often receive deeply nested API data.
If the same data is stored in many places, updates become difficult and inconsistent.
Normalisation helps by:
- removing redundant data
- improving lookup efficiency
- simplifying nested relationships
- storing related data together
- keeping unrelated data separate
- making updates easier and safer
Nested data -> harder to update
Normalised data -> easier to update from one place
Core Idea
Instead of storing full nested objects inside other objects, store each entity separately.
Then use IDs to represent relationships.
Users stored separately
Posts stored separately
Comments stored separately
Tags stored separately
Relations are stored using IDs
This avoids repeating the same object in multiple places.
Basic Normalised Shape
A common normalised structure uses:
| Field | Purpose |
|---|---|
| byIds | Stores records by their unique ID |
| allIds | Stores the list of all entity IDs |
Example structure:
users.byIds -> user records by ID
users.allIds -> list of user IDs
This makes direct lookup fast.
state.users.byIds["2"];
The lookup becomes direct because the ID points to the exact record.
Example 1: Nested Data
This is nested data where each user contains posts inside the user object.
const state = {
users: [
{
id: 1,
name: "Alice",
posts: [
{ id: 101, title: "Post 1" },
{ id: 102, title: "Post 2" },
],
},
{
id: 2,
name: "Bob",
posts: [{ id: 103, title: "Post 3" }],
},
],
};
Problem with this shape:
- posts are nested inside users
- updating a post requires searching through users
- relationships are harder to manage
- duplicated data can appear as app grows
Example 1: Normalised Data
The normalised version stores users and posts separately.
const state = {
users: {
byIds: {
1: {
id: 1,
name: "Alice",
},
2: {
id: 2,
name: "Bob",
},
},
allIds: [1, 2],
},
posts: {
byIds: {
101: {
id: 101,
title: "Post 1",
userId: 1,
},
102: {
id: 102,
title: "Post 2",
userId: 1,
},
103: {
id: 103,
title: "Post 3",
userId: 2,
},
},
allIds: [101, 103, 102],
},
};
Now users and posts are independent entities.
The relation between user and post is maintained using userId.
What Changed in Example 1
The normalised structure follows three rules.
1. Store users and posts separately
2. Store relationships using IDs
3. Store entities by ID and maintain allIds list
Direct lookup becomes simple.
state.users.byIds["2"];
This is more efficient than searching through an array of users.
Example 2: More Complex Nested Data
In larger apps, data can include multiple relationships.
Example:
const state = {
users: [
{
id: 1,
name: "Alice",
posts: [
{
id: 101,
title: "Post 1",
},
],
},
{
id: 2,
name: "Bob",
posts: [
{
id: 102,
title: "Post 2",
},
],
},
],
tags: [
{
id: 301,
name: "Tech",
posts: [{ id: 101 }, { id: 102 }],
},
{
id: 302,
name: "Travel",
posts: [{ id: 102 }],
},
],
};
This kind of nested structure can become difficult to update because users, posts, tags, and comments may all reference each other.
Example 2: Normalised Data
A better structure stores every entity separately.
const normalized_state = {
users: {
byIds: {
1: {
id: 1,
name: "Alice",
posts: [101],
},
2: {
id: 2,
name: "Bob",
posts: [102],
},
},
allIds: [1, 2],
},
posts: {
byIds: {
101: {
id: 101,
title: "Post 1",
comments: [201],
},
102: {
id: 102,
title: "Post 2",
comments: [202],
},
},
allIds: [101, 102],
},
comments: {
byIds: {
201: {
id: 201,
text: "Comment 1",
},
202: {
id: 202,
text: "Comment 2",
},
},
allIds: [201, 202],
},
tags: {
byIds: {
301: {
id: 301,
name: "Tech",
posts: [101, 102],
},
302: {
id: 302,
name: "Travel",
posts: [102],
},
},
allIds: [301, 302],
},
};
Now each entity has its own collection.
Relationships are represented using arrays of IDs.
What Changed in Example 2
The normalised version separates:
- users
- posts
- comments
- tags
Then it stores relationships using IDs.
User -> post IDs
Post -> comment IDs
Tag -> post IDs
This makes it easier to update one post, one comment, or one tag without modifying many nested objects.
Benefits
Normalisation improves the structure and reliability of application data.
| Benefit | Meaning |
|---|---|
| Less duplication | Same data is not stored in many places |
| Better integrity | One update affects the correct single source |
| Faster lookup | Entity can be accessed directly by ID |
| Simpler updates | Update one object instead of searching nested trees |
| Cleaner relationships | Related data is connected using IDs |
| Better scalability | Easier to manage large application state |
When to Use
Use normalisation when the data has many entities and relationships.
Good use cases:
- users and posts
- posts and comments
- products and categories
- tags and articles
- dashboards with shared entities
- frontend stores with repeated API data
- data that needs frequent updates
Use normalisation when nested data becomes hard to update or duplicate.
When Not to Use
Normalisation may be unnecessary for very small or simple data.
Avoid overusing it when:
- the data is small
- the data is not reused
- the data has no relationships
- the data does not need frequent updates
- nested structure is easier and clear enough
Simple data does not always need normalisation.
Normalisation Table
| Area | Explanation |
|---|---|
| Main goal | Reduce redundancy and improve data integrity |
| Data shape | Flattened entities |
| Relationships | Stored using IDs |
| Common structure | byIds and allIds |
| Lookup | Direct by ID |
| Best for | Related entities and large state |
| Avoid for | Small simple unrelated data |
Basic Checklist
Identify main entities
Separate each entity into its own collection
Store each entity by unique ID
Keep allIds list for each entity
Replace nested objects with IDs
Keep relationships using IDs
Avoid duplicating the same object in many places
Update entities from one location
Use normalisation when nested updates become difficult
Interview Style Answer
Normalisation is the process of organizing data to reduce redundancy and improve data integrity. In frontend state management, it means flattening nested data, storing each entity separately, and connecting relationships using unique IDs. A common structure is to store records inside byIds and maintain an allIds array for ordering or listing. For example, instead of storing posts inside each user, users and posts are stored separately, and posts contain userId or users contain post IDs. This makes lookups faster, updates easier, relationships clearer, and state more consistent in large applications.
One-Line Summary
Normalisation = Flatten nested data, store entities separately, and connect them using IDs.
Final Mental Model
Nested data -> duplicate and hard to update
Normalised data -> entities by ID and relationships by IDs
Store once, reference everywhere.