Data & Analytics
Database design: put the rules where the data lives
Where a rule should live
One table, designed
jobs
- key
- job_id, generated by the database
- belongs to
- a customer and a property, both required
- status
- one of: requested, scheduled, in progress, completed, cancelled
- times
- scheduled start and end; end must be after start
- fast questions
- “history at this address”, “today's board by status”
- history
- every status change kept in job_events, never overwritten
- access
- technicians see their assigned jobs; the office sees all
Each line is a decision someone would otherwise make by accident. The allowed statuses are the same list the screens show, so a typo can't create a sixth one.
Indexes follow the questions people actually ask. A technician opening an address sees its whole history straight away, because that lookup was designed for.
Five decisions in every design
Keys
How each row is known
Generated ids for rows, natural ones (like invoice numbers) kept unique.
Constraints
What can't be true
Required links, allowed values and checks that reject bad rows with a reason.
Indexes
What must be fast
Built for the questions people ask every day, and no more.
History
What's kept when it changes
Status changes and edits recorded, so “who changed this?” has an answer.
Access
Who sees which rows
Rules in the database, so every screen and report applies them the same way.
What a database design hands off
In
Out
Worth designing properly when the data has to stay right
Good fit
- You're building a system that becomes the record for jobs, customers or money.
- More than one screen, import or integration writes the same data.
- Bad rows are found in reports, weeks after they were written.
Not the right fit
- A spreadsheet or an off-the-shelf tool already holds the data well.
- A short-lived prototype. Design the schema when the shape has settled.
Questions about database design
Which database do you use?
Usually PostgreSQL. It handles constraints, history and access rules well, and runs almost anywhere. Starting candidates, not requirements.
Can you fix our existing database?
Often. We find the rules it should enforce, clean the rows that break them, and add the constraints so new bad rows can't arrive.
Doesn't putting rules in the database make changes harder?
Changes become deliberate: a migration that's reviewed and can be rolled back. That's slower than editing a screen, and that's the point.
What about NoSQL?
It fits some jobs, like large volumes of events. Business records that relate to each other usually belong in a relational database.