Ако разглеждате йерархията на дървото, тогава моделът на вложените множества работи доста добре, но включва значителна промяна в структурата на вашата таблица за наследяване.
Ако внедрявате произволно насочена графика (например имате профил на "автор", който може да публикува статии, но не и да модерира коментари, и профил на "модератор", който може да модерира коментари, но не и да публикува статии), може да искате да погледнете за някакво друго решение.
Една от възможностите е да се откажете от наследяването и ръчно да зададете разрешенията за всяка група.
Друга възможност е да се използва таблицата за наследяване за съхраняване както на пряко, така и на непряко наследяване (тоест възелът ще бъде свързан с всички свои деца, използващи "пряка" връзка, както и всички негови потомци, използващи "непряка" връзка). Тази стратегия изисква от вас да създавате отново всички непреки връзки в таблицата, когато промените една от директните връзки (това може да стане с помощта на прост INSERT SELECT
), но има предимството, че изисква само едно присъединяване за достъп до всички потомци.
Основната идея е:
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 = ?
Цикълът за разстояние трябва да се извършва, докато няма повече налични елементи от разстояние D-1, което може да се направи с помощта на заявка за избор или, ако имате такава, мета-информация за това колко реда са били вмъкнати.