Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving in Closure Table with Multiple Parents

I have the following DAG

A --> B

|     |
v     v

C --> D

Here is the closure table

| Ancestor | Descendant | Depth |
---------------------------------
| A        | A          | 0     |
| A        | B          | 1     |
| A        | C          | 1     |
| A        | D          | 2     |
| A        | D          | 2     |
| B        | B          | 0     |
| B        | D          | 1     |
| C        | C          | 0     |
| C        | D          | 1     |
| D        | D          | 0     |

How would I go about removing path B > D (thus removing A > B > D) without also removing A > C > D and C > D.

Right now I'm using the following query but it only works when every node only has 1 parent.

DELETE FROM `Closure`
WHERE `Descendant` IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`=@Node)
AND `Ancestor` NOT IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`=@Node);
like image 753
NtscCobalt Avatar asked Mar 09 '12 22:03

NtscCobalt


1 Answers

Given your current model I'm not sure it's possible. I'd propose that you add a column to count the number of paths tracking how many different ways there are to get from any node X to node Y.

So rather than your table you end up with

| Ancestor | Descendant | Depth | Refs  |
-----------------------------------------
| A        | A          | 0     | 1     |
| A        | B          | 1     | 1     |
| A        | C          | 1     | 1     |
| A        | D          | 2     | 2     |
| B        | B          | 0     | 1     |
| B        | D          | 1     | 1     |
| C        | C          | 0     | 1     |
| C        | D          | 1     | 1     |
| D        | D          | 0     | 1     |

Removing a node would then entail an update statement followed by a delete statement. The update would, instead of deleting the entries it finds, decrement the number of references for that entry. Then you could delete the entries with 0 or fewer references afterwards.

Coming up with a SQL query which does the update is escaping me at the moment but in theory this should work without having to completely reconstruct the closure table...

like image 184
Don Avatar answered Oct 11 '22 12:10

Don