Database Schema Designer
Overview
Design normalized relational database schemas from business requirements, entity-relationship diagrams, or existing application code. This skill produces PostgreSQL or MySQL DDL with proper data types, constraints, indexes, and relationships following normalization principles (3NF by default) with strategic denormalization where performance requires it.
Prerequisites
- Business domain requirements or existing application models/classes to derive schema from
psql or mysql CLI for testing schema DDL
- Target database engine and version (determines available data types and features)
- Expected data volumes and query patterns for sizing and index decisions
- Multi-tenancy requirements (shared schema, schema-per-tenant, or database-per-tenant)
Instructions
- Identify all entities (nouns) from the business requirements. Each entity becomes a table. List every attribute (property) of each entity and classify as required or optional.
- Define primary keys for each table. Prefer
BIGSERIAL (PostgreSQL) or BIGINT AUTOINCREMENT (MySQL) for surrogate keys. Use UUID (via genrandom_uuid()) for distributed systems or when IDs are exposed in URLs. Natural keys are acceptable when truly immutable and unique (ISO country codes, IATA airport codes).
- Normalize the schema to Third Normal Form (3NF):
- 1NF: Eliminate repeating groups. Each column holds a single atomic value. No arrays in columns (unless using PostgreSQL array types intentionally).
- 2NF: Remove partial dependencies. Every non-key column depends on the entire primary key.
- 3NF: Remove transitive dependencies. Non-key columns depend only on the primary key, not on other non-key columns. Extract lookup tables for values that change independently.
- Define relationships between tables:
- One-to-many: Add a foreign key column on the "many" side referencing the "one" side. Example:
orders.customer_id REFERENCES customers(id).
- Many-to-many: Create a junction table with two foreign keys. Example:
productcategories(productid, category_id) with a composite primary key.
- One-to-one: Add a foreign key with a UNIQUE constraint, or merge into a single table if entities are always accessed together.
- Choose appropriate data types with precision:
- Money:
NUMERIC(12,2) or INTEGER storing cents (never FLOAT/DOUBLE)
- Timestamps:
TIMESTAMPTZ (PostgreSQL) with time zone for events; DATE for calendar dates
- Status fields: <