NestJS Database
NestJS Database Standards
Selection Framework
1. Data Structure Analysis (The "What")
- Structured & Highly Related: Users, Orders, Inventory, Financials.
- Choice: PostgreSQL (Default).
- Why: Strict schema validation, ACID transactions, complex generic queries (Joins).
- Unstructured / Polymorphic: Product Catalogs (lots of unique attributes), CMS Content, Raw JSON blobs.
- Choice: MongoDB.
- Why: Schema flexibility, fast development speed for flexible data models.
- Time-Series / Metrics: IoT Sensor Data, Stock Prices, Server Logs.
- Choice: TimescaleDB (Postgres Extension).
- Why: Compression, hypertable partitioning, rapid ingestion.
2. Access Pattern Analysis (The "How")
- Transactional (OLTP): "User buys items to cart".
- Requirement: Strong Consistency (ACID). SQL is mandatory.
- Analytical (OLAP): "Dashboard showing sales trends".
- Requirement: Aggregation speed. Columnar storage (ClickHouse) or Read Replicas.
- High Throughput Write: "1M events/sec".
- Requirement: Append-only speed. Cassandra / DynamoDB (Leaderless replication).
3. Decision Matrix
| Feature Needed | Primary Choice | Alternative |
|---|---|---|
| General Purpose App | PostgreSQL | MySQL |
| Flexible JSON Docs | MongoDB | PostgreSQL (JSONB) |
| Search Engine | ElasticSearch | PostgreSQL (Full Text) |
| Financial Transactions | PostgreSQL | (None) |
Patterns
- Repository Pattern: Isolate database logic.
- TypeORM: Inject
@InjectRepository(Entity). - Prisma: Create a comprehensive
PrismaService.
- TypeORM: Inject
- Abstraction: Services should call Repositories, not raw SQL queries.
Configuration (TypeORM)
- Async Loading: Always use
TypeOrmModule.forRootAsyncto load secrets fromConfigService. - Sync: Set
synchronize: falsein production; use migrations instead.
Scaling & Production
- Read Replicas: Configure separate
replicationconnections (Master for Write, Slaves for Read) in TypeORM/Prisma to distribute load. - Connection Multiplexing:
- Problem: Scaling K8s pods to 100+ exhausts DB connection limits (100 pods * 10 connections = 1000 conns).
- Solution: Use PgBouncer (Postgres) or ProxySQL (MySQL) in transaction mode. Do NOT rely solely on ORM pooling.
- Migrations:
- NEVER run
synchronize: truein production. - Execution: Run migrations via a dedicated "init container" or CD job step. Do NOT auto-run inside the main app process on startup (race conditions when scaling to multiple pods).
- NEVER run
- Soft Deletes: Use
@DeleteDateColumn(TypeORM) or middleware (Prisma) to preserve data integrity.
Architectures (Multi-Tenancy & Sharding)
- Column-Based (SaaS Standard): Single DB,
tenant_idcolumn.- Scale: High. Isolation: Low.
- Code: Requires Row-Level Security (RLS) policies or strict
Wherescopes.
- Schema-Based: One DB, one Schema per Tenant.
- Scale: Medium. Isolation: Medium. Good for B2B.
- Database-Based: One DB per Tenant.
- Scale: Low (max ~500 tenants per cluster). Isolation: High.
- Code: Requires "Connection Switching" middleware. Complex.
- Horizontal Sharding:
- Logic: Shard massive tables by a key (e.g.
user_id) across physical nodes to exceed single-node write limits. - Complexity: Extreme. Avoid until >10TB data. Use "Partitioning" first.
- Logic: Shard massive tables by a key (e.g.
- Partioning (Postgres):
- Strategy: Use native Table Partitioning (e.g., by range/date) for massive tables (Logs, Audit, Events).
- App Logic: Ensure partition keys (e.g.,
created_at) are included inWHEREclauses to enable "Partition Pruning".
Migrations & Data Evolution
- Separation:
- Schema Migrations (DDL): Structural changes (
CREATE TABLE,ADD COLUMN). Fast. Run before app deploy. - Data Migrations (DML): transforming data (
UPDATE users SET name = ...). Slow. Run as background jobs or separate scripts purely to avoid locking tables for too long.
- Schema Migrations (DDL): Structural changes (
- Zero-Downtime Field Migration (Expand-Contract Pattern):
- Expand: Add new column
new_field(nullable). Deploy App v1 (Writes to botholdandnew). - Migrate: Backfill data from
oldtonewin batches (background script). - Contract: Deploy App v2 (Reads/Writes only
new). Dropold_fieldin next schema migration.
- Expand: Add new column
- Seeding:
- Dev: Use factories (
@faker-js/faker) to generate mock data. - Prod: Only seed static dictionaries (Roles, Countries) using "Upsert" logic to prevent duplicates.
- Dev: Use factories (
Best Practices
- Pagination: Mandatory. Use limit/offset or cursor-based pagination.
- Indexing: Define indexes in code (decorators/schema) for frequently filtered columns (
where,order by). - Transactions: Use
QueryRunner(TypeORM) or$transaction(Prisma) for all multi-step mutations to ensure atomicity.
More from diegosouzapw/awesome-omni-skill
music-assistant
Control Home Assistant Music Assistant - browse library, search, play, manage preferences and moods.
12agent-code-generator
Generates Agent definitions (.md files) based on user intent and standard templates.
6terragrunt-generator
Comprehensive toolkit for generating best practice Terragrunt configurations (HCL files) following current standards and conventions. Use this skill when creating new Terragrunt resources (root configs, child modules, stacks, environment setups), or building multi-environment Terragrunt projects.
6api contract sync manager
Validate OpenAPI, Swagger, and GraphQL schemas match backend implementation. Detect breaking changes, generate TypeScript clients, and ensure API documentation stays synchronized. Use when working with API spec files (.yaml, .json, .graphql), reviewing API changes, generating frontend types, or validating endpoint implementations.
5upstash/workflow typescript sdk skill
Lightweight guidance for using the Upstash Workflow SDK to define, trigger, and manage workflows. Use this Skill whenever a user wants to create workflow endpoints, run steps, or interact with the Upstash Workflow client.
5upstash/search typescript sdk
Entry point for documentation skills covering Upstash Search quick starts, core concepts, and TypeScript SDK usage. Use when a user asks how to get started, how indexing works, or how to use the TS client.
5