Articles

Microsoft SQL Server Gráfico – Un intento que se quedó corto (por ahora)

Posted by admin
TRAN Ngoc Thach
TRAN Ngoc Thach

Seguir

Jun 29, 2020 · 9 min read

Descargo de responsabilidad: La opinión en este artículo es solo mía, basado en mi exposición limitada a SQL del Servidor Gráfico. No soy de ninguna manera un experto en SQL Server. Podría estar sesgado hacia el Neo4j.

Con el creciente uso de Graph Database y el dominio de Neo4j en este nicho de mercado, así como su significativa ganancia de rendimiento en la consulta de datos altamente conectados, es comprensible que Microsoft no quiera quedarse fuera de esta mega tendencia.

A partir de SQL Server 2017, SQL Server ofreció funcionalidades de gráficos, con la introducción de la palabra claveMATCH. En la versión de 2019, entre otras, se agregaron dos nuevas características notables: Restricciones de borde y el uso de tablas derivadas en consultas MATCH. Bucear en esta tecnología el tiempo suficiente, tengo la impresión de que, a partir de ahora:

  • El soporte de gráficos en SQL Server aún está lejos de ser una base de datos de gráficos completa, por ejemplo, Neo4j.
  • La adición de funcionalidad se incrementa lentamente.
  • La función de gráfico se ajusta a regañadientes a la mentalidad de Base de datos relacional.

Vamos a entrar en detalles!

Pros & Cons

La palabra claveMATCH es, en mi opinión, simplemente un Azúcar sintático. En lugar de:

SELECT *
FROM NodeTable1 nt1 JOIN EdgeTable et ON nt1.$node_id = et.$from_id JOIN NodeTable2 nt2 ON nt2.$node_id = et.$to_id

… los usuarios pueden acortar la consulta como:

SELECT *
FROM NodeTable1 nt1, EdgeTable et, NodeTable2 nt2
WHERE MATCH(nt1-(et)->nt2)

La consulta acortada es, sin duda, agradable a la vista. Sin embargo, en el mundo.NET, Entity Framework puede ser preferido para aplicaciones de software orientadas a datos; como resultado de lo cual no hay necesidad de comandos de texto sin formato SQL. Los desarrolladores simplemente permiten que el marco genere consultas óptimas para ellos mientras se centran en abstracciones de alto nivel. Según esta lógica, el efecto agradable de MATCH es repentinamente irrelevante. Peor aún, en este momento, ni siquiera hay una hoja de ruta para admitir estas capacidades de gráficos en Entity Framework (Core).

En comparación con Neo4j, mirando de nuevo las consultas anteriores, es inevitable que los usuarios doblen su mentalidad de gráfico en el mundo de la base de datos Relacional. Todavía tenemos que declarar de antemano qué tablas, en la cláusula FROM, para llevar a cabo la coincidencia (¿Debería ser más bien el gráfico considerado como un ‘todo transitable’ y uno no necesita preocuparse por la organización detallada de los datos?). Cuando es necesario conocer la dirección de la flecha en MATCH, los usuarios se dan cuenta de la asignación 1-1 entre la cláusula MATCH y la cláusula original JOIN, en el sentido de que hay que distinguir el Nodo de origen y el Nodo de Destino. En contraste, la sintaxis de cifrado de Neo4j permite ignorar esta distinción. Todos ellos no son necesariamente un cambio de juego, sino simplemente una cuestión de conveniencia y alegría de desarrollo. (Más tarde, en el 1er Caso de estudio, veremos que tenemos que hacer un UNION ALL debido a esto.)

Una clave para el alto rendimiento de la base de datos de gráficos nativos en el recorrido de datos conectados es la adyacencia sin índice. Desafortunadamente, no existe tal cosa con la función de gráficos en SQL Server:

No estamos manteniendo una lista de adyacencia en cada nodo, sino que estamos almacenando datos de borde en tablas. Debido a que es una base de datos relacional, almacenar datos en forma de tablas fue una opción más natural para nosotros

Otro problema molesto es la falta de herramientas de visualización adaptadas a Gráficos, tanto para esquemas como para datos. Como solución alternativa, los usuarios aún pueden crear un Diagrama de esquema en SSM, pero esas tablas de Nodos y Bordes terminan como tablas individuales y desconectadas, incluso en caso de que tengan restricciones de bordes. Entre otras cosas, la tecnología de gráficos también debería aportar atractivos visuales, facilitando a los usuarios la construcción de consultas correctas. La falta de tales herramientas es frustrante y perjudicial para la productividad de los desarrolladores.

Diagrama Gráfico de Tablas

Entonces, ¿qué hacemos para obtener la Gráfica del esquema? Supongo que abrimos cada Tabla de bordes para ver manualmente las restricciones, y luego razonamos en ellas, con la ayuda de un trozo de papel, para averiguar todo el esquema de gráfico.

Restricciones de borde del gráfico

Con respecto a la visualización de datos, probé Microsoft Power BI con el complemento Gráfico dirigido por fuerza. Sin embargo, esta herramienta no es gratuita y no admite las capacidades de gráficos de SQL Server listas para usar, lo que significa que ve las tablas de nodos y bordes como tablas de base de datos normales. Examinando de cerca las listas de columnas, hay nombres de columnas de aspecto extraño, por ejemplo, graph_id_...,from_obj_id.... Son columnas internas, generadas automáticamente al crear tablas de nodos / bordes, inaccesibles desde el exterior. Se genera un error, como se muestra a continuación, por la función Get Data de Power BI si se accede a esas columnas.

Power BI – «Obtener datos» de las tablas gráficas de SQL Server

Para solucionar este problema, se debe crear una vista de base de datos que contenga solo columnas relevantes/accesibles, p. ej. from_id y to_id en la tabla de bordes, node_id en la tabla de nodos. Luego, en Power BI, extraiga los datos a través de esa vista. Espero que no me equivoque, el gráfico Dirigido a la Fuerza de Power BI parece requerir una sola tabla que consta de columnas Source, Target, Weight, Source Type, Target Type, Link Type. Nuestro esquema de ejemplo es simplista; por lo tanto, crear esta tabla única es trivial. ¿Qué pasaría si el esquema contuviera Tablas de +20 Nodos y Tablas de +10 bordes, podríamos terminar con una sola tabla para visualizar todo el gráfico con Power BI?

# Actualizado el 04.07.2020: Pensándolo bien, esto es seguramente posible, aunque sigue siendo engorroso. Se debe comenzar en las Tablas de Bordes, en cada una de las cuales las tablas $from_id y $to_id se unen contra Tablas de Nodos relevantes para traducirse en propiedades compartidas de todos los Nodos, por ejemplo, Name o Id. Luego haga UNION ALL para que todos se combinen en la mesa única final requerida por Power BI.

Consultar nodos y bordes es una de las posibilidades de la tecnología de gráficos. Lo que puede hacer que una base de datos de gráficos destaque es el soporte incorporado pero extensible para algoritmos de gráficos, como PageRank y Detección de comunidad de Lovaina (también conocido como «Louvain Community Detection»). Modularidad de Lovaina). Lamentablemente, una vez más, no hay funcionalidades de análisis disponibles en el gráfico de SQL Server, como se dijo:

Algunas bases de datos de gráficos proporcionan funciones analíticas de gráficos dedicadas como «ruta más corta» o «rango de página».»SQL Graph no proporciona ninguna de estas funciones en esta versión. Una vez más, se pueden usar bucles T-SQL y tablas temporales para escribir una solución alternativa para estos escenarios.

En Neo4j, esos algoritmos están fácilmente disponibles en grado de producción, gracias a Graph Data Science Library. Además, es de código abierto. Por lo general, la documentación es útil, pero a veces no es suficiente. Con el código abierto, los desarrolladores pueden descargar y profundizar en cómo se implementa un algoritmo específico; o incluso recompilar la biblioteca, con información de registro adicional, para comprender mejor. Implementar PageRank en SQL es posible, pero un algoritmo más complejo como la modularidad de Lovaina puede ser un desafío. Sin embargo, muchos ingenieros de software prefieren preocuparse más por la lógica de negocios, en lugar de estar atascados con detalles técnicos de bajo nivel.

Por último, pero no menos importante, en mi opinión, la expresión de tabla común es un tipo de tablas derivadas. Desde SQL Server 2019, esta técnica se supone oficialmente que es viable con Graph:

Expresión de tabla común (CTE) con tablas de gráficos y cláusula de coincidencia

Pero si sigue la creación de la VISTA, puede hacerlo:

la creación de Vistas con el Gráfico y tablas del PARTIDO de la cláusula

creo que esto es un signo de contradicción. El segundo enfoque requiere una Vista creada permanentemente, ya que no es posible crear una Vista temporal en SQL Server. Normalmente, los usuarios superan esto con CTE, pero de nuevo CTE no funciona con Graph, como se muestra arriba.

Casos de estudio

Un escenario de muestra: Estudiantes y Profesores.

Neo4j del Cypher:

CREATE (S1:NStudents {name: "S1"}), (S2:NStudents {name: "S2"}), (T1:NTeachers {name: "T1"}), (S3:NStudents {name: "S3"}), (T2:NTeachers {name: "T2"}), (S4:NStudents {name: "S4"}), (S1)-->(S2), (S2)-->(T1), (T1)-->(T2), (T2)-->(S4), (S3)-->(T1)

Gráfico de SQL Server 2019:

CREATE TABLE NStudents ( NVARCHAR(MAX) NOT NULL, INT NOT NULL) AS NODE;CREATE TABLE NTeachers ( NVARCHAR(MAX) NOT NULL, FLOAT NOT NULL) AS NODE;CREATE TABLE Talks (CONSTRAINT EC_Talk CONNECTION (NStudents TO NStudents, NStudents TO NTeachers, NTeachers TO NStudents, NTeachers TO NTeachers) ON DELETE CASCADE) AS EDGE;INSERT INTO NStudents VALUES ('S1',1),('S2',2),('S3',3),('S4',4);
INSERT INTO NTeachers VALUES ('T1',123), ('T2',456);
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S1'),
(SELECT $node_id FROM NStudents WHERE = 'S2'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S2'),
(SELECT $node_id FROM NTeachers WHERE = 'T1'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NTeachers WHERE = 'T1'),
(SELECT $node_id FROM NTeachers WHERE = 'T2'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NTeachers WHERE = 'T2'),
(SELECT $node_id FROM NStudents WHERE = 'S4'));
INSERT INTO Talks VALUES (
(SELECT $node_id FROM NStudents WHERE = 'S3'),
(SELECT $node_id FROM NTeachers WHERE = 'T1'));

Caso 1: Todas las conexiones entrantes y salientes de nodos

Motivación: Contar estas conexiones para cada nodo es una forma de averiguar cuáles son las más importantes.

Neo4j’sCypher:

MATCH (n)--()
RETURN n.name, COUNT(r) AS allCons
ORDER BY allCons DESC

SQL Server 2019 Gráfico de la:

--Create a View first, for convenience purpose.
CREATE VIEW view_AllPeople
AS
SELECT $node_id AS ,
FROM NStudents
UNION ALL
SELECT $node_id AS ,
FROM NTeachers;--Query using the View.
WITH CTE()
AS
(
SELECT ap1.
FROM view_AllPeople ap1, Talks t, view_AllPeople ap2
WHERE MATCH(ap1-(t)->ap2)
UNION ALL
SELECT ap1.
FROM view_AllPeople ap1, Talks t, view_AllPeople ap2
WHERE MATCH(ap1<-(t)-ap2)
)
SELECT , COUNT(*) AS allConns
FROM CTE
GROUP BY
ORDER BY allConns DESC

Comentarios: La versión SQL no solo es más larga, sino también más incómoda, ya que siempre se debe tener en cuenta la dirección de las flechas en MATCH.

Caso 2: Caminos más largos superiores

Motivación: Las cadenas de dependencia largas tienden a ser frágiles. Por ejemplo, dependencia de bibliotecas.

Neo4j’sCypher:

// The WHERE is to filter out duplicate paths, e.g. A->B = B->A.
MATCH p=(n)--(m)
WHERE ID(n) < ID(m)
RETURN n.name, m.name, length(p) AS len, AS node_list
ORDER BY len DESC

SQL Server 2019 Gráfico de la:

WITH CTE(from_id, to_id, , )
AS
(
SELECT $from_id, $to_id, 1 AS , CONVERT(NVARCHAR(MAX), $to_id) AS
FROM Talks
UNION ALL
SELECT t.$from_id, t.$to_id, +1, CONVERT(NVARCHAR(MAX), CTE. + ',' + CONVERT(NVARCHAR(MAX), $to_id))
FROM Talks t JOIN CTE ON t.$to_id = CTE.
)
SELECT vap., ,
FROM CTE JOIN (SELECT MAX(c.) AS maxLevel FROM CTE c GROUP BY c.) myMax ON CTE. = myMax.maxLevel JOIN
view_AllPeople vap ON CTE. = vap.
ORDER BY DESC

Comentarios: En la versión de SQL Server, uno tiene que recurrir a la Técnica de Expresión de Tabla Común Recursiva. Adopta la mentalidad de base de datos relacional para resolver problemas de gráficos.

Conclusión

En el dominio de gráficos, el comando SQL de un servidor SQL, con función de gráficos utilizada o no, utilizada para abordar problemas de gráficos, es típicamente mucho más largo y complejo, en comparación con el cifrado de Neo4j. Esto lleva a la implicación de que el código llevará más tiempo desarrollarlo y será difícil de mantener y ampliar más tarde. Otro ingeniero o incluso el original, mirando el mismo fragmento de código un mes después, encontrará frustrante comprender todos sus aspectos. Un término bien conocido para describir esta situación es deuda técnica.

Combinando todos los puntos antes mencionados, desde el aspecto de código, el soporte de funciones, hasta el ecosistema de herramientas / bibliotecas, la funcionalidad de gráficos de SQL Server en la actualidad, aunque es alentadora, no cumple con las expectativas.

SQL Server es extremadamente maduro con respecto a la base de datos Relacional, pero claramente es un novato en la base de datos de gráficos. Probablemente se considere que este soporte gráfico está contenido en la mentalidad de base de datos Relacional.

Related Post

Leave A Comment