Two teams mean the same thing when every business noun — customer, order, account, paid — has one agreed name and one written definition. A short set of data naming conventions plus a shared data dictionary makes that agreement checkable, so reports, apps and spreadsheets stop drifting apart.
Key Takeaways
- One term, one meaning: pick a single canonical name per business concept and retire its synonyms (cust, client, account) from new code.
- Write it where people look: a one-page data dictionary — term, definition, owner, example — beats a policy document nobody opens.
- Mechanical rules stick: fix case style, is_ booleans, _at versus _date suffixes and entity_id keys, then enforce them in review.
- Never rename live systems in one jump: alias first, migrate consumers, then drop the old name on a published date.
- Verify with queries, not memory: a scheduled check for stray status values or off-pattern columns catches drift before a report does.
- Names are a security surface: an orders_backup_old table full of customer rows is personal data nobody is protecting.
What does a shared name actually require?
Start from definitions, not column names. A shared name needs three things written down: the concept it stands for, the system that owns the master copy, and one example value. With those, customer stops meaning three different things; without them, sales reads paying account while the database stores a contact person.
Two artefacts do the work. A business glossary defines terms in plain language: what counts as an active customer, whether a refund is a payment. A data dictionary maps each term to its canonical name — the single agreed spelling — in each system: customer_id in the Postgres database, ClientRef in the CRM, Cust No in the finance export. One page each beats a policy document.
Why do mismatched names turn into production incidents?
Mismatched names break joins, and broken joins produce wrong numbers that surface the moment two teams compare reports. The mechanism is dull: one idea lives under different keys in two systems, a report joins the wrong pair, and the error stays invisible until finance reconciles against the CRM in front of a customer.
Three shapes cover most of the damage. Same word, different meaning: account is a company to sales and a billing record to finance. Different words, same meaning: cust_ref, client_no and party_id all hold one customer key. And free-text values that drift: Active, active and Active with a trailing space become three statuses in every GROUP BY. Add amounts stored without a currency code, and dates that mean sometimes placed, sometimes paid, and month-end becomes archaeology.
When do you need written conventions — and when is it overkill?
Decide by blast radius — how much breaks if a name is wrong — not by headcount. Written conventions earn their keep the moment two systems exchange data, two teams read the same numbers, or a report feeds a decision with money attached. One internal tool with one maintainer can carry naming in a single head, until handover empties it.
Be honest about the small end: a five-person business with one bookkeeping export needs half a page and a habit, not a governance board. The triggers that change the answer are boring and reliable — a second system arrives, a new developer onboards, two reports disagree, or a spreadsheet quietly becomes critical. Ownership and handover questions come up constantly in this territory; our FAQ covers the ones we hear most.
How does a naming convention hold up day to day?
Conventions hold when they are enforced where data enters: in migrations, in API contracts and in report definitions — not in a PDF nobody opens. The working mechanism is review plus checks: every pull request that adds a column is compared against the dictionary, and a scheduled query fails when a value lands outside an agreed list.
Each layer gets one convention. The database layer fixes case style (snake_case in Postgres and MySQL), decides singular or plural table names once, names foreign keys after the entity they point at (customer_id, never ref1), prefixes booleans with is_ or has_, and separates _at timestamps from _date fields. The API layer picks camelCase or snake_case and never mixes. The report layer maps every column header back to a dictionary term. None of this is exotic — the discipline is writing it down and applying it in review.
Case folding is where teams get burned. PostgreSQL folds unquoted identifiers to lowercase, so a column created once as quoted "CustomerID" becomes a second, different column sitting next to customerid; the PostgreSQL identifier rules cover the exact behaviour. MySQL column names are case-insensitive, but table-name case handling depends on the platform and server settings — which is how a database moved from Windows to Linux can suddenly lose tables. Check the MySQL identifier case-sensitivity page before relying on case to tell names apart.
How do you set one up in practice?
Set it up in a week with the team you already have. The sequence needs no new tooling: a wiki page for the dictionary, your existing code review for enforcement, and two or three scheduled queries for verification. Big-bang documentation efforts die quietly; a short list of agreed nouns survives.
- Inventory the words already in use. Export column names from the database, headers from finance spreadsheets and report builders, and the terms people say in meetings. One afternoon is enough — the database side is literally a query against information_schema.
- Reconcile the top twenty nouns in one meeting. For each: one owner, one definition, one canonical name. Settle the client-versus-customer debate with a decision, not a shrug.
- Publish the dictionary where work happens. A table with term, canonical name, definition, owner, source of truth and an example value. In the repository beats in a shared drive nobody opens.
- Adopt one page of mechanical rules: case style per layer, is_ booleans, _at versus _date, amount alongside currency_code, and a closed status list with fixed spellings.
- Wire enforcement into the change you were making anyway. Review new columns against the dictionary, update the dictionary inside the same pull request, and schedule the drift queries below.
- Bridge legacy names instead of renaming overnight. Expose dictionary-approved names through database views or API serializers first; schedule real renames with a deprecation window — the timeline later in this article shows one.
Which naming rules earn their keep?
Prioritise rules that prevent silent wrong answers. An is_ prefix on booleans, _at for timestamps against _date for calendar days, a currency code beside every amount and a closed status list stop the four classic failures: misread flags, mixed time boundaries, added currencies and one status split into five spellings.
The entity_id pattern for foreign keys — customer_id pointing at customers.id — makes joins guessable and grep-able, which matters more than any style argument. Everything else is taste; write it down once and stop relitigating it.
How do you verify the convention is holding?
Verify with queries, not memory. Three scheduled checks cover most drift: a pattern audit that lists columns breaking the naming rules, a value check that counts statuses outside every closed list, and a reconciliation that joins the same key in two systems and reports the difference.
Treat drift — any gap between the dictionary and the data — as a bug, not a observation. The pattern audit is one query:
SELECT table_name, column_name
FROM information_schema.columns
WHERE table_schema = 'public'
AND column_name ILIKE '%cust%'; The value check is another:
SELECT status, COUNT(*) AS rows
FROM orders
GROUP BY status
ORDER BY rows DESC; Anything the dictionary does not explain — a spelling, a blank, a cluster of NULLs — is drift. Reconcile on the agreed key, not on names: join the CRM's account_id to orders.customer_id over a fixed date range and compare counts. Send the output to a named person; alerts nobody owns are alerts nobody reads. Reconciliation discipline like this underpins the analytics work in our portfolio.
What breaks when names drift, and how do you debug it?
Debug in order: join key, then values, then time boundary. When two reports disagree, first confirm both join on the same identifier; next, dump the distinct status values and look for case and whitespace variants; last, check whether one report reads a timestamp and the other a calendar date.
Renames have their own failure mode: the ALTER TABLE succeeds, and a weekly export script nobody remembered breaks at 2 a.m. Before any rename, search the old name across the repository, cron jobs, saved reports and spreadsheet macros. A name that appears in five places needs five migrations, not one. If a numbers dispute has already reached a customer, bring us the two reports — tracing the join usually takes an hour, not a week.
What are the security implications of careless names?
Careless names hide personal data from the people protecting it. A table called orders_backup_old still holds customer rows, so access reviews, retention jobs and breach inventories skip right past it. Add a classification column to the dictionary so anyone can see which fields hold personal data before they build an export.
Environment names matter too: a database labelled staging that holds production copies invites both accidents and shortcuts. Keep secrets out of names entirely — column and table names travel into dashboards, exports and error reports. And treat the dictionary as part of offboarding: when the person whose head held the conventions leaves, the page is what remains.
Which mistakes sink most naming efforts?
The classic failure is boiling the ocean on day one. Teams try to define four hundred columns, produce a document nobody opens, and quietly abandon the effort. Naming efforts survive when they start with twenty nouns, get enforced by a check that can fail, and get updated inside the change that touched the schema.
- Writing a policy instead of a dictionary — prose nobody applies.
- Enforcing by memory; a rule with no check decays within a quarter.
- Renaming live objects in one jump instead of aliasing first.
- Letting every new vendor tool invent its own terms for the same nouns.
- Abbreviating to save typing — cust, regn, amt — and charging every future reader for it.
What does keeping this alive actually cost?
Budget attention, not licences. The dictionary costs one workshop and an hour of writing; the recurring cost is a few minutes inside each schema change to update the dictionary and run the checks. What genuinely drives expense is rework: reports rebuilt, reconciliations argued, and a contractor's first month spent decoding names.
A rule of thumb from experience: if updating the dictionary feels heavier than the change itself, the dictionary has grown past its purpose — trim it back to the twenty nouns that actually argue.
What does this look like in a real business?
Picture a distributor running a CRM, a Laravel order system and a finance export. Sales' account is a company, the database's customer row is a contact person, and finance's customer number is neither. One reconciliation meeting mapped all three onto one customer_id, and every report since joins on it.
The legacy part takes longer. The orders table carried cust_ref, the old free-text customer reference. Nobody renamed it with a single ALTER TABLE. The team added customer_id, wrote both for a fortnight, exposed the dictionary name through a view, moved each consumer across, and dropped the old column on a published date after a verified backup. Twelve weeks, no broken exports — a boring rename, which is the point.
Should you buy a data catalog tool instead?
Usually, not yet: data catalog platforms pay off with dozens of databases and several analytics teams. They auto-scan schemas and centralise definitions, which matters at scale. Below that, a catalog adds hosting, configuration and a steward role before the wiki page has gone stale. Build the habit first; adopt the platform when the page stops keeping up.
| Approach | Best for | Upkeep | Watch out for |
|---|---|---|---|
| Tribal knowledge | One maintainer, one tool | None | Vanishes at handover |
| Shared spreadsheet | One team, a few terms | Minutes a week | Goes stale silently |
| Dictionary page plus checks | Most businesses with two or more systems | Updated with each schema change | Needs a named owner |
| Data catalog platform | Many databases, several teams | Hosting plus steward time | Overhead arrives before the value |
In short: agree one name and one meaning per business noun, write them in a dictionary people actually open, enforce the conventions with checks where data enters, and migrate old names slowly on published deprecation dates. That is the whole discipline — and it costs less than rebuilding the same report twice.
People also search for
- What should a web development quote actually include?
- Custom software or off-the-shelf: which fits a growing business?
- How should a small business run UAT before launch?
- Which online accounts should a business own directly?
- How do we set up website analytics so the numbers are trusted?
- Is a customer portal worth building for a small business?
If two of your reports already disagree, or a rename is looming, our team can help you run the reconciliation, draft the dictionary and wire the checks into your codebase. Tell us what is arguing with what, and see our services for the builds and ongoing maintenance that sit around this work.












0 comments
Be the first to share your thoughts.
Leave a comment
Replying to — cancel