Prompt
How do I know if I should use JSONB or normalize my schema?
Latest observation
A good rule is:
- Use normalized tables by default when the data has a stable structure and you query it often.
- Use JSONB when the shape is flexible, varies a lot, or you mostly store/read it as a blob and only occasionally inspect fields.
Use normalized schema when:
- You need strong integrity: foreign keys, uniqueness, constraints.
- You frequently filter, join, sort, or aggregate by fields.
- The data represents a real entity with relationships, like
users,orders,products. - You want easier reporting and simpler indexing.
- The fields are known and unlikely to change often.
Example: an orders table with customer_id, status, created_at, and an order_items table is usually better than putting items in JSON.
Use JSONB when:
- The structure is semi-structured or user-defined.
- Different rows can have different fields.
- The schema changes often and you want flexibility.
- You need to store extra metadata, configs, event payloads, logs, or API responses.
- You rarely query individual nested fields, or only a few fields matter.
Example: storing settings like:
{
"theme": "dark",
"notifications": {
"email": true,
"sms": false
}
}
makes sense in JSONB if the settings vary by user and aren’t heavily joined on.
A practical decision test
Ask:
-
Do I need to query this field often?
- Yes → normalize
- No → JSONB may be fine
-
Do I need constraints or relationships?
- Yes → normalize
-
Is the structure stable?
- Yes → normalize
- No / evolving → JSONB
-
Will I need analytics/reporting on it?
- Yes → normalize, or at least extract the queried parts into columns
-
Is this “data about data” or a payload?
- Often JSONB is a good fit
Common hybrid approach
You do not need to choose one exclusively.
A common pattern is:
- Put the core fields in normalized columns
- Put optional or rarely used fields in JSONB
Example:
users (
id,
email,
name,
profile_jsonb
)
This works well if email and name are important, but profile extras vary.
Performance notes
JSONB can be fast, especially with good indexes, but:
- querying nested fields is usually more complex,
- constraints are weaker,
- and long-term maintenance/reporting can become harder if too much business data lives in JSONB.
Normalization can require more joins, but it usually gives:
- better data quality,
- clearer schema,
- and easier querying at scale.
Quick rule of thumb
If you’re unsure, start normalized. Add JSONB only for:
- flexible extension data,
- rarely queried attributes,
- or payloads that don’t fit a stable relational model.
If you want, I can help you decide for a specific table/design if you share the columns and example queries.