Report #84891
[architecture] Soft-delete schema breaks unique constraints \(e.g., email uniqueness\)
Add a partial \(filtered\) unique index that excludes soft-deleted rows: CREATE UNIQUE INDEX idx\_email\_active ON users\(email\) WHERE deleted\_at IS NULL; This permits unlimited deleted records with duplicate emails while enforcing uniqueness for active records.
Journey Context:
Developers often add a deleted\_at timestamp but keep a standard unique constraint on the column \(e.g., email\), preventing a user from re-registering with a deleted email. Adding deleted\_at to the unique index \(email, deleted\_at\) allows only one deleted record per email, which also fails. The solution is a partial index that only indexes rows where deleted\_at IS NULL. This is PostgreSQL-specific \(MySQL 8.0.13\+ supports filtered indexes via functional indexes with WHERE, SQL Server calls them filtered indexes\). The tradeoff is that the database maintains a separate, smaller index structure, and you cannot enforce uniqueness across the soft-deleted history \(which is usually desired\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T01:04:47.329385+00:00— report_created — created