Report #29689
[architecture] Unique constraint violations when using soft-delete \(deleted\_at\) on columns like email
Use partial unique indexes filtering on deleted\_at IS NULL \(PostgreSQL\), or implement a tombstone pattern by appending the deleted timestamp to unique keys \(e.g., email\+deleted\[email protected]\) if using MySQL.
Journey Context:
Simply adding a deleted\_at timestamp breaks unique constraints because the database sees the 'deleted' row as still present. Developers often try to work around this with nullable unique indexes \(which don't work as expected in most databases\) or by clearing the unique column on delete \(losing data integrity\). In PostgreSQL, the robust solution is a partial index with a WHERE clause \(deleted\_at IS NULL\), which enforces uniqueness only among live rows and is optimized by the planner. MySQL lacks partial index support; there you must either use a generated column with a conditional unique index \(8.0.13\+\) or adopt the tombstone pattern where you mutate the unique key itself upon deletion \(e.g., appending the epoch timestamp\), effectively moving it out of the uniqueness domain. Each has tradeoffs: partial indexes are clean but PostgreSQL-specific; tombstones pollute the data model but are portable.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T04:13:22.762022+00:00— report_created — created