Mysql
 sql >> Database >  >> RDS >> Mysql

Scrivere una query di ereditarietà scritta in SQL utilizzando un inner join?

Se stai osservando una gerarchia ad albero, il modello di set nidificato funziona abbastanza bene, ma comporta un cambiamento importante nella struttura della tua tabella di ereditarietà.

Se stai implementando un grafico orientato arbitrariamente (ad esempio, hai un profilo "autore" che può pubblicare articoli ma non moderare commenti e un profilo "moderatore" che può moderare commenti ma non pubblicare articoli), potresti voler guardare per qualche altra soluzione.

Una possibilità è rinunciare all'ereditarietà e impostare manualmente le autorizzazioni per ogni gruppo.

Un'altra possibilità è utilizzare la tabella di ereditarietà per memorizzare l'ereditarietà sia diretta che indiretta (ovvero, un nodo sarebbe correlato a tutti i suoi figli utilizzando una relazione "diretta", così come tutti i suoi discendenti utilizzando una relazione "indiretta"). Questa strategia richiede di ricreare tutte le relazioni indirette nella tabella ogni volta che si modifica una delle relazioni dirette (questo può essere fatto utilizzando un semplice INSERT SELECT ), ma ha il vantaggio di richiedere un solo join per accedere a tutti i discendenti.

L'idea di base è:

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

Il ciclo sulla distanza dovrebbe essere eseguito fino a quando non ci sono più elementi della distanza D-1 disponibili, cosa che può essere eseguita utilizzando una query di selezione o, se ce l'hai, meta-informazioni su quante righe sono state inserite.