sql >> Base de Datos >  >> RDS >> Mysql

¿Escribir una consulta de herencia escrita en SQL usando una combinación interna?

Si está viendo una jerarquía de árbol, entonces el modelo de conjuntos anidados funciona bastante bien, pero implica un cambio importante en la estructura de su tabla de herencia.

Si está implementando un gráfico dirigido arbitrario (por ejemplo, tiene un perfil de "autor" que puede publicar artículos pero no moderar comentarios, y un perfil de "moderador" que puede moderar comentarios pero no publicar artículos), es posible que desee buscar para alguna otra solución.

Una posibilidad es renunciar a la herencia y configurar manualmente los permisos para cada grupo.

Otra posibilidad es usar la tabla de herencia para almacenar tanto la herencia directa como la indirecta (es decir, un nodo estaría relacionado con todos sus hijos usando una relación "directa", así como con todos sus descendientes usando una relación "indirecta"). Esta estrategia requiere que vuelva a crear todas las relaciones indirectas en la tabla siempre que cambie una de las relaciones directas (esto se puede hacer usando un simple INSERT SELECT ), pero tiene la ventaja de que solo requiere una única combinación para acceder a todos los descendientes.

La idea básica es:

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

El ciclo de distancia se debe realizar hasta que no haya más elementos de distancia D-1 disponibles, lo que se puede realizar mediante una consulta de selección o, si la tiene, metainformación sobre cuántas líneas se insertaron.