ツリー階層を見ると、入れ子集合モデルはかなりうまく機能しますが、継承テーブルの構造に大きな変更が加えられます。
任意の有向グラフを実装している場合(たとえば、記事を公開できるがコメントをモデレートできない「作成者」プロファイルと、コメントをモデレートできるが記事を公開できない「モデレーター」プロファイルがある場合)、他の解決策について。
1つの可能性は、継承をあきらめて、すべてのグループのアクセス許可を手動で設定することです。
もう1つの可能性は、継承テーブルを使用して直接継承と間接継承の両方を格納することです(つまり、ノードは「直接」関係を使用してすべての子に関連付けられ、「間接」関係を使用してすべての子孫に関連付けられます)。この戦略では、直接関係の1つを変更するたびに、テーブル内のすべての間接関係を再作成する必要があります(これは、単純なINSERT SELECT
を使用して実行できます。 )が、すべての子孫にアクセスするために1つの結合のみを必要とするという利点があります。
基本的な考え方は次のとおりです。
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の要素がなくなるまで実行する必要があります。これは、選択クエリ、または挿入された行数に関するメタ情報を使用して実行できます。