← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Database Schema Design

database PHP 5.0+ Intermediate
debt(d5/e7/b9/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches' (d5). Schema design issues like missing primary keys, no FK constraints, and VARCHAR(255) everywhere can be detected by tools like mysql-workbench, pgadmin, and schemacrawler as listed in detection_hints. However, semantic issues (wrong cardinality, inappropriate data types for the domain) require manual review, so this sits at the specialist-tool level.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor' (e7). The misconception explicitly states that fixing bad schema decisions 'requires painful multi-step migrations on live tables with millions of rows.' While quick_fix suggests designing properly upfront, remediation after go-live involves downtime risk, data migration scripts, and potentially touching every query that touches the affected tables. This is worse than a single-component refactor but not quite full architectural rework.

b9 Burden Structural debt — long-term weight of choosing wrong

Closest to 'defines the system's shape' (b9). Database schema is the foundational architectural choice that every other layer depends on. Wrong FK cardinality, missing constraints, or inappropriate data types become load-bearing across the entire system. applies_to shows this affects all contexts (web, cli), and the why_it_matters confirms that schema decisions pervade everything. You either live with bad schema decisions or face a major rework.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception directly states the trap: developers believe 'schema design can be fixed later with migrations' when in reality some decisions are extremely costly to change post-deployment. This contradicts how migrations work in simpler cases (where they're indeed easy), leading competent developers to underestimate the permanence of early schema choices. The common_mistakes list reinforces multiple non-obvious pitfalls.

About DEBT scoring →

Also Known As

database design schema ER design

TL;DR

The process of defining tables, columns, data types, constraints, and relationships — decisions made at schema design time are expensive to reverse once data is live.

Explanation

Good schema design balances normalisation, query patterns, and future flexibility. Key decisions: appropriate data types (INT not VARCHAR for IDs), NOT NULL constraints by default with explicit NULL allowances, indexes aligned with access patterns, and soft-delete patterns vs hard deletes. Schema evolution is managed through migrations. Naming conventions (snake_case, plural table names) should be consistent. The biggest cost of bad schema design is not the initial pain but the migration tax paid on every subsequent change.

Diagram

flowchart TD
    subgraph Normalisation_Goals
        DUP[Eliminate duplicate data]
        ANO[Prevent update anomalies]
        INT[Enforce referential integrity]
    end
    subgraph Normal_Forms
        UNF[Unnormalised: repeated groups]
        NF1[1NF: atomic values no repeats]
        NF2[2NF: no partial dependencies]
        NF3[3NF: no transitive dependencies]
        UNF --> NF1 --> NF2 --> NF3
    end
    subgraph Denormalisation
        PERF2[When reads dominate<br/>add redundant data for speed]
        MAT[Materialised views<br/>pre-computed aggregates]
    end
style NF3 fill:#238636,color:#fff
style UNF fill:#f85149,color:#fff
style PERF2 fill:#d29922,color:#fff

Common Misconception

Schema design can be fixed later with migrations — some bad decisions (wrong data type, missing constraint, wrong FK cardinality) require painful multi-step migrations on live tables with millions of rows.

Why It Matters

A VARCHAR(255) used as a primary key, a missing NOT NULL constraint, or a wrong FK relationship discovered after go-live costs days of careful migration work and downtime risk.

Common Mistakes

  • Using VARCHAR for all columns including numeric IDs — INT is smaller, faster to index, and prevents invalid values.
  • No NOT NULL constraints by default — nullable columns make every query more complex and null propagation causes bugs.
  • Singular vs plural table names inconsistently — pick one convention and enforce it everywhere.
  • Using DATETIME instead of TIMESTAMPTZ in PostgreSQL — timezone-naive timestamps cause subtle bugs for international users.

Code Examples

✗ Vulnerable
-- Poor schema design:
CREATE TABLE user (
    id VARCHAR(255),           -- Should be INT or UUID
    name VARCHAR(255),         -- Nullable by default — is name optional?
    email VARCHAR(255),        -- No UNIQUE constraint
    age VARCHAR(255),          -- Age as string?
    created VARCHAR(255)       -- Timestamp as string?
);
✓ Fixed
-- Well-designed schema:
CREATE TABLE users (             -- Plural, snake_case
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name VARCHAR(200) NOT NULL,
    email VARCHAR(254) NOT NULL UNIQUE,
    age SMALLINT CHECK (age >= 0 AND age < 150),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 32
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping F 0 pings S 1 ping S 0 pings M 0 pings T 3 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 2 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Perplexity 8 Amazonbot 8 Google 4 Unknown AI 2 Ahrefs 2 SEMrush 2 Majestic 1
crawler 24 crawler_json 3
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
Design for reads first (how will this data be queried most often?) then normalise for writes — add appropriate indexes, foreign keys, and constraints from the start rather than retrofitting
📦 Applies To
PHP 5.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
Table without primary key; no foreign key constraints; columns without appropriate NOT NULL constraints; VARCHAR(255) for everything
Auto-detectable: ✓ Yes mysql-workbench pgadmin schemacrawler
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update

✓ schema.org compliant