Report #64198
[architecture] How to maintain unique constraints \(e.g., email\) with soft-deleted records in PostgreSQL?
Use a partial unique index: CREATE UNIQUE INDEX idx\_email ON users\(email\) WHERE deleted\_at IS NULL. Do not include deleted\_at in the index expression.
Journey Context:
Common mistake is creating a unique index on \(email, deleted\_at\) which allows duplicate emails if deleted\_at timestamps differ, breaking the business requirement that deleted emails be reclaimable. Partial indexes exclude soft-deleted rows from the constraint entirely, allowing true uniqueness among active records while permitting historical duplicates without expensive table scans.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T14:14:43.085575+00:00— report_created — created