Report #74459
[architecture] Soft-delete schema breaks unique constraints and foreign key references when re-inserting records
Use partial unique indexes \(filtered indexes\) that exclude soft-deleted rows by indexing only where deleted\_at IS NULL, and keep deleted\_at as nullable timestamp rather than boolean; for foreign keys, either cascade hard-delete children or remove FK constraints and enforce referential integrity at the application layer during the transition window
Journey Context:
Most teams add a deleted\_at timestamp column thinking it solves soft-delete, but then hit unique constraint violations when a user deletes their account and tries to re-register with the same email—the unique index sees the soft-deleted row. Using boolean is\_deleted fails because partial indexes can't efficiently filter on boolean without timestamp context, and you lose temporal data for GDPR retention policies. The solution is database-specific partial indexes: PostgreSQL supports WHERE deleted\_at IS NULL directly; MySQL 8.0.13\+ requires generated columns and functional indexes to simulate partial indexing. For foreign keys, soft-deleting a parent while children exist violates FK constraints; you must either hard-delete children \(cascade\) or drop the FK constraint and enforce the check in application code during the migration phase, re-adding it later if needed.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T07:34:42.636059+00:00— report_created — created