← IndexEntry № 182·coding

Design a normalized database schema from plain requirements

Turns plain-language requirements into a normalized relational schema with DDL, relationships, and trade-offs.

Optimized for
ChatGPTClaude
§ When to use this

Schema decisions are expensive to reverse, so getting the first design close to right matters. This prompt turns plain-language requirements into a normalized relational schema—aiming for third normal form while flagging any deliberate denormalization—and expresses it as real CREATE TABLE statements for your specific engine. It models relationships explicitly, explains how it handled many-to-many cases with join tables, and recommends indexes based on the query patterns you describe. The output's trade-off notes and open-questions list are where it earns its keep: schema design is full of judgment calls (soft deletes vs. hard, UUID vs. serial, where to denormalize for read speed), and surfacing them lets you decide deliberately. Give it the database engine, because type systems and index features differ between Postgres, MySQL, and SQLite, and describe your most important query patterns so indexing advice is grounded. Use it as a design partner for a first draft you then refine—not as a final migration you apply blindly.

§ The Prompt— fill in the fields, then copy or open in a tool
§ Customize0/3 fields filled
your prompt — fill the fields above
You are an expert data engineer who designs clean relational schemas. From the requirements below, propose a normalized schema (aim for 3NF, noting any deliberate denormalization) for [DATABASE_ENGINE]. For each table, give columns with types, primary keys, foreign keys, and important constraints and indexes. Model the relationships explicitly and explain how you handled many-to-many cases. Call out trade-offs and where future scale might force changes. Expected query patterns: [QUERY_PATTERNS]. Requirements:

[REQUIREMENTS]

Return the schema as CREATE TABLE statements, an entity-relationship summary in text, and a short list of open design questions.
Open with your prompt →ChatGPTClaudeSends your filled-in prompt straight into a new chat.
§ Example Output

What you can expect back

```sql
CREATE TABLE categories (
  id        BIGSERIAL PRIMARY KEY,
  name      TEXT NOT NULL UNIQUE
);
CREATE TABLE products (
  id          BIGSERIAL PRIMARY KEY,
  category_id BIGINT NOT NULL REFERENCES categories(id),
  name        TEXT NOT NULL,
  price_cents INT  NOT NULL CHECK (price_cents >= 0)
);
CREATE INDEX idx_products_category ON products(category_id);
CREATE TABLE users (
  id    BIGSERIAL PRIMARY KEY,
  email TEXT NOT NULL UNIQUE
);
CREATE TABLE orders (
  id         BIGSERIAL PRIMARY KEY,
  user_id    BIGINT NOT NULL REFERENCES users(id),
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at DESC);
CREATE TABLE order_items (
  order_id   BIGINT NOT NULL REFERENCES orders(id),
  product_id BIGINT NOT NULL REFERENCES products(id),
  quantity   INT NOT NULL CHECK (quantity > 0),
  PRIMARY KEY (order_id, product_id)
);
```
ERD: users 1—N orders; orders N—M products via order_items; categories 1—N products.

Open questions:
- Store price on order_items to freeze historical price? (Recommended—prices change.)
- Soft deletes for products/users?
- Is one-category-per-product permanent, or will tagging be needed later?

Illustrative example — your results will vary by tool and inputs.

§ Pro Tips

Get sharper results

  • 01Always name the engine—Postgres TIMESTAMPTZ, MySQL ENUM, and SQLite's loose typing change the DDL.
  • 02Act on the 'open questions'—decisions like freezing order prices are easy now, painful later.
  • 03Give real query patterns so index suggestions match your access patterns, not generic guesses.
  • 04Review every foreign key's ON DELETE behavior before applying; the model may omit cascade rules.
§ Variations

Adapt it for your case

Migration file

Add 'Output as a single reversible migration with both up and down scripts for [migration tool].'

Add seed data

Add 'Also generate a few INSERT statements of realistic seed data covering each table and relationship.'

Tags#database#schema-design#modeling
§ FAQ

Common questions

Is the schema production-ready?

Treat it as a strong first draft. Resolve the open questions, check ON DELETE rules, and review indexing against real query volume before applying.

Why does it ask for query patterns?

Indexes should match how you read data. Without your access patterns, index suggestions are generic guesses.

Can it target my specific database?

Yes—set [DATABASE_ENGINE] to the exact engine and version so the types, constraints, and index syntax are correct.

§ Related Entries

You may also need