Image of Lucian Ghinda writing for notes.ghinda.com
October 3rd, 2025

Designing Database Schemas for Clarity

Whenever I create a new table or column in a web app, I aim for clarity so that anyone connecting directly to the database can easily understand it.

My heuristic involves designing the database so that direct queries yield sensible results without needing any additional information beyond the database itself. 

There are trade-offs with this approach. For example, you might sacrifice some performance, so keep that in mind.

Let me give some examples: 


1. Enums: String vs Integer
Using integer enums like priority = 0, 1, 2 can be confusing when querying directly.

Using string enums like priority = 'urgent', 'medium', 'low' makes results instantly clear when running SELECT *.

👉 Use string enums unless performance is critical.

2. Nullable vs Non-Nullable
If something is required logically, enforce NOT NULL.
Don’t leave half your schema nullable "just in case."

👉 This makes the schema self-documenting.


3. More generally any validation that can be added on the DB should be there

Eg: user_invoices might contain a unique validation on user_id + invoice_id so add a unique index on ['invoice_id', 'user_id'] on that table


4. Relationship context 

If you need to store the creator of a record, don't just add user_id. Consider a more descriptive name like creator_id or even created_by_author_id. 

Inspired by Igor Aleksandrov post on running migrations multiple times:

Igor about proper domain technology