What it is
The Schema Design & Naming Conventions Guide is the set of decisions a senior data engineer locks in before the first table ships — naming, keys, types, and constraints — so the schema stays readable and refactorable at a hundred tables instead of ten. It is part rationale, part naming-conventions reference table, part per-table design checklist, and part 'decide these once, up front' Q&A. Adopt it once and every new table, column, and migration follows the same predictable shape, which is what keeps a growing schema from becoming a thicket of one-off choices.
The guide opens with why conventions beat cleverness: consistency compounds. When every table has a surrogate primary key, every foreign key is a real constraint, and every timestamp is UTC timestamptz, a developer can predict the shape of a table they have never seen. The per-table checklist makes that concrete — a BIGINT identity or UUID primary key never relying on a natural key alone, declared FK constraints rather than conventions, an index on every foreign-key column (the database does not add it for you), created_at and updated_at on every table, and the narrowest correct type for each column.
Where it earns its keep is the type and constraint discipline. NOT NULL by default, so nullability is a deliberate decision; CHECK constraints for enums and ranges; numeric or decimal for money but never float; text over varchar(n) unless a real limit exists; and domain-driven names — a column is total_amount_cents, not the label shown on a screen. The 'decide once' Q&A confronts the genuinely hard calls — UUID versus auto-increment BIGINT, integer cents versus NUMERIC for money, enum type versus lookup table versus CHECK — with the trade-offs spelled out so the team chooses deliberately and then stays consistent.
What it's used for
Teams use the conventions guide to standardize schema decisions before they fossilize, so a database stays coherent as it grows. It is a reference for new tables and a rubric for reviewing migrations. The concrete jobs it does:
- ✓ Establishing naming conventions — consistent casing, pluralization, and column naming so a developer can predict a table's shape from its name without reading the DDL.
- ✓ Mandating surrogate primary keys — a BIGINT identity or UUID on every table, never relying on a natural key alone, so the PK is stable even as business attributes change.
- ✓ Enforcing real foreign-key constraints and indexing every FK column — because the database enforces referential integrity only when the constraint is declared, and unindexed FKs cripple joins and cascade deletes.
- ✓ Standardizing timestamps — created_at and updated_at on every table, stored in UTC as timestamptz, with updated_at maintained by trigger or app.
- ✓ Choosing the narrowest correct type — integer keys over text, numeric/decimal for money (never float), text over varchar(n) unless a real limit exists — and defaulting columns to NOT NULL.
- ✓ Adding CHECK constraints for enums and ranges, and deciding deliberately between an enum type, a lookup table, or a CHECK for fixed value sets.
- ✓ Keeping names domain-driven rather than UI-driven — total_amount_cents, not the on-screen label — so the schema survives interface redesigns.
Who uses it
Schema conventions are a team agreement, so the guide is written for everyone who creates, reviews, or evolves the data model. Its value is consistency, which only holds if the whole team follows it.
Context & good to know
The cost of inconsistent schema design is invisible early and crippling later. With ten tables, a few naming quirks and a missing FK index are tolerable; at a hundred tables, every inconsistency multiplies the cognitive load of working with the data, and every missing constraint is a latent integrity bug. This guide front-loads the decisions precisely because they are cheap to make before the first table ships and expensive to retrofit once a hundred tables and their migrations depend on the choice.
The primary-key question is the canonical 'decide once' call. BIGINT identity keys are smaller, faster to index, and naturally ordered for good locality; UUIDs hide row counts, allow client-side generation, and avoid cross-shard collisions but bloat indexes unless you use a time-ordered variant like UUIDv7 or ULID. There is no universally right answer, which is exactly why the guide insists the team pick one deliberately and apply it consistently rather than mixing strategies table by table.
Type discipline is where data integrity is quietly won. Storing money as FLOAT introduces rounding errors that surface as accounting discrepancies; defaulting columns to nullable makes every query defend against NULLs that should never exist; choosing varchar(n) with an arbitrary limit creates painful migrations when the limit proves wrong. The guide's defaults — NUMERIC or integer cents for money, NOT NULL by default, text over bounded varchar, CHECK constraints for ranges — encode hard-won lessons that apply across PostgreSQL, MySQL, and Oracle Database alike.
Spotsaas includes this guide in its database-management resources because schema quality is a durable, often underappreciated differentiator between teams — and the conventions translate across engines. Whether a team standardizes on PostgreSQL, MariaDB, or a document model in MongoDB, the underlying questions of naming, keys, types, and constraints recur, and a guide that answers them once helps a team keep its data model clean as the product and the table count grow.