I need some wisdom shed on the controversy over soft-deletes vs hard-deletes in a relational-database-centric application. Commentaries like this, this, and this all discourage soft-deletes as basically a hack, a dirty, easy way out, and claim that hard-deletes are the better way.
I'd love to agree. But nobody seems to mention how to deal with one major, inescapable problem: how can one hard-delete a row when a foreign key constraint prevents its deletion, and when cascade-deleting is not an option?
Essentially, if you want to hard-delete entity A, and entity B is pointing to it, and for business reasons B simply cannot be removed, doesn't that force you to use some form of soft-delete (i.e. keep the record right where it is)?
If you have a customer "Acme" who has made transaction 10001, you can't simply just hard-delete Acme because the virtually any business would require that:
- No transaction can be deleted
- A transaction must point to the customer that made it
Regardless of how Acme got "deleted" (hard, soft, over-medium) a sales report, for instance, would still have to show that Transaction #10001 was made on 2010-05-01 by customer Acme--even if Acme is no longer around. So it requires that Acme be still stored at least somewhere in the system.
One thread keeps coming up from the advocates of hard-delete: use a proper audit table, and do things like keep a serialized copy of the deleted object in there. But we can't redirect the FK of Transaction #10001 to this particular row in the audit table. What then? Create an "OldCustomers" table that mirrors the schema of "Customers" and somehow redirect every FK in the system that pointed to Acme there? I'm no DB expert so I don't know if that's even possible, but even if it were, now all your reporting queries have to factor in two tables (sounds even worse than having to append AND IsDeleted = false
to all queries)
In short, I feel like I'm missing something because hard- and soft-deletes are debated--implying that they are both feasible options. But as I understand it, in 95% of business cases, there is no possibility for using hard-delete (on a technical level, due FK constraints, and on a logical level, simply because a thing can't just disappear when another thing points to it)