Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Schreiben einer in SQL geschriebenen Vererbungsabfrage mit einem inneren Join?

Wenn Sie sich eine Baumhierarchie ansehen, dann funktioniert das Nested-Set-Modell ziemlich gut, bringt aber eine größere Änderung in der Struktur Ihrer Vererbungstabelle mit sich.

Wenn Sie einen beliebigen gerichteten Graphen implementieren (z. B. wenn Sie ein „Autor“-Profil haben, das Artikel veröffentlichen, aber keine Kommentare moderieren kann, und ein „Moderator“-Profil, das Kommentare moderieren, aber keine Artikel veröffentlichen kann), möchten Sie vielleicht nachsehen für eine andere Lösung.

Eine Möglichkeit besteht darin, die Vererbung aufzugeben und die Berechtigungen für jede Gruppe manuell festzulegen.

Eine andere Möglichkeit besteht darin, die Vererbungstabelle zu verwenden, um sowohl direkte als auch indirekte Vererbung zu speichern (d. h. ein Knoten würde mit allen seinen Kindern über eine "direkte" Beziehung sowie mit allen seinen Nachkommen über eine "indirekte" Beziehung in Beziehung stehen). Diese Strategie erfordert, dass Sie alle indirekten Beziehungen in der Tabelle neu erstellen, wenn Sie eine der direkten Beziehungen ändern (dies kann mit einem einfachen INSERT SELECT erfolgen ), hat aber den Vorteil, dass nur ein einziger Join erforderlich ist, um auf alle Nachfolger zuzugreifen.

Die Grundidee ist:

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 = ?

Die Entfernungsschleife sollte so lange durchgeführt werden, bis keine Elemente der Entfernung D-1 mehr verfügbar sind, was mit einer Auswahlabfrage oder, falls vorhanden, Metainformationen darüber, wie viele Linien eingefügt wurden, erfolgen kann.