Articles

Microsoft SQL Server Gráfico – Uma tentativa que caiu curto (por agora)

Posted by admin
TRAN Ngoc Thach
TRAN Ngoc Thach

Siga

Jun 29, 2020 · 9 min de leitura

Disclaimer: O parecer neste artigo é só meu, com base na minha exposição limitada do SQL Server Gráfico. Não sou de forma alguma um especialista em SQL Server. Eu poderia ser tendencioso para Neo4j.

com o crescente uso do Graph Database e o domínio do Neo4j neste nicho de mercado, bem como seu significativo ganho de desempenho na consulta de dados altamente conectados, é compreensível que a Microsoft não queira ficar de fora dessa mega-tendência.

a partir do SQL Server 2017, o SQL Server oferecia funcionalidades gráficas, com a introdução da palavra-chave MATCH. Na versão de 2019, entre outros, dois novos recursos notáveis foram adicionados: restrições de borda e o uso de tabelas derivadas em consultas MATCH. Mergulhando nessa tecnologia por tempo suficiente, tenho a impressão de que, a partir de agora:

  • o suporte gráfico no SQL Server ainda está longe de ser um banco de dados gráfico completo, por exemplo, Neo4j.
  • a adição de funcionalidade é lentamente incremental.
  • o recurso gráfico é relutantemente encaixado na mentalidade do banco de dados relacional.

vamos entrar em detalhes!

prós& contras

a palavra-chave MATCH é, na minha opinião, apenas um açúcar sintático. Em vez 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

… os usuários podem praticamente encurtar a consulta como:

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

a consulta abreviada é, sem dúvida, agradável aos olhos. No entanto, no. net world, Entity Framework pode ser preferido para aplicativos de software orientados a dados; como resultado, não há necessidade de comandos de texto simples SQL. Os desenvolvedores apenas permitem que a estrutura gere consultas ideais para eles enquanto estão focados em abstrações de alto nível. Por essa lógica, o efeito agradável de MATCH é repentinamente irrelevante. Pior, no momento, não há nem mesmo um roteiro no suporte a esses recursos de gráfico no Entity Framework (Core).

comparando com Neo4j, olhando novamente para as consultas acima, é inevitável que os usuários dobrem sua mentalidade gráfica no mundo do banco de dados relacional. Ainda temos que declarar antecipadamente quais tabelas, na cláusula FROM, para realizar a correspondência (deve ser o gráfico considerado como uma “coisa toda atravessável” e não se precisa se preocupar com a organização detalhada dos dados?). Ao saber que a direção da seta em MATCH é obrigatória, os usuários percebem o mapeamento 1-1 entre a cláusula MATCH e a cláusula JOIN original, no sentido de que é preciso distinguir o nó de origem e o nó de destino. Em contraste, a sintaxe Cypher de Neo4j permite ignorar essa distinção. Todos eles não são necessariamente um divisor de águas; mas simplesmente uma questão de conveniência e alegria de desenvolvimento. (Mais tarde, no primeiro caso de estudo, veremos que temos que fazer um UNION ALL por causa disso.)

uma chave para o alto desempenho do banco de dados Gráfico nativo na travessia de dados conectados é a adjacência sem índice. Infelizmente, não existe tal coisa com o recurso Graph no SQL Server:

não estamos mantendo uma lista de adjacências em todos os nós; em vez disso, estamos armazenando dados de borda em tabelas. Por ser um banco de dados relacional, armazenar dados na forma de tabelas foi uma escolha mais natural para nós

outro problema irritante é a falta de ferramentas de visualização adaptadas ao gráfico, tanto para esquema quanto para dados. Como solução alternativa, os usuários ainda podem criar um diagrama de esquema no SSMS, mas essas tabelas de nós e bordas acabam como tabelas individuais e desconectadas, mesmo no caso de terem restrições de borda. Entre outras coisas, a tecnologia Graph também deve trazer recursos visuais, facilitando aos usuários a construção de consultas corretas. A falta dessas ferramentas é frustrante e prejudicial para a produtividade dos desenvolvedores.

Diagrama de Gráfico de Tabelas

Então, o que fazer para obter o Gráfico de esquema? Acho que abrimos cada tabela de Borda para ver manualmente as restrições e, em seguida, raciocinamos sobre elas, com a ajuda de um pedaço de papel, para descobrir todo o esquema do Gráfico.

restrições de borda do Gráfico

em relação à visualização de dados, tentei o Microsoft Power BI com Addon gráfico direcionado à força. No entanto, esta ferramenta não é gratuita e não suporta os recursos de gráfico do SQL Server prontos para uso, o que significa que vê os nós e as tabelas de bordas como tabelas de banco de dados normais. Examinando de perto as listas de colunas, existem nomes de colunas de aparência estranha, por exemplo, graph_id_...,from_obj_id.... Essas são colunas internas, geradas automaticamente ao criar tabelas de nó / borda, inacessíveis de fora. Um erro é gerado, como abaixo, pela função Get Data do Power BI se acessar essas colunas.

Alimentação BI — “Obter Dados” a partir do SQL Server Gráfico tabelas

Para contornar este problema, deve-se criar um Banco de dados contém apenas relevantes/acessível colunas, e.g. from_id e to_id na tabela Edge, node_id na tabela Node. Em seguida, no Power BI, extraia os dados por meio dessa visualização. Espero não estar enganado, o gráfico direcionado à força do Power BI parece exigir uma única tabela que consiste em colunas Source, Target, Weight, Source Type, Target Type, Link Type. Nosso esquema de amostra é simplista; assim, criar esta única tabela é trivial. E se o esquema contivesse tabelas de +20 nós e tabela de +10 arestas, poderíamos acabar com uma única tabela para visualizar todo o gráfico com o Power BI?

#atualizado em 04.07.2020: Pensando Bem, isso certamente é possível, embora ainda seja complicado. Deve-se começar em tabelas de arestas, em cada uma das quais as tabelas $from_id e $to_id são unidas contra nós relevantes, a fim de traduzir em propriedades compartilhadas de todos os nós, por exemplo, Name ou Id. Em seguida, faça UNION ALL para que todos se combinem na tabela única Final exigida pelo Power BI.

consultar nós e arestas é uma das possibilidades da tecnologia Graph. O que pode fazer um banco de dados Gráfico se destacar é o suporte integrado, mas extensível, para algoritmos de gráfico, como PageRank e Louvain Community Detection (aka. Modularidade do Louvain). Infelizmente, novamente, nenhuma dessas funcionalidades de Análise disponível no gráfico do SQL Server, como dito:

alguns bancos de dados de gráficos fornecem funções analíticas de gráficos dedicadas, como” caminho mais curto “ou” Page rank.”O SQL Graph não fornece essas funções nesta versão. Novamente, loops T-SQL e tabelas temporárias podem ser usados para escrever uma solução alternativa para esses cenários.

em Neo4j, esses algoritmos estão prontamente disponíveis na categoria de produção, graças à Graph Data Science Library. Além disso, é de código aberto. Geralmente, a documentação é útil, mas às vezes não é suficiente. Com o código aberto, os desenvolvedores podem baixar e mergulhar em como um algoritmo específico é implementado; ou mesmo recompilar a biblioteca, com informações adicionais de registro, para entender melhor. Implementar o PageRank no SQL é possível, mas um algoritmo mais complexo, como a modularidade de Louvain, pode ser um desafio. No entanto, muitos engenheiros de software preferem se incomodar mais com a lógica de negócios, em vez de ficarem atolados com detalhes técnicos de baixo nível.

por último, mas não menos importante, na minha opinião, a expressão de tabela comum é um tipo de tabelas derivadas. Desde o SQL Server 2019, esta técnica é oficialmente suposto para ser viável com o Gráfico:

Expressão de Tabela Comuns (CTE) com o Gráfico e tabelas de CORRESPONDÊNCIA de cláusula

Mas se, após a criação da EXIBIÇÃO, ele é capaz de fazer:

criação de Vista de Gráfico e tabelas de CORRESPONDÊNCIA de cláusula

eu acho que isso é um sinal de inconsistência. A segunda abordagem requer uma visualização criada permanentemente, pois não é possível criar uma visualização temporária no SQL Server. Normalmente, os usuários superam isso com CTE, mas novamente o CTE não funciona com Graph, como mostrado acima.

casos de estudo

um cenário de amostra: alunos e professores.

Neo4j do 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)

SQL Server 2019 Gráfico da:

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 as conexões de entrada e saída de nós

Motivação: Contagem estas ligações, para cada nó é uma maneira de descobrir quais são as mais importantes.

Neo4j’sCypher:

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

o SQL Server 2019 Gráfico da:

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

Comentários: A versão SQL não é apenas mais longa, mas também mais inconveniente, pois a direção das setas em MATCH deve ser sempre levada em consideração.

caso 2: caminhos mais longos superiores

motivação: cadeias de dependência longas tendem a ser frágeis. Por exemplo, dependência de biblioteca.

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

o SQL Server 2019 Gráfico da:

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

Comentários: Na versão do SQL Server, é preciso recorrer à técnica de expressão de tabela comum recursiva. Ele praticamente abraça a mentalidade do banco de dados relacional para resolver problemas de gráfico.

conclusão

no Graph domain, o comando SQL de um SQL Server, com recurso de gráfico utilizado ou não, usado para resolver problemas de gráfico, é normalmente muito mais demorado e complexo, em comparação com o Cypher de Neo4j. Isso leva a uma implicação de que o código será mais demorado para se desenvolver e difícil de manter e estender posteriormente. Outro engenheiro ou mesmo o original, olhando para o mesmo trecho de código um mês depois, achará frustrante entender todos os seus aspectos. Um termo bem conhecido para descrever essa situação é a dívida técnica.

combinando todos os pontos acima mencionados, do aspecto do Código ao suporte a recursos, ao ecossistema de ferramentas/bibliotecas, a funcionalidade gráfica do SQL Server no momento, embora seja encorajadora, fica aquém das expectativas.

o SQL Server é extremamente maduro em relação ao banco de dados relacional, mas claramente um novato no banco de dados Graph. Este suporte gráfico é provavelmente considerado contido na mentalidade de banco de dados relacional.

Related Post

Leave A Comment