Database Schema Design
Use this skill when the main job is choosing and evolving the storage model, not dumping generic SQL or ORM snippets.
database-schema-design is the backend storage-design anchor for:
- choosing between relational-first, document-heavy, and hybrid models
- turning domain entities into tables, collections, ownership boundaries, and lifecycle rules
- justifying constraints, indexes, tenant scope, history/audit structures, and deletion/retention behavior
- planning staged schema evolution so migrations, backfills, and cleanup are believable
- handing downstream teams one compact storage-design packet before implementation, verification, reporting, or observability work branches out
Read these support docs before handling larger or riskier work:
- references/storage-decision-matrix.md
- references/schema-review-checklist.md
- references/intake-packets-and-route-outs.md
When to use this skill
- Design a new schema for a product feature, internal tool, admin workflow, customer-data surface, or live-ops/game backend system.
- Refactor an existing storage model with weak constraints, naming drift, poor cardinality modeling, or untrusted indexing.
- Decide which fields must be first-class columns or indexed document fields versus flexible metadata payloads.
- Plan multi-tenant, audit-log, entitlement, status-history, retention, or soft-delete boundaries.
- Review whether a migration is safe, staged realistically, and honest about backfills, compatibility windows, and cleanup.
- Produce one bounded storage packet before implementation or while a risky backend change is being shaped.
When not to use this skill
- The main job is REST/GraphQL contract shape, endpoint behavior, webhook semantics, or versioning →
api-design.
- The main job is identity/session/provider setup or auth-owned user/org boundaries →
authentication-setup.
- The main job is migration verification, repository coverage, or contract/regression tests →
backend-testing.
- The main job is published docs, quickstarts, or developer-facing schema/API explanations →
api-documentation.
- The main job is broad hardening beyond data integrity, like secret handling, CSRF, cookies, or abuse controls →
security-best-practices.
- The main job is dashboard/reporting presentation or telemetry/alert coverage on top of already-modeled data →
looker-studio-bigquery or monitoring-observability.
- The request has no real domain, access pattern, or lifecycle context yet; in that case return the missing questions instead of pretending the schema is settled.
Instructions
Step 1: Classify one primary storage-design packet
Use one primary lane and one smallest useful artifact.
schema_packet:
workload_shape: oltp | analytics-adjacent | event-log | content-heavy | mixed | unknown
data_lane: relational-first | document-heavy | hybrid | unknown
change_type: greenfield | incremental | migration | cleanup | scale-fix
ownership_focus: product-core | internal-ops | marketing-customer-data | game-live-ops | mixed
durability_needs: basic | transactional | audit-heavy | compliance-sensitive | unknown
hottest_risk: integrity | queryability | migration-safety | lifecycle-drift | unclear
output_packet: design-memo | schema-review | migration-rollout | erd-plus-decisions | unknown
Normalize first:
- What are the real business entities or aggregates?
- Which reads, writes, filters, joins, or reports are highest value?
- Is this greenfield design, live-system change, or schema cleanup?
- Which rules are true business invariants versus temporary implementation convenience?
- Which platform constraints already exist (database engine, ORM, hosted service, compliance, scale)?
Step 2: Gather the minimum credible evidence
Do not design storage from vibes alone. Pull the smallest packet that supports real decisions:
- product/domain objective
- current schema, models, or representative records if they exist
- known reads/writes, filters, joins, search/reporting needs, and retention rules
- tenant/ownership, audit/history, and deletion expectations
- rollout constraints: traffic, migration windows, lock risk, compatibility concerns, downstream consumers
- open questions that would make the design fake-ready
If the evidence is thin, say so explicitly and keep the packet at review/memo level instead of pretending it is implementation-ready.
Step 3: Choose the data lane deliberately
Use references/storage-decision-matrix.md.
- Relational-first when integrity, transactions, shared invariants, joins, or reporting matter most.
- Document-heavy when one aggregate is usually read/written together and the shape varies enough that strict relational modeling would be fake precision.
- Hybrid when the transactional core is stable but some metadata/content payloads are legitimately flexible.
State the reason in one or two sentences. “Because the stack already uses it” is useful context, not the whole rationale.
Step 4: Model ownership, lifecycle, and query-critical fields
For each core entity/collection/aggregate, define:
- purpose and ownership boundary
- identifier strategy
- required vs optional attributes
- lifecycle states and timestamps
- relationships or reference direction
- tenant/org ownership if relevant
- deletion, archival, retention, and history rules
- which fields must stay queryable, unique, or reportable
- which fields can remain flexible metadata without harming search/reporting/ops
Watch for these traps:
- mirroring UI objects instead of business concepts
- hiding many-to-many or history in JSON blobs or ad hoc arrays
- collapsing mutable state, audit history, and derived/cache data into one table/document
- letting auth/profile/session ownership blur into unrelated product entities
- storing analytics, telemetry, or campaign attributes in opaque payloads when they already drive filtering, reporting, or live-ops decisions
Step 5: Design integrity and access rules together
A schema is only as good as the invariants it can defend.
Name:
- keys and ownership rules
- uniqueness / nullability / defaults / state constraints
- hottest reads, writes, filters, joins, or aggregate lookups
- indexes and why each one exists
- intentional denormalization or flexible fields and the reason they stay flexible
If you cannot name the main query shapes, the indexing guidance is probably fake.
Step 6: Plan rollout and route-outs
For incremental or live-system changes, define:
- additive vs destructive changes
- expand-and-contract, backfill, dual-read/write, or shadow-read phases if needed
- when indexes/constraints become safe to enforce
- rollback or stop conditions
- cleanup conditions for old columns/tables/doc fields
Then route adjacent work clearly using references/intake-packets-and-route-outs.md:
api-design for interface or contract changes that depend on the model
authentication-setup for identity/session/provider ownership
backend-testing for migration verification and regression coverage
looker-studio-bigquery when the main job is stakeholder dashboards/reporting over curated data
monitoring-observability when the main job is telemetry freshness, alert coverage, or runtime visibility
security-best-practices when the concern goes beyond data integrity into broader app/web hardening
Step 7: Run the boundary check
Use references/schema-review-checklist.md before finalizing.
Verify:
- One data lane and one output packet were chosen.
- Ownership, lifecycle, and query-critical fields are explicit.
- Flexible metadata is justified instead of acting as deferred modeling debt.
- Migration safety is believable for a live system.
- API/auth/testing/reporting/observability work was routed out instead of silently absorbed.
- The packet ends with the next concrete move.
Output format
## Storage Design Packet: [System or Feature]
### Packet framing
- Workload shape:
- Chosen data lane:
- Change type:
- Ownership focus:
- Why this lane fits:
### Evidence used
- Current artifacts:
- Query/reporting needs:
- Lifecycle or retention constraints:
- Assumptions / gaps:
### Entity / collection map
| Entity | Purpose | Key fields | Relationships / ownership | Lifecycle notes |
|--------|---------|------------|----------------------------|-----------------|
| ... | ... | ... | ... | ... |
### Integrity and access rules
- Required constraints:
- Uniqueness / nullability notes:
- Indexes and why:
- Flexible metadata that stays flexible:
### Rollout / migration plan
- Sequence:
- Backfill / compatibility notes:
- Cleanup conditions:
- Stop / rollback signals:
### Route-outs
- API / contract:
- Auth / identity:
- Verification:
- Reporting / observability:
### Recommended next move
- draft migration plan | review with owners | hand off to API/auth/testing/reporting | defer until missing evidence is gathered
Examples
Example 1: SaaS core model
Input: "We need schema help for a B2B SaaS app with users, organizations, memberships, subscriptions, invoices, and audit logs. We use Postgres and need something implementation-ready."
Good output direction
- chooses
relational-first
- separates users, organizations, memberships, subscriptions, and immutable invoice records clearly
- treats audit/history separately from mutable entity state
- routes session/provider details to
authentication-setup
Example 2: Flexible metadata migration
Input: "Our marketplace stores product metadata in one JSON column, but search, moderation, and filters now depend on stable fields. Plan a safe migration."
Good output direction
- chooses
hybrid
- identifies which fields must graduate from JSON into first-class columns or indexed fields
- proposes staged rollout, backfill, and cleanup conditions
- routes verification to
backend-testing
Example 3: Game live-ops boundary
Input: "We need to model player inventory, seasonal event progress, and telemetry for a live game without burying reporting needs in opaque blobs."
Good output direction
- separates player-owned transactional state from telemetry/reporting concerns
- keeps one storage packet focused on state integrity and lifecycle
- routes dashboard/telemetry follow-through to
looker-studio-bigquery or monitoring-observability
Best practices
- Start from business invariants and access patterns, not table aesthetics.
- Treat migration safety as part of schema design, not a later ops chore.
- Keep flexible metadata honest: useful when justified, dangerous when it hides query-critical fields.
- Separate mutable state, history/audit, and derived/reporting data.
- Route adjacent API/auth/testing/reporting work outward instead of turning this into a generic backend mega-skill.
- Prefer a durable packet over giant vendor-specific example dumps.
References
1---2name: database-schema-design3description: Design storage-model and migration-safety packets for relational, document-heavy, and hybrid data systems. Use when the user needs entity ownership, constraints, indexes, staged schema changes, or queryable-vs-flexible field decisions across backend/fullstack products, internal ops tools, marketing/customer-data workflows, or game/live-ops systems. Route API contracts to api-design, auth-owned identity/session modeling to authentication-setup, verification to backend-testing, and reporting/telemetry follow-through to looker-studio-bigquery or monitoring-observability.4license: MIT5---6789101112# Database Schema Design1314Use this skill when the main job is **choosing and evolving the storage model**, not dumping generic SQL or ORM snippets.1516`database-schema-design` is the backend storage-design anchor for:17- choosing between relational-first, document-heavy, and hybrid models18- turning domain entities into tables, collections, ownership boundaries, and lifecycle rules19- justifying constraints, indexes, tenant scope, history/audit structures, and deletion/retention behavior20- planning staged schema evolution so migrations, backfills, and cleanup are believable21- handing downstream teams one compact storage-design packet before implementation, verification, reporting, or observability work branches out2223Read these support docs before handling larger or riskier work:24- [references/storage-decision-matrix.md](references/storage-decision-matrix.md)25- [references/schema-review-checklist.md](references/schema-review-checklist.md)26- [references/intake-packets-and-route-outs.md](references/intake-packets-and-route-outs.md)2728## When to use this skill29- Design a new schema for a product feature, internal tool, admin workflow, customer-data surface, or live-ops/game backend system.30- Refactor an existing storage model with weak constraints, naming drift, poor cardinality modeling, or untrusted indexing.31- Decide which fields must be first-class columns or indexed document fields versus flexible metadata payloads.32- Plan multi-tenant, audit-log, entitlement, status-history, retention, or soft-delete boundaries.33- Review whether a migration is safe, staged realistically, and honest about backfills, compatibility windows, and cleanup.34- Produce one bounded storage packet before implementation or while a risky backend change is being shaped.3536## When not to use this skill37- **The main job is REST/GraphQL contract shape, endpoint behavior, webhook semantics, or versioning** → `api-design`.38- **The main job is identity/session/provider setup or auth-owned user/org boundaries** → `authentication-setup`.39- **The main job is migration verification, repository coverage, or contract/regression tests** → `backend-testing`.40- **The main job is published docs, quickstarts, or developer-facing schema/API explanations** → `api-documentation`.41- **The main job is broad hardening beyond data integrity, like secret handling, CSRF, cookies, or abuse controls** → `security-best-practices`.42- **The main job is dashboard/reporting presentation or telemetry/alert coverage on top of already-modeled data** → `looker-studio-bigquery` or `monitoring-observability`.43- The request has no real domain, access pattern, or lifecycle context yet; in that case return the missing questions instead of pretending the schema is settled.4445## Instructions4647### Step 1: Classify one primary storage-design packet48Use one primary lane and one smallest useful artifact.4950```yaml51schema_packet:52 workload_shape: oltp | analytics-adjacent | event-log | content-heavy | mixed | unknown53 data_lane: relational-first | document-heavy | hybrid | unknown54 change_type: greenfield | incremental | migration | cleanup | scale-fix55 ownership_focus: product-core | internal-ops | marketing-customer-data | game-live-ops | mixed56 durability_needs: basic | transactional | audit-heavy | compliance-sensitive | unknown57 hottest_risk: integrity | queryability | migration-safety | lifecycle-drift | unclear58 output_packet: design-memo | schema-review | migration-rollout | erd-plus-decisions | unknown59```6061Normalize first:621. What are the real business entities or aggregates?632. Which reads, writes, filters, joins, or reports are highest value?643. Is this greenfield design, live-system change, or schema cleanup?654. Which rules are true business invariants versus temporary implementation convenience?665. Which platform constraints already exist (database engine, ORM, hosted service, compliance, scale)?6768### Step 2: Gather the minimum credible evidence69Do not design storage from vibes alone. Pull the smallest packet that supports real decisions:70- product/domain objective71- current schema, models, or representative records if they exist72- known reads/writes, filters, joins, search/reporting needs, and retention rules73- tenant/ownership, audit/history, and deletion expectations74- rollout constraints: traffic, migration windows, lock risk, compatibility concerns, downstream consumers75- open questions that would make the design fake-ready7677If the evidence is thin, say so explicitly and keep the packet at review/memo level instead of pretending it is implementation-ready.7879### Step 3: Choose the data lane deliberately80Use [references/storage-decision-matrix.md](references/storage-decision-matrix.md).8182- **Relational-first** when integrity, transactions, shared invariants, joins, or reporting matter most.83- **Document-heavy** when one aggregate is usually read/written together and the shape varies enough that strict relational modeling would be fake precision.84- **Hybrid** when the transactional core is stable but some metadata/content payloads are legitimately flexible.8586State the reason in one or two sentences. “Because the stack already uses it” is useful context, not the whole rationale.8788### Step 4: Model ownership, lifecycle, and query-critical fields89For each core entity/collection/aggregate, define:90- purpose and ownership boundary91- identifier strategy92- required vs optional attributes93- lifecycle states and timestamps94- relationships or reference direction95- tenant/org ownership if relevant96- deletion, archival, retention, and history rules97- which fields must stay queryable, unique, or reportable98- which fields can remain flexible metadata without harming search/reporting/ops99100Watch for these traps:101- mirroring UI objects instead of business concepts102- hiding many-to-many or history in JSON blobs or ad hoc arrays103- collapsing mutable state, audit history, and derived/cache data into one table/document104- letting auth/profile/session ownership blur into unrelated product entities105- storing analytics, telemetry, or campaign attributes in opaque payloads when they already drive filtering, reporting, or live-ops decisions106107### Step 5: Design integrity and access rules together108A schema is only as good as the invariants it can defend.109110Name:111- keys and ownership rules112- uniqueness / nullability / defaults / state constraints113- hottest reads, writes, filters, joins, or aggregate lookups114- indexes and why each one exists115- intentional denormalization or flexible fields and the reason they stay flexible116117If you cannot name the main query shapes, the indexing guidance is probably fake.118119### Step 6: Plan rollout and route-outs120For incremental or live-system changes, define:121- additive vs destructive changes122- expand-and-contract, backfill, dual-read/write, or shadow-read phases if needed123- when indexes/constraints become safe to enforce124- rollback or stop conditions125- cleanup conditions for old columns/tables/doc fields126127Then route adjacent work clearly using [references/intake-packets-and-route-outs.md](references/intake-packets-and-route-outs.md):128- `api-design` for interface or contract changes that depend on the model129- `authentication-setup` for identity/session/provider ownership130- `backend-testing` for migration verification and regression coverage131- `looker-studio-bigquery` when the main job is stakeholder dashboards/reporting over curated data132- `monitoring-observability` when the main job is telemetry freshness, alert coverage, or runtime visibility133- `security-best-practices` when the concern goes beyond data integrity into broader app/web hardening134135### Step 7: Run the boundary check136Use [references/schema-review-checklist.md](references/schema-review-checklist.md) before finalizing.137138Verify:1391. One data lane and one output packet were chosen.1402. Ownership, lifecycle, and query-critical fields are explicit.1413. Flexible metadata is justified instead of acting as deferred modeling debt.1424. Migration safety is believable for a live system.1435. API/auth/testing/reporting/observability work was routed out instead of silently absorbed.1446. The packet ends with the next concrete move.145146## Output format147148```markdown149## Storage Design Packet: [System or Feature]150151### Packet framing152- Workload shape:153- Chosen data lane:154- Change type:155- Ownership focus:156- Why this lane fits:157158### Evidence used159- Current artifacts:160- Query/reporting needs:161- Lifecycle or retention constraints:162- Assumptions / gaps:163164### Entity / collection map165| Entity | Purpose | Key fields | Relationships / ownership | Lifecycle notes |166|--------|---------|------------|----------------------------|-----------------|167| ... | ... | ... | ... | ... |168169### Integrity and access rules170- Required constraints:171- Uniqueness / nullability notes:172- Indexes and why:173- Flexible metadata that stays flexible:174175### Rollout / migration plan176- Sequence:177- Backfill / compatibility notes:178- Cleanup conditions:179- Stop / rollback signals:180181### Route-outs182- API / contract:183- Auth / identity:184- Verification:185- Reporting / observability:186187### Recommended next move188- draft migration plan | review with owners | hand off to API/auth/testing/reporting | defer until missing evidence is gathered189```190191## Examples192193### Example 1: SaaS core model194**Input:** "We need schema help for a B2B SaaS app with users, organizations, memberships, subscriptions, invoices, and audit logs. We use Postgres and need something implementation-ready."195196**Good output direction**197- chooses `relational-first`198- separates users, organizations, memberships, subscriptions, and immutable invoice records clearly199- treats audit/history separately from mutable entity state200- routes session/provider details to `authentication-setup`201202### Example 2: Flexible metadata migration203**Input:** "Our marketplace stores product metadata in one JSON column, but search, moderation, and filters now depend on stable fields. Plan a safe migration."204205**Good output direction**206- chooses `hybrid`207- identifies which fields must graduate from JSON into first-class columns or indexed fields208- proposes staged rollout, backfill, and cleanup conditions209- routes verification to `backend-testing`210211### Example 3: Game live-ops boundary212**Input:** "We need to model player inventory, seasonal event progress, and telemetry for a live game without burying reporting needs in opaque blobs."213214**Good output direction**215- separates player-owned transactional state from telemetry/reporting concerns216- keeps one storage packet focused on state integrity and lifecycle217- routes dashboard/telemetry follow-through to `looker-studio-bigquery` or `monitoring-observability`218219## Best practices2201. Start from business invariants and access patterns, not table aesthetics.2212. Treat migration safety as part of schema design, not a later ops chore.2223. Keep flexible metadata honest: useful when justified, dangerous when it hides query-critical fields.2234. Separate mutable state, history/audit, and derived/reporting data.2245. Route adjacent API/auth/testing/reporting work outward instead of turning this into a generic backend mega-skill.2256. Prefer a durable packet over giant vendor-specific example dumps.226227## References228- [PostgreSQL Data Definition docs](https://www.postgresql.org/docs/current/ddl.html)229- [Prisma Data Guide — Making Connections](https://www.prisma.io/dataguide/datamodeling/making-connections)230- [MongoDB data modeling docs](https://www.mongodb.com/docs/manual/data-modeling/)231- [Firestore structure-data guide](https://firebase.google.com/docs/firestore/manage-data/structure-data)