Databases — MongoDB + Postgres
Two real data layers: document (Mongoose) and relational (Drizzle + Postgres)
Phase Goal
Model and query real data in MongoDB, then put Postgres behind your Node API with Drizzle — schema as TypeScript, migrations, relations, transactions — and know exactly when to reach for each. You already know SQL; this teaches Drizzle from zero and how to spend that SQL knowledge inside a real backend.
Open the written lectures for this course before checking off the phase topics.
Day 64: Mongo Concepts & Atlas
Day 65: Mongoose Schemas & Models
Day 66: CRUD with Mongoose
Day 67: Relationships & Population
Day 68: Indexes from Scratch — How a Database Finds a Row
Municipal Permit Index Benchmark
Generate 300k synthetic permit applications with district, category, submittedAt, riskScore, and status; seed identical records into Postgres and Mongo. Measure equality, range, and sorted queries before/after indexing, report rows examined versus returned and wall time, and explain one case where ignoring the index is correct.
Day 69: Index Types & Index Design — Postgres and MongoDB
Festival Schedule Index Design
List six real festival-schedule queries: events by day, venue timetable, accessibility filter, performer lookup, text search, and upcoming changes. Break down equality/sort/range needs, design the smallest supporting index set, justify every index, and record one deliberately omitted index.
Day 70: Query Plans, Diagnosis & Index Maintenance
Clinic Waitlist Slow-Query Postmortem
Diagnose three slow clinic-waitlist reads: next patient per service, overdue triage cases, and clinician queue. Capture each plan, state a hypothesis, apply one fix, and compare examined/returned rows and wall time in Postgres and Mongo; leave one acceptable query unchanged and defend that choice.
Day 71: Aggregation Pipeline
Day 72: Mongo Transactions & Data Integrity
Day 73: Data-model Trade-off Workshop
Field Survey Archive on Mongo (in progress)
Build a Mongo archive for field expeditions, sites, observations, specimens, and review notes with deliberate embedding/reference choices, supporting indexes, one aggregation, and one integrity-sensitive transaction. Finish and review it on Day 74.
Day 74: Query, Index & Migration Review
Field Survey + Collection APIs (checkpoint)
Notes API + Blog backend, both on real Mongo Atlas, indexed, with an aggregation and a transaction. Next: give a relational database the same treatment.
Day 75: Postgres Behind Your API — Drizzle from Zero
Volunteer Registry Table, End to End
Add a real Postgres volunteer registry to the Phase 5 Express service with Drizzle: schema, configuration, migration, db singleton, and validated create/list endpoints. Print the generated SQL and explain the uniqueness, status, and availability constraints.
Day 76: Modeling a Real Schema — Types, Constraints & Indexes
Equipment Booking Schema in Drizzle
Model equipment, locations, borrowers, bookings, bookingItems, and maintenance holds relationally. Include an enum status, non-overlap/inventory constraints you can defend, explicit cascade rules, and indexes for availability and history. Derive insert types and Zod schemas from tables.
Day 77: Querying with Drizzle — Builder & Relational Queries
Accessible Venue Feed, Two Query Styles
Build an accessible-venue feed twice against a venue/access-feature/inspection schema: once with relational queries and once with explicit joins plus reshape. Inspect SQL and plans, choose one implementation with evidence, then replace offset pagination with a stable `(verifiedAt, id)` cursor.
Day 78: Migrations, Seeding & Transactions
Seed-Exchange Ledger: Migrated and Transactional
Create versioned migrations for seed varieties, members, offers, and exchanges; add a column through expand/backfill/contract and write an idempotent seed. Complete an exchange plus inventory decrement transactionally, prove rollback by throwing halfway, and map a duplicate offer key to 409.
Day 79: Project — Mutual-Aid Inventory Lineage API
Mutual-Aid Inventory Lineage API — DEPLOYED
Build a Postgres/Drizzle API that traces donated goods from intake batch through storage, reservation, handoff, and adjustment. Support full-text search, faceted filters, and cursor pagination; make every multi-record handoff transactional, enforce invariants in the database, seed realistic batch histories, test against a real database, and defend the relational model.
- Claims link to sources and tags through explicit join tables; every response preserves provenance.
- Search, faceted filters, keyset pagination, deliberate indexes, and an EXPLAIN ANALYZE plan you can explain.
- Versioned Drizzle migrations, an idempotent seed script, and integration tests against a real Postgres.
- One transactional ingest that is provably all-or-nothing, and constraint violations mapped to correct HTTP status codes.
Phase Complete!
After this phase, you'll be able to:
- Mongo + Mongoose: schema, queries, indexes, aggregation, transactions
- Population & N+1 avoidance (in Mongoose and any ORM)
- Reading explain() output
- Put Postgres behind a Node API with Drizzle: schema as TypeScript, constraints, indexes, inferred types
- Query with both the builder and relational queries; read the SQL Drizzle compiles and tune it
- Versioned migrations, safe zero-downtime schema changes, seeding, and ACID transactions
- Choose document vs relational deliberately (and say where a typed query builder beats a raw driver)
Your APIs persist real data in both a document and a relational store. Now make them know who's asking.