Chapter 22 — Quiz
12 questions. Answers at the bottom.
Multiple choice
Q1. A migration is: - A) A backup - B) A versioned, ordered, reviewed script that changes the schema (and is tracked) - C) An ad-hoc ALTER typed into prod - D) A query
Q2. Migrations should be: - A) Run differently per environment - B) Version-controlled and applied in the same order everywhere - C) Never reviewed - D) Only for new tables
Q3. Which is generally SAFE on a large live table? - A) Dropping a column - B) Adding a nullable column - C) Renaming a column - D) Changing a column's type
Q4. CREATE INDEX CONCURRENTLY:
- A) Locks the table for writes
- B) Builds the index without blocking writes
- C) Is faster but riskier
- D) Can run inside a transaction
Q5. Renaming a column in one step on a live system is dangerous because: - A) It's slow - B) Running app code expecting the old name breaks immediately - C) It drops data - D) It can't be done
Q6. The expand-contract pattern's three phases are: - A) Backup, change, restore - B) Expand (add new), migrate (backfill/dual-write), contract (remove old) - C) Lock, alter, unlock - D) Test, deploy, rollback
Q7. During expand-contract, why is there no downtime? - A) The database is paused - B) Old and new structures both work, so schema and code never disagree - C) Users are logged out - D) It runs at night
Q8. Large data migrations should be:
- A) One giant UPDATE
- B) Batched (N rows at a time) and ideally re-runnable
- C) Done by hand
- D) Skipped
Q9. You should test migrations against: - A) An empty dev database only - B) Production-like data (including the rollback path) - C) Never test them - D) The README
Q10. NOT VALID + VALIDATE CONSTRAINT helps by:
- A) Skipping the constraint
- B) Adding a constraint without a long blocking scan, validating it separately
- C) Dropping the table
- D) Renaming
True/False
Q11. Dropping a column is easily reversible with a "down" migration. (True / False)
Q12. A change that is instant on a 100-row dev table may lock a 100-million-row production table. (True / False)
Short answer
Q13. Outline the expand-contract steps to change order_items.qty from text to integer with zero downtime.
---
Answer key
Q1 — B. A tracked, versioned, reviewed schema-change script.
Q2 — B. Version-controlled and applied identically everywhere (no drift).
Q3 — B. Adding a nullable column is fast/safe; the others are dangerous.
Q4 — B. Builds without blocking writes (but can't run in a transaction).
Q5 — B. Code using the old name breaks the instant the rename runs.
Q6 — B. Expand → migrate → contract.
Q7 — B. Both structures work during the transition, so code and schema never mismatch.
Q8 — B. Batch and make re-runnable to avoid long locks and allow resuming.
Q9 — B. Production-like data, including rollback.
Q10 — B. Avoids the long exclusive-lock scan by validating separately.
Q11 — False. Dropping a column loses its data; the rollback is usually "restore from backup," so do it as the last (contract) step.
Q12 — True. Data volume and traffic change everything; always test at scale.
Q13. Expand: add a new qty_int integer column (nullable). Migrate: backfill qty_int = qty::integer in batches (re-runnable), and deploy code that writes both and reads qty_int. Contract: once all code uses qty_int, drop the old qty and (optionally) rename qty_int to qty via another expand-contract, or have used the final name from the start. Each step is additive/backward-compatible, so there's no moment where schema and code disagree.
Scoring: 10–12 you can evolve schemas safely; 7–9 review expand-contract; below 7, redo Exercises B–C.