Skip to main content

Data Modelling

Describing what the product is actually about — the entities, how they relate, and what must always be true of them. It happens before the schema and before the API, and everything downstream inherits whatever you decide here.

Why it matters. A wrong model is the most expensive kind of mistake to fix, because by the time it hurts there is production data shaped like it. Screens can be redrawn in an afternoon; a relation that should have been many-to-many cannot.

What to understand

  • What the real-world thing is, independent of the screen showing it
  • Which relations are one-to-one, one-to-many, many-to-many — and which will change
  • What must always be true, and where that rule is enforced
  • What is stored versus what is derived
  • Whether history matters, or only the current state

Core topics

Entities and relations

  • Identifying entities from the domain, not from the UI
  • Cardinality, and the cost of getting it wrong
  • Join tables, and when a relation deserves its own entity because it carries data
  • Optional versus required, and what null actually means here

Constraints and invariants

Rules the data must satisfy, wherever they are enforced.

  • Uniqueness, foreign keys, check constraints
  • Rules the database can enforce versus rules only the application can
  • Why enforcing in one place is better than validating in three

Normalisation and its limits

  • Removing duplication so a fact lives in one place
  • Where denormalising is a deliberate performance decision
  • Recognising a schema that has been denormalised by accident

Change over time

  • Migrations, and writing them so they can run against real data
  • Soft deletes, audit trails, and event history
  • Versioning a model that clients already depend on

Levels

LevelWhat it looks like
JuniorAdds fields and tables that work for the screen in front of them.
MiddleModels entities from the domain, gets cardinality right, and uses constraints rather than validation alone.
SeniorAnticipates how the model will need to change, keeps migrations safe on live data, and knows when to denormalise on purpose.

Practice

Starting out

  • Model from the domain Take a feature described in words and derive the entities before drawing any screen.

  • Fix a cardinality Find a one-to-many that reality says should be many-to-many, and change it.

  • Add a real constraint Move a rule currently checked in application code into the database.

Going deeper

  • Write a migration that cannot lose data Split a table or change a column type on data that already exists.

  • Model history Change something that only stores current state into something that can answer "what did this look like last month".

  • Design for two consumers Model an entity that a mobile app and an admin panel both use, without either distorting it.

Check yourself

  • How do you tell a real entity from a field that happens to be on a screen?
  • What tells you a relation is about to need its own table?
  • Which rules in your project are validated in code but not enforced in the database?
  • How do you decide whether to store a value or compute it?
  • When has a model change forced you to touch far more code than expected?
  • How do you make a schema change safe on a table with a million rows?

Resources