Reputation: 17548
I have a requirement to change the behavior of the "delete" function on a web application on a table that has 5 child foreign key relationships. It is a fairly large sized web application so I am looking for the least risky and lowest impact change so that it will require the minimum amount of changes to the web application.
I can think of two options:
add a column to the table deleted
with default 0
, and 1
will indicate that the record has been deleted. This will require updating all selects on the table (and also, on it's child tables, as they are now orphaned) to include the clause where deleted = 0
. The web app is old and not well written (repeated code) so there are many places that will require this change, so it is risky that one or more locations might be missed.
Move the record to another copy of the table, specifically for deleted records. I would likely need to mirror every child table as well.
Option 1 seems to be more effort up front, but more maintainable in the future, option 2 is not much work up front, minimal changes to web app, but very messy. Are there other options ?
Upvotes: 5
Views: 3844
Reputation: 5636
This is an excellent example of why I am so fond of views.
Example:
create view MyData as
select ...
from AllMyData
where Deleted = 0
Write triggers on the view to handle DML as if it was the original table.
Create another view to expose the deleted rows.
Example:
create view DeletedMyData as
select ...
from AllMyData
where Deleted = 1
Implement a "soft delete" and "undelete" functionality within the app. This code will be the only code directly accessing the table, setting the value of Deleted to 0 or 1 as appropriate. Existing code will need no modification.
The child tables will probably require no changes at all. Since they are likely queried by joining with the undeleted view (the one with the original table name), records referring to "deleted" data will not be exposed but will be automatically re-exposed when data is undeleted.
UPDATE: The ON_DELETE trigger on the MyData
view would just issue an update against the actual table, setting the Deleted value to 1. An UNDELETE action can be implemented using the ON_DELETE trigger on the DeletedMyData
view to set the value to 0. So issuing a Delete on the MyData
view would perform a soft delete (the record would vanish from the MyData
data set and appear in DeletedMyData
) and issuing a Delete on the DeletedMyData
view would perform a soft undelete (the record would vanish from the DeletedMyData
data set and reappear in MyData
).
Upvotes: 4