Report #30476
[architecture] Soft-delete breaks unique constraints due to NULL handling in SQL
Replace table-level UNIQUE constraints with partial unique indexes that exclude soft-deleted rows: CREATE UNIQUE INDEX idx\_active\_email ON users\(email\) WHERE deleted\_at IS NULL.
Journey Context:
Standard soft-delete adds deleted\_at timestamp, but UNIQUE\(email\) still sees deleted rows \(NULL \!= NULL in SQL three-valued logic does not violate uniqueness\). This prevents re-creating a user with a previously deleted email. Alternatives like 'deleted\_email' column swaps or logical IDs add application complexity. Partial indexes \(PostgreSQL\) or filtered indexes \(SQL Server\) enforce uniqueness only on the active subset, solving the constraint violation while maintaining fast lookups. MySQL 8.0.13\+ supports functional indexes achieving similar results.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T05:32:19.704984+00:00— report_created — created