How to document a database schema your team will actually read
Ask five developers which table owns the concept of a customer and you will get two confident answers, one “it depends”, and two people who quietly open the schema to check. That is the gap schema documentation is supposed to close, and most teams close it badly: a wiki page written during a quiet week two years ago, and a diagram image that no longer matches the migrations.
Documentation that survives has to be cheap to write, reviewed like code, and short enough to read. Everything below is about getting those three properties, using the DDL you already have as the source of truth.
Start with the three questions the document must answer
Schemas are big; documentation budgets are not. Write down what people actually ask about:
- What is this table for, in one sentence? Not its columns — its purpose. “One row per signed subscription, including cancelled ones” answers questions that a column list never will.
- What happens to this row when the parent is deleted? Cascade, block, or silently orphaned because the relationship lives in application code. This is the question that prevents production incidents.
- Which table is the centre of the model? The one everything else points at. New developers orient themselves around it faster than they will ever tell you.
If the document answers those three for the ten tables that matter, it is already better than most company wikis.
Three places to keep it, and what each one costs
- A wiki page. Easy to write, easy to read, and it rots in silence. Nobody reviews a wiki edit, and nobody notices when a migration makes it wrong. Costs the least to create and the most to trust.
- A diagram image in a shared drive. Good for orientation, terrible for maintenance: it is a binary, so a change is invisible in review, and re-exporting it is a manual job somebody has to remember.
- Text in the repository. A Mermaid block in the README, or a
docs/schema.mmdfile next to the code. It shows up in pull requests, it diffs line by line, GitHub and most internal tools render it, and it lives where developers already are. This is the only option that gets reviewed by accident.
Keep the source-of-truth diagram as text in the repository. Use images for slides and onboarding packs, generated from the same text.
Generate the diagram from the DDL instead of drawing it
Hand-drawn diagrams are wrong the moment a migration lands. Generate instead:
- Dump the schema without data:
mysqldump --no-data,pg_dump --schema-only, or.schemain SQLite. - Paste it into the SQL to ER diagram tool and check the result against the three questions above. The mechanics — what the parser reads, how to verify the arrows, which export to pick — are covered in detail in From CREATE TABLE to a clear ER diagram.
- Export Mermaid and commit it as
docs/schema.mmd, with a one-line note in the README saying how to regenerate it. The file is now text that reviewers can read in a diff. - Export SVG for the human-facing page — the wiki, the onboarding doc, the slide — and treat it as a build artifact rather than something to be maintained by hand.
The point of generating is that the diagram costs a paste, so regenerating it after every schema change is realistic. A diagram that takes half an hour to redraw is a diagram that will be stale within a quarter.
The five lines per table that save the most time
You do not need to document every column. Document the tables you touch, with five lines each:
- Purpose — one sentence, as above.
- Owner — the service or team that writes to it. When two services write to one table, write that down too; it is a fact people discover painfully.
- Lifecycle — what inserts rows, what deletes them, and how historical rows are archived. Deletion paths are where the surprises live.
- Columns whose names lie —
statusvalues that mean something other than they appear, a*_rawcolumn that is not raw, alegacy_*prefix that is still in daily use. - Known traps — a nullable foreign key, a soft-delete flag no constraint enforces, a column that stores a timestamp in local time. One line each, and they stop being traps.
The drift problem: make the doc a review item
Documentation does not rot because people are lazy. It rots because nothing in the workflow asks for it at the moment it changes. Two cheap mechanisms fix that:
- A line in the migration pull-request template: “Does this change the schema doc? If not, why not?” It takes four seconds to answer and turns an invisible task into a visible one.
- A quarterly pass over the diagram. Regenerate it from the current DDL, diff it against the committed version, and read the diff. Whatever changed without a note is the drift.
The orphan-table pass
Once you have a diagram, look for the tables that nothing references. Each one is either a lookup table or a place where the relationship exists only in application code. Those are the tables where data quality problems accumulate quietly: rows deleted in one service while another still holds the id, joins that work in one code path and fail in another. Write one line of purpose for each orphan and you will have found the parts of the model nobody currently understands.
The onboarding test
Hand the document and a database connection to someone who has never seen the system, and ask three questions:
- Where do I find the money that a customer has been charged?
- What happens if I delete this customer row?
- Which table would I change to add a feature for a new pricing plan?
If they can answer all three within ten minutes, the document works. If they cannot, the missing piece is usually not a column description — it is the purpose line or the deletion behaviour, which is exactly what the five-line format above asks for.
Keep the schema out of random browsers
A schema is business intelligence. Table names describe your roadmap, and column names describe your customer relationships: a chargeback_reason column says what you process, an enterprise_contracts table says who you sell to. A production schema under NDA should not be pasted into a website whose retention policy you have not read.
The SQL to ER diagram tool parses in your browser, so the DDL never leaves the machine — you can watch the network panel while you paste. The PDF tools follow the same rule, which matters when the schema doc ends up as a PDF attached to a client pack: merging and compressing happen locally too.
A 30-minute routine
- Dump the schema without data.
- Paste it, glance at the diagram, spot the orphan tables.
- Export Mermaid, commit it as
docs/schema.mmd, link it from the README. - Write the five lines for the two tables you changed most recently.
- Add the regenerating command to the team’s notes, and a schema question to the pull-request template.
Half an hour, once, and then fifteen minutes a quarter. That is the difference between a schema diagram people look at and one they learned to ignore.
Turn your schema into a diagram in one paste
Paste your CREATE TABLE statements, check the relationships, then export Mermaid and commit it next to the code. Free, and nothing is sent to a server.
Open the SQL tool