Om du tittar på en trädhierarki, fungerar den kapslade uppsättningsmodellen ganska bra, men innebär en stor förändring i strukturen för din arvstabell.
Om du implementerar ett godtyckligt riktat diagram (du har till exempel en "författarprofil" som kan publicera artiklar men inte moderera kommentarer, och en "moderator"-profil som kan moderera kommentarer men inte publicera artiklar), kanske du vill titta för någon annan lösning.
En möjlighet är att avstå från arv och manuellt ställa in behörigheterna för varje grupp.
En annan möjlighet är att använda arvstabellen för att lagra både direkt och indirekt arv (det vill säga, en nod skulle vara relaterad till alla dess barn som använder en "direkt" relation, såväl som alla dess avkomlingar som använder en "indirekt" relation). Denna strategi kräver att du återskapar alla indirekta relationer i tabellen när du ändrar en av de direkta relationerna (detta kan göras genom att använda en enkel INSERT SELECT
), men har fördelen att bara kräva en enda koppling för att få åtkomst till alla avkomlingar.
Grundidén är:
CREATE TABLE group_inherit (
parent INT NOT NULL,
child INT NOT NULL,
distance INT NOT NULL,
PRIMARY KEY (parent,child)
);
/* Clean up indirect relations */
DELETE FROM group_inherit WHERE distance <> 0;
/* Repeat this for each D > 0 until the maximum distance is reached */
INSERT IGNORE INTO (parent, child, distance)
SELECT fst.parent, snd.child, D
FROM group_inherit fst
INNER JOIN group_inherit snd ON snd.parent = fst.child
WHERE fst.distance = 0 AND snd.distance = D - 1;
/* Select all permissions for a user type */
SELECT perm.*
FROM group_permissions perm
INNER JOIN group_inherit ON perm.moderator = child
WHERE parent = ?
Slingan om avstånd bör göras tills det inte finns fler element av avstånd D-1 tillgängliga, vilket kan göras med hjälp av en urvalsfråga eller, om du har det, metainformation om hur många rader som infogats.