[ACCEPTED]-Should I delete or disable a row in a relational database?-relational
It depends. (But you guessed that already, I'm 26 sure.)
In practice, the violation of proper 25 usage here is almost always in the direction 24 of deleting.
The main bad consequence of 23 deleting is how often there are dependent 22 records in other tables whose referential 21 integrity is lost when the parent record 20 goes away.
One red herring used to defend 19 deletion (which you've already dealt with 18 properly by dismissing the issue of storage 17 capacity), is expecting that it will make 16 any noticeable difference in query efficiency.
There 15 are too many cases where user or software 14 issues cause someone to need to hit the 13 big "Undo" button; if you delete, you're 12 out of luck (at least without getting special 11 help and aggravating people you'd rather 10 be nice to.)
The terminology I usually use 9 is "Active" and "Inactive".
A 8 few more points to consider (by Totophil):
- Deleting a record in some databases will not automatically free up the disk space.
- Purging any sensitive information that you no longer require helps avoiding security risks.
Data 7 protection legislation might require your 6 organisation under certain circumstances 5 to purge any identifiable information about 4 an individual. The legislation differs from 3 country to country, some pointers:
On 2 the other hand you might be required by 1 law to keep certain information.
Not deleting will create a new class of 40 bugs for all future queries. Don't forget 39 that query writing is often done by power 38 users (i.e. non-IT professionals), and junior 37 developers. So now every table that has 36 invalid data marked only by a BIT active 35 flag will need an additional AND in the 34 WHERE clause for every query from now until 33 forever. This will help users fall into 32 the pit of failure instead of the pit of 31 success. However, I strongly encourage 30 you to implement these flag systems anyhow 29 because without bad design, there is no 28 need for maintenance developers to fix the 27 numerous bugs it will create.
How valuable 26 is it to have historical data in the table? If 25 the business if forward looking, having 24 old data in the tables can just be a burden-- it 23 cause problems when creating constraints 22 (all constraints will have to be modified 21 to exclude data you wish wasn't there). Data 20 quality assurance is complicated by having 19 to continually re-identify what is "old 18 crap we are afraid to delete but never want 17 to ever use or update again" and new stuff 16 we care about.
Is it being deleted because 15 it was a mistake? If the row corresponds 14 to an entity in real life, maybe it is interesting 13 to keep and set a "vaporized", "dead", "left 12 the building" flag. If you accidentally 11 inserted a row that corresponds to no entity 10 in real life, a DELETE is not a bad thing. Are 9 imaginary customers that never existed important 8 to keep in the customer table?
And finally, personality 7 plays a big role. People can be packrats 6 with data, too. If a DBA keeps all his 5 newspapers from 30 years back and don't 4 like deleting data, maybe he should make 3 sure he's making data design decisions based 2 on the merits and not an irrelevant personal 1 preference.
After reading a book on temporal database 22 design, I came to believe in the philosophy 21 that every record of temporal significance 20 needs to have at least 4 timestamp columns. Those 19 four are: created, deleted, start, end. The 18 created and deleted timestamps are fairly 17 self-explanatory. Your system shouldn't 16 look at records where deleted is before 15 now(). The start and end columns determine 14 when the data applies to your system. It's 13 for keeping a history of changes. If you 12 need to update a record, you'd set it's 11 end time to now(), copy it, update the copy, and 10 set the copy's start time to now(). That 9 way, when you need to look at the way something 8 was historically, you can have the system 7 figure it out. You could also set the start 6 to some point in the future to have a change 5 take place automatically at that time, or 4 set the end to a future time to have it 3 automatically go away at that time. Setting 2 the created/deleted timestamps to the future 1 doesn't really make sense...
If you do use a deleted, visible, isactive, etc 2 column, you can abstract away having to 1 remember to use it by using views.
It's up to you and your requirements (some 7 things get rather hard when records exist 6 that...don't).
I will say that a boolean 5 is a bad choice, though. Make it a nullable 4 timestamp. It's pretty handy to know when 3 something was deleted, especially when you 2 deleted too much and want to undo part of 1 the delete.
It depends. If it is disabled then it is 8 easier to undelete / to see that someone 7 actually deleted the record (for auditing).
You 6 may also have a technical requirement to 5 not delete records. For example, if you 4 wanted to synchronize your database with 3 another user by just sending changed records 2 you wouldn't be able to do that if it was 1 actually deleted.
You need to have it in functional requirements. If 7 it is not said there explicitly you will 6 have to figure out it yourself.
In most cases 5 it is better to store such records in separate 4 table. You then avoid various situations 3 where one table refers another table and 2 you need to decide should records in second 1 table be treated as deleted as well or not.
Adding a "DELETED" column to your table 18 and marking rows instead of deleting them 17 creates a lot more work for you with little 16 (if any) benefit. Now, every time you write 15 a query you have to remember to include 14 "WHERE DELETED IS NOT NULL" (or whatever).
A 13 better approach is to delete data when you 12 need to delete data, and rely on your regular 11 backup process to ensure that no data is 10 ever lost. If for some reason you need 9 to keep some deleted data handy (for searches, maybe), you're 8 better off just copying the data to a different 7 table created for this purpose and then 6 deleting the originals.
I've inherited many 5 databases over the years, and this strategy 4 of flagging records instead of deleting 3 them is unfortunately very common, and (in 2 my experience at least) always leads to 1 major problems down the road.
If you will need the deleted data sometimes, but 6 not very often: you can move the records into a separate database/table (e.g.
users and 5
users_deleted, or better
This way, the data is 4 still accessible through a query (although 3 it won't be as simple as the normal one), yet 2 it doesn't clutter the original database 1 and you don't have to code around it.
Unless you have a specific need for managing 2 your own deletions, you are better off just 1 deleting the rows.
I'd like to note that there are (in most 9 countries) use-cases where you can't delete 8 records for legal reasons. Industry and 7 data dependant of course.
In this case I 6 believe the best practice guidleine is to 5 shadow table the "deleted" data 4 which gains you the benefits of actual deletion 3 outlined by MatthewMartin and by extension I have come to find this 2 pattern frequently preferable to creating 1 "active" bit-flags across my data-tables.
This should be determined by the application 27 needs. I have done it both ways. I have 26 some applications that need to support undo 25 as the cost of removing a row -- and the 24 cascading deletes that are caused by that 23 -- are too expensive to not have it. Normally, though, the 22 applications I have done require the user 21 to confirm deletes, then just do as the 20 user has asked. In some cases, you must 19 delete the data due to privacy concerns. That 18 is, if the user requests to be removed, you 17 need to really remove it, not just mark 16 it as not current. In other cases (like 15 tax-related transactions), there may be 14 reasons to keep data in a non-current state 13 until no longer required by law. I have 12 applications that fit in both categories.
Various 11 strategies can be used in the case where 10 you need to keep "archival" data. Depending 9 on whether it needs to be immediately available 8 you can push it to archive tables that are 7 either kept or backed up and cleaned out 6 regularly. If there is a need for undo 5 you may want to keep it in the current table 4 and just mark it by setting a flag. It 3 really depends on the complexity of your 2 schema, the requirements of the application, and 1 personal preference to some extent.
I am creating a CRUD and i'm facing the 2 same problem.
Solution : The D of CRUD should 1 disable instead of delete.
- "Every" query should check if the registry is disable or not (flag=1 for example). More specifically, ever select * should check that.
- Every insert should activate the registry (flag=1) by default.
- Update shouldn't change the flag.
- Disable is an update in disguise that marks the flag=0.
- Garbage collector. Exists three strategies : to delete old registries, to delete registries that are not referenced or a mix of strategies.
It's a judgment call, but I have ended up 6 adding "disabled" columns on tables where 5 I previously thought I could just delete 4 row. I'd say most of the time you're safer 3 adding a disabled column. This can get tricky 2 with n:n relations however, so that's something 1 to consider.
It's probably best to add "deleted" column 2 and offer users to undelete or purge deleted 1 items.
It depends on the function of the database. Is 6 it the source of all truth? If yes, then disable rather than 5 delete, as it is easier to recover from 4 bad operations (ie user error). If the database 3 is feed from some upstream data source, delete 2 then unused data. Any recreation/recovery 1 can be done by the upstream system.
As many have already said, the application 22 needs dictated what you want to do. But 21 to me, marking a row seems like not using 20 the right tool for the right thing. We logically 19 think of a delete as a DELETE, so when if 18 you are not allowed to delete for legal 17 reasons, then you don't delete it in the 16 first place. At the same time, i think about 15 all the internal data structure keeping 14 and indexing. Not to mention all the optimizations 13 that can be done to retrieve data, but adding 12 that check(in the view or in the query) affects 11 the performance exponentially with the complexity 10 of the database and the relations the entities 9 have.
In a nutshell, put the deletion logic 8 in the UI layer to prevent user errors and 7 give delete permissions to users who should 6 be able to delete it. Use regular backups 5 for keeping archives. If your application 4 absolutely requires a strict audit history, implement 3 it in triggers and put the audit in an off-site 2 database to avoid all that traffic, check 1 and crap from the production.
There are two additional solutions for this 22 which I have commonly used. I agree with 21 other individuals who have posted that it 20 is really up to the requirements of your 19 data.
You could prevent the user from deleting 18 the record if it will cause referential 17 integrity problems by using foreign key 16 constraints (provided your RDBMS supports 15 that). A few times I have provided a message 14 to the end-user that "You cannot delete 13 this <object> until you disassociate 12 <parent object> with it." This can 11 work as long as you don't anticipate there 10 are a tremendously high number of associations 9 with another other table or tables.
Another 8 approach is to move any disassociated records 7 to be associated with a record that isn't 6 deleted. For example, say you have a course 5 for which 10 separate class times are associated 4 with it. If you delete the course, you 3 could allow to the user to decided if all 2 10 classes are deleted or if they are associated 1 with a new or existing course.
More Related questions