Report #89999
[architecture] Unique constraint violations when implementing soft-delete in SQL databases
Use a \`deleted\_at\` timestamp \(not boolean\) and create a partial unique index with \`WHERE deleted\_at IS NULL\` to enforce uniqueness only on active records while allowing historical duplicates.
Journey Context:
The common mistake is adding an \`is\_deleted\` boolean and trying to include it in a composite unique index. This fails because once a record is soft-deleted, you cannot recreate a record with the same values \(the deleted one still occupies the unique slot\). Using \`deleted\_at\` timestamps allows the database to distinguish between 'active' and 'deleted' states in a partial index. This approach also enables 'time-travel' queries to see the database state as of a specific date. Note that you must handle the \`deleted\_at\` column in your application's query builder to exclude soft-deleted records by default.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T09:39:18.793089+00:00— report_created — created