15

In SQL Server 2008, there is a Primary table which is linked to three other child tables by 1 to many relationship. So, we are thinking of using Cascading delete in the primary table, so that all the records on the child table will be removed when record from primary table is deleted.

  1. So, is cascading delete a correct choice here?
  2. When cascading detele should not be used?
0

3 Answers 3

19

I am generally wary of cascaded deletes (and other automatic actions that could drop/damage data), either via triggers or ON <something> CASCADE. Such facilities are very powerful, but also potentially dangerous.

  • So, is cascading delete a correct choice here?

It would certainly do what you are looking for it to do: remove related records when a parent record is removed, without you needing to implement any other logic to ensure that children get removed first therefore making your code more concise. All the actions will be wrapped in an implicit transaction so if something blocks the child deletes the whole operation is blocked, maintaining referential integrity with little or no extra coding effort.

Make sure that your use of cascaded deletes and other "behind the scenes" actions are well documented so future maintainers of the system are fully aware of it.

  • When cascading detele should not be used?

It should not be used if you are paranoid like me! One key point to consider is the other developers who currently, or may in future, work on your code/database (hence the comment above about documenting any "hidden" behaviours).

It is quite common in my experience for inexperienced people to use DELETE then re-INSERT in order to update rows, especially when what they really want is a MERGE/UPSERT operation (update existing rows and create new ones where a row with a given key does not exist) and the DBMS doesn't support merge/upsert (or they are unaware of its support). Without cascaded actions this is perfectly safe (or will error when it threatens data integrity) but if someone does this for rows in a parent table where referring FKs have ON DELETE CASCADE set then related data will be deleted as a result of the initial delete and not replaced - so data is lost (not that even if the delete and subsequent insert are wrapped in explicit transactions, the cascade happens with the delete operation - it won't wait to see if the transaction replaces rows in the parent table in subsequent statements) and the cascade could continue through other relation ships (for instance: delete a senior supervisor, his team get deleted by cascade, his teams' teams get deleted by cascade, all the tracked records for all those people get deleted by cascade, ...). Without cascading enabled, you would just get an error here instead of the data being silently lost.

4
  • Will there be any performance implications? Like acquiring a lock and manually deleting would be better than cascade?
    – Ramesh
    Sep 10, 2013 at 3:58
  • I would assume that there would be very little difference, assuming you have the more manual process wrapped in an explicit transaction which you should do for consistency concerns. Both the manual and automatic (cascade) methods will be affected by locking and isolation levels once concurrency is considered, of course. Sep 10, 2013 at 9:08
  • If you don't use On Cascade delete, then how do you delete a parent row and also all the corresponding childs & grandchilds?
    – Juan Perez
    Nov 22, 2023 at 3:45
  • @JuanPerez - as stated in the answer: without cascade you need to make sure that the child rows in other tables are deleted first so cascading is not needed. This is less convenient, but that is the trade-off you make with cascading: gaining convenience in exchange for some risk (the risk that a bug or other accident will silently remove a lot more than it otherwise would where it might remove nothing without cascade due to the FK exceptions that would result). Nov 22, 2023 at 17:24
5

I guess the answer boils down to whether or not makes sense for your situation, it depends. For your situation, does it make sense for the rows in the 'child' table to remain if their corresponding 'primary' rows go? Would the data in the child table be meaningless without the parent? If so, then cascading delete would enforce referential integrity. You might want to keep child rows as a record, an archive of past activity (though potentially you could write these rows to another table specially for this purpose).

An example I use to illustrate this point is the doctor/patient relation. One doc can have many patients. A patient can only be a patient if they have a doctor. If the doc goes (leaves the practice) then something has to happen to the remaining patients. One possibility is that they get purged. Another is that a default value replaces the doc reference or they could be removed from the main table and placed somewhere else. Alternatively no activity occurs and the patients remain as they were, untouched, as though the doc was still present. It depends what you want to do.

From personal experience think carefully about the design of the database. This week I had to run a purge of orphaned records in a table which pointed to nowhere and was literally taking up space.

2
  • 1
    I have to delete the child records when the parent record goes.
    – Ramesh
    Sep 5, 2013 at 8:20
  • 1
    If the records must go completely and they don't make sense to keep, then a cascading delete would make more sense in your situation Sep 5, 2013 at 8:26
3

Using cascading delete is a matter of personal preference, like whether to name tables with plural names or not (Customer vs Customers).

I would prefer to never use cascading delete. Some database designs avoid deleting at all. There are few justifications to delete data from a database when disk space is so cheap. Some database designs set an additional field "IsDeleted" rather than physically delete data.

If you have to delete data then using stored procedures to manage this gives you more transparency and control. Your application can execute a stored procedure which deletes from the child then parent. You don't know how the business requirements will change over time so sp's will give you more versatility. That's my 2c.

1
  • 1
    True, it gives you more versatility, but it also introduces "hidden" behaviour, meaning you have to have additional documentation for those sps (so that ppl know what business action requires what sp) another way could be to restrict sql users to only be able to execute those sps and not execute other "plain" inserts/updates at all. Sep 5, 2013 at 11:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.