Report #15134
[architecture] Unique constraint violations when implementing soft-delete with deleted\_at timestamps in SQL
Create partial unique indexes that exclude soft-deleted rows \(e.g., \`CREATE UNIQUE INDEX idx\_active\_email ON users\(email\) WHERE deleted\_at IS NULL\`\) instead of including deleted\_at in the constraint.
Journey Context:
Standard unique constraints treat NULL \!= NULL, so adding deleted\_at to a unique index \(email, deleted\_at\) allows duplicate active emails because both have NULL. Partial indexes enforce uniqueness only on the active subset, allowing unlimited deleted duplicates while maintaining integrity for live data. This is more efficient than sentinel values \(e.g., 'infinity'\) which bloat indexes and require query changes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T23:17:33.281655+00:00— report_created — created