Suporte a grafos no SQL Server 2017

Fala pessoal, há algumas semanas atrás tive o prazer de presenciar o pré-lançamento do SQL Server 2017, sim é isso mesmo SQL Server 2017 está chegando, ainda não conferiu as novidades? Baixe a versão CTP (Community Technical Preview) e divirta-se.

https://www.microsoft.com/en-us/sql-server/sql-server-2017

Diversas novidades nessa nova versão do SQL Server, sendo uma das principais o suporte a algumas distribuições Linux (Red hat, Ubuntu e Suse).

Uma das novidades que achei muito interessante foi a extensão para suportar grafos dentro do SQL Server. O suporte a grafos no SQL Server vai de encontro com as tendências do mercado e com tudo que a Microsoft vem incluindo dentro da plataforma para deixa-la cada vez mais completa e robusta.

A utilização de grafos dentro do SQL Server foge um pouco da forma convencional como pensamos hoje no momento de modelarmos nosso banco de dados, quando falamos em grafos não pensamos mais em chaves estrangeiras como da maneira convencional,  em grafos temos relacionamentos de forma mais natural e com diferentes propriedades do nosso mundo relacional.

A utilização de grafos não é novidade no mundo de banco de dados, temos diversos bancos de dados que são orientados a grafos atualmente, alguns exemplos são:

  • Neo4J
  • ArangoDb
  • Oracle Spatial
  • InfoGrid

Como podemos ver não é uma coisa nova no mercado, mas sim a Microsoft atendendo as tendências e deixando o SQL Server a plataforma mais completa do mercado.

graphsimg

Imagem retirada de: https://blogs.technet.microsoft.com/dataplatforminsider/2017/04/20/graph-data-processing-with-sql-server-2017/

Na imagem acima podemos ver a arquitetura para o suporte a grafos dentro do SQL Server, onde o “Node” representa uma entidade (ou também conhecido como vértices) e o “Edge table” representa o relacionamento (ou também conhecido como arestas).

Para simplificar o funcionamento abaixo uma demonstração simples:

USE MASTER
GO
DROP DATABASE IF EXISTS GRAPHSDB
GO
CREATE DATABASE GRAPHSDB
GO

USE GRAPHSDB
GO
–CRIA NOSSA ENTIDADE CHAMADA PESSOA
CREATE TABLE [dbo].[Pessoas](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Nome] [varchar](200) NULL) AS NODE
GO

–CRIA NOSSO RELACIONAMENTO CHAMADO CURTIU
CREATE TABLE dbo.Curtiu AS EDGE;

go

–INSERINDO DADOS NA ENTIDADE PESSOA
INSERT INTO [Pessoas] VALUES(‘Reginaldo’)
INSERT INTO [Pessoas] VALUES(‘Bruno’)
INSERT INTO [Pessoas] VALUES(‘Felipe’)
INSERT INTO [Pessoas] VALUES(‘Antonieta’)
INSERT INTO [Pessoas] VALUES(‘Caio’)
INSERT INTO [Pessoas] VALUES(‘Paulo’)
INSERT INTO [Pessoas] VALUES(‘Sara’)
INSERT INTO [Pessoas] VALUES(‘Rafael’)
INSERT INTO [Pessoas] VALUES(‘Ricardo’)
INSERT INTO [Pessoas] VALUES(‘Ferdinanda’)
INSERT INTO [Pessoas] VALUES(‘Pedro’)
INSERT INTO [Pessoas] VALUES(‘Joaquim’)
INSERT INTO [Pessoas] VALUES(‘Samuela’)
INSERT INTO [Pessoas] VALUES(‘Pedrina’)

go

–INSERINDO RELACIONAMENTOS
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Reginaldo’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Bruno’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Reginaldo’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Felipe’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Paulo’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Bruno’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Paulo’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Pedrina’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Bruno’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Antonieta’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Bruno’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Pedro’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Caio’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Joaquim’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Caio’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Bruno’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Joaquim’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Reginaldo’));
INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Joaquim’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Felipe’));
go

–PESSOAS QUE O ‘REGINALDO’ CURTIU
SELECT p.Nome Pessoa1, p2.Nome CurtidoPessoa1
FROM Pessoas P, Curtiu, Pessoas p2
WHERE MATCH(P-(Curtiu)->p2)
AND p.NOME = ‘Reginaldo’;

–PESSOAS QUE CURTIRAM AS MESMAS PESSOAS QUE O ‘REGINALDO’
SELECT Person1.nome AS Pessoa1,Person3.nome CurtidoPessoa1, Person2.nome AS CurtidoPessoa2
FROM Pessoas Person1, Curtiu Curtiu1, Pessoas Person2,
Curtiu Curtiu2, Pessoas Person3
WHERE MATCH(Person1-(Curtiu1)->Person3<-(Curtiu2)-Person2)
AND Person1.NOME = ‘Reginaldo’ and Person1.nome <> Person2.nome

–PESSOAS QUE CURTIRAM O ‘REGINALDO’ E QUE FORAM CURTIDAS POR ALGUEM
SELECT Person1.nome AS Pessoa1,Person3.nome CurtidoPessoa1, Person2.nome AS CurtidoPessoa2
FROM Pessoas Person1, Curtiu Curtiu1, Pessoas Person2,
Curtiu Curtiu2, Pessoas Person3
WHERE MATCH(Person1<-(Curtiu1)-Person3<-(Curtiu2)-Person2)
AND Person1.NOME = ‘Reginaldo’ and Person1.nome <> Person2.nome

O script acima funciona da seguinte forma:

 

Tabela ‘Pessoas’ é a nossa entidade(Node) e a tabela ‘Curtiu’ é o nosso relacionamento(Edge table), perceba que a forma de criar as tabelas é diferente do convencional, temos novas palavras reservadas.

Após a inserção das entidades ‘Pessoas’, temos uma forma diferente de inserir nossos relacionamentos na tabela ‘Curtiu’, repare que nossa tabela ‘Curtiu’ não possuí campos nesse caso, mas poderia ter.

Screen Shot 05-31-17 at 07.57 PM

Esse é o formato de informações que vamos encontrar dentro da nossa tabela de relacionamento ‘Curtiu’ (Edge table).

Podemos pensar que a inserção nessa tabela de relacionamento seja um evento de ‘curtida’ de uma rede social, como por exemplo o facebook, então cada registro inserido na tabela ‘Curtiu’ agora representa uma curtida para nossa demonstração, por exemplo:

INSERT INTO dbo.Curtiu VALUES ((SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Reginaldo’),
(SELECT $node_id FROM dbo.Pessoas WHERE Nome = ‘Bruno’));

O Insert acima representa que a entidade ‘Reginaldo’ deu uma ação de ‘curtida’ na entidade ‘Bruno’, que no mundo real seria equivalente ao usuário ‘Reginaldo’ deu um Like no perfil do ‘Bruno’.

Com base nesses relacionamentos acima podemos começar a brincar com T-SQL utilizando um novo operador chamado MATCH.

–PESSOAS QUE O ‘REGINALDO’ CURTIU
SELECT p.Nome Pessoa1, p2.Nome CurtidoPessoa1
FROM Pessoas P, Curtiu, Pessoas p2
WHERE MATCH(P-(Curtiu)->p2)
AND p.NOME = ‘Reginaldo’;

Screen Shot 05-31-17 at 07.30 PM

A consulta acima retorna as pessoas que o ‘Reginaldo’ curtiu, perceba a forma que utilizamos o operador MATCH(Entidade-(relacionamento)->entidade).

 

–PESSOAS QUE CURTIRAM AS MESMAS PESSOAS QUE O ‘REGINALDO’
SELECT Person1.nome AS Pessoa1,Person3.nome CurtidoPessoa1, Person2.nome AS CurtidoPessoa2
FROM Pessoas Person1, Curtiu Curtiu1, Pessoas Person2,
Curtiu Curtiu2, Pessoas Person3
WHERE MATCH(Person1-(Curtiu1)->Person3<-(Curtiu2)-Person2)
AND Person1.NOME = ‘Reginaldo’ and Person1.nome <> Person2.nome

Screen Shot 05-31-17 at 07.32 PM

Consulta um pouco mais complexa, estou buscando pessoas que curtiram as mesmas pessoas que o ‘Reginaldo’ também curtiu, repare novamente no operador MATCH(Entidade-(relacionamento)->Entidade<-(relacionamento)-Entidade).

 

–PESSOAS QUE CURTIRAM O ‘REGINALDO’ E QUE FORAM CURTIDAS POR ALGUEM
SELECT Person1.nome AS Pessoa1,Person3.nome CurtidoPessoa1, Person2.nome AS CurtidoPessoa2
FROM Pessoas Person1, Curtiu Curtiu1, Pessoas Person2,
Curtiu Curtiu2, Pessoas Person3
WHERE MATCH(Person1<-(Curtiu1)-Person3<-(Curtiu2)-Person2)
AND Person1.NOME = ‘Reginaldo’ and Person1.nome <> Person2.nome

Screen Shot 05-31-17 at 07.36 PM

Consultando pessoas que curtiram pessoas que curtiram o ‘Reginaldo’, complexo? Bom, daqui pra a sua imaginação é o limite.

 

É isso ai galera, SQL Server cada vez mais robusto e completo, espero que tenha gostado, mas se gostou ou não deixe o seu feedback, até a próxima.

 

Referencias

Graph Data Processing with SQL Server 2017

https://blogs.technet.microsoft.com/dataplatforminsider/2017/04/20/graph-data-processing-with-sql-server-2017/

GraphDB Series: o que é um banco de dados de grafos

https://imasters.com.br/banco-de-dados/graphdb-series-o-que-e-um-banco-de-dados-de-grafos/?trace=1519021197&source=single

MATCH (Transact-SQL)

https://docs.microsoft.com/en-us/sql/t-sql/statements/match-sql-graph

 

Script publicado no Github:

https://github.com/Jamal27/SQLServer_Scripts/blob/master/GraphsOnSQLServer

Reginaldo Silva

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s