In what order are ON DELETE CASCADE constraints processed?

后端 未结 4 921
失恋的感觉
失恋的感觉 2021-01-02 05:20

Here is an example of what I\'ve got going on:

CREATE TABLE Parent (id BIGINT NOT NULL,
  PRIMARY KEY (id)) ENGINE=InnoDB;

CREATE TABLE Child (id BIGINT NOT         


        
相关标签:
4条回答
  • 2021-01-02 06:07

    @Matt Solnit first of all this is really a good question and as far as I know when a record from Parent is to be deleted then innodb first tries to identify which other tables holds references to it so that it can delete the record from them as well. In your case it is Child table and Uncle table, now it seems that in this case it decides to first delete record from Child table and thus it repeats the same process for Child and eventually fails as Uncle holds reference to Child table but neither "ON DELETE CASCADE" nor "ON DELETE SET NULL" is specified for fk_child FK in Uncle table. However, it does seems that if innodb first tries to delete record from the Uncle table then deletion should have happened smoothly. Well after giving a second thought I think that since innodb follows ACID model thus it chooses Child over Uncle to start the deletion process becuase if it starts with Uncle even then the deletion in Child might still have failed e.g. assume a Friend table that has fk_child key (similar to Uncle) without ON DELETE CASCADE, now this would still have caused the whole transaction to fail and therefore this looks right behaviour to me. In others words innodb starts with table that may cause a possible failure in the transaction but that is my theory in reality it might be a completely different story. :)

    0 讨论(0)
  • 2021-01-02 06:10

    The parent deletion is triggering the child deletion as you stated and I don't know why it goes to the child table before the uncle table. I imagine you would have to look at the dbms code to know for sure, but im sure there is an algorithm that picks which tables to cascade to first.

    The system does not really 'figure out' stuff the way you imply here and it is just following its constraint rules. The problem is the schema you created in that it encounters a constraint that will not let it pass further.

    I see what you are saying.. if it hit the uncle table first it would delete the record and then delete the child (and not hit the uncle cascade from the child deletion). But even so, I don't think a schema would be set up to rely on that kind of behavior in reality. I think the only way to know for sure what is going on is to look through the code or get one of the mysql/postgresql programmers in here to say how it processes fk constraints.

    0 讨论(0)
  • 2021-01-02 06:16

    In the simpler case, what happens if a record is deleted from Child and it has a referencing Uncle? That's unspecified, so the constraints fail for that anyway.

    If deleting a Child does not delete its Uncles, then what happens instead? Uncle.childid cannot be null.

    What you want is one of these three things:

    1. Uncle.childid can be null, and you want ON DELETE SET NULL for childid.
    2. Uncle.childid cannot be null, and you want ON DELETE CASCADE for childid.
    3. Childid does not belong on Uncle, and you want a ChildsUncle relation with ON DELETE CASCADE foreign key constraints to both Child and Uncle. Uncleid would be a candidate key for that relation (i.e. it should be unique).
    0 讨论(0)
  • 2021-01-02 06:22

    the design is all wrong. You should have single table, with parent child relationship (literrally). Then you can figure out uncles (and aunts) with a query

    select id from persons where -find all children of the grandparents
    parent id in (
    select parentid from persons --find the grandparents
    where id in (
    select parentid from persons --find the parents
    where id=THECHILD) )
    minus --and take out the child's parents
    select parentid from persons
    where id=THECHILD

    0 讨论(0)
提交回复
热议问题