Graph Tables en SQL Server

Usando Graph Tables en SQL Server

Una base de datos gráfica es una colección de nodos (o vértices) y bordes (o relaciones). Un nodo representa una entidad (por ejemplo, una persona o una organización) y un borde representa una relación entre los dos nodos que conecta (por ejemplo, grupos o amigos). Tanto los nodos como los bordes pueden tener propiedades asociadas a ellos.

Características de los Graph Tables

  • Los bordes o las relaciones son entidades de primera clase en una base de datos gráfica y pueden tener atributos o propiedades asociadas.
  • Un solo borde puede conectar de forma flexible varios nodos en una base de datos de gráficos.
  • Puede expresar la coincidencia de patrones y las consultas de navegación de múltiples saltos fácilmente.
  • Puede expresar cierre transitivo y consultas polimórficas fácilmente.

La imagen muestra la arquitectura básica de las Graph Tables.

Cuando usar una base de datos gráfica

No hay nada que una base de datos gráfica pueda lograr, lo que no se puede lograr utilizando una base de datos relacional. Sin embargo, una base de datos gráfica puede hacer que sea más fácil expresar cierto tipo de consultas. Además, con optimizaciones específicas, ciertas consultas pueden tener un mejor desempeño.

Factores para decidir usar una base de datos gráfica

  • Su aplicación tiene datos jerárquicos. El tipo de datos HierarchyID se puede usar para implementar jerarquías, pero tiene algunas limitaciones. Por ejemplo, no le permite almacenar varios padres para un nodo.
  • Su aplicación tiene relaciones complejas de muchos a muchos; A medida que la aplicación evoluciona, se agregan nuevas relaciones.
  • Necesitas analizar datos y relaciones interconectadas.

Tabla Node

Una tabla Node representa una entidad en un esquema gráfico. Cada vez que se crea una tabla Node, junto con las columnas definidas por el usuario, se crea una columna implícita llamada $node_id, que identifica de forma exclusiva un nodo dado en la base de datos.

Los valores en $node_id se generan automáticamente y son una combinación de object_id de esa tabla de nodos y un valor bigint generado internamente. Sin embargo, cuando se selecciona la columna $node_id, se muestra un valor calculado en forma de una cadena JSON. Además, $node_id es una pseudo columna, que se asigna a un nombre interno con una cadena hexadecimal.

Cuando selecciona $node_id de la tabla, el nombre de la columna aparecerá como $node_id_ <Cadena_Hexadecimal>. El uso de nombres de pseudocolumnas en las consultas es la forma recomendada de consultar la columna interna $node_id y se debe evitar el uso del nombre interno con una cadena hexadecimal.

Se recomienda que los usuarios creen una restricción o índice único en la columna $node_id en el momento de la creación de la tabla Node, pero si no se crea una, se crea automáticamente un índice único no agrupado predeterminado. Sin embargo, cualquier índice en una pseudo columna de gráfico se crea en las columnas internas subyacentes. Es decir, un índice creado en la columna $node_id, aparecerá en la columna interna graph_id_<Cadena_Hexadecimal> .

Tabla Edge

Una tabla Edge representa una relación en un gráfico. Los Edge siempre se dirigen y conectan dos nodos. Una tabla Edge permite a los usuarios modelar relaciones de muchos a muchos en el gráfico. Una tabla Edge puede tener o no atributos definidos por el usuario. Cada vez que se crea una tabla Erge, junto con los atributos definidos por el usuario, se crean tres columnas implícitas en la tabla Edge

En la tabla siguiente se muestra las columnas del Edge

ColumnaDescripción
$edge_idIdentifica de forma exclusiva un Edge dado en la base de datos. Es una columna generada y el valor es una combinación de object_id de la tabla de borde y un valor bigint generado internamente. Sin embargo, cuando se selecciona la columna $edge_id, se muestra un valor calculado en forma de una cadena JSON. $edge_id es una pseudo-columna, que se asigna a un nombre interno con una cadena hexadecimal.
Cuando selecciona $edge_id de la tabla, el nombre de la columna aparecerá como $edge_id_ \ <cadena_Hexadecimal>. El uso de nombres de pseudocolumnas en las consultas es la forma recomendada de consultar la columna interna $edge_id y se debe evitar el uso del nombre interno con una cadena hexadecimal.
$from_idAlmacena el $ node_id del Node, desde donde se origina el borde.
$to_idAlmacena el $ node_id del Node, en el que termina el borde.
Columnas en la tabla Edge

Los nodos que puede conectar un borde determinado se rigen por los datos insertados en las columnas $ from_id y $ to_id. En la primera versión, no es posible definir restricciones en la tabla de borde, para restringir la conexión de dos tipos de nodos. Es decir, un borde puede conectar dos nodos en el gráfico, independientemente de sus tipos.

Similar a la columna $node_id, se recomienda que los usuarios creen un índice o restricción únicos en la columna $edge_id en el momento de la creación de la tabla de borde, pero si no se crea uno, se crea automáticamente un índice único no agrupado predeterminado en esta columna Sin embargo, cualquier índice en una pseudo columna de gráfico se crea en las columnas internas subyacentes. Es decir, un índice creado en la columna $ edge_id, aparecerá en la columna interna graph_id_<Cadena_Hexadecimal> .
También se recomienda, para escenarios OLTP, que los usuarios creen un índice en columnas ($ from_id, $ to_id), para búsquedas más rápidas en la dirección del borde.

Restricciones Edge

Una restricción de Edge se define en una tabla Edge de gráfico y es un par de tablas Node que un tipo de Edge determinado puede conectar. Esto le da a los usuarios un mejor control sobre su esquema gráfico.
Con la ayuda de restricciones Edge, los usuarios pueden restringir el tipo de nodos a los que se permite conectar un borde determinado.

Cláusulas de restricción Edge

  • Cada restricción Edge consta de una o más cláusulas de restricción Edge.
  • Una cláusula de restricción Edge es el par de nodos FROM y TO que el Edge dado podría conectar.
  • Tenga en cuenta que tiene nodos de Producto y Cliente en su gráfico y que utiliza la restricción Venta Edge para conectar estos nodos.
  • La cláusula de restricción Edge especifica el par de nodos FROM y TO y la dirección del borde. En este caso, la cláusula de restricción de borde será Cliente A Producto. Es decir, se permitirá la inserción de un Venta que va de un Cliente a un Producto.
  • Los intentos de insertar un borde que va del Producto al Cliente fallan.
  • Una cláusula de restricción Edge contiene un par de tablas de nodo FROM y TO en las que se aplica la restricción de borde.
  • Si se crean múltiples restricciones de borde en una sola tabla de borde, los bordes deben satisfacer TODAS las restricciones para ser permitidos.

Limitaciones en el uso de Graph Tables

  • Las tablas temporales locales o globales no pueden ser tablas de nodo o borde.
  • Los tipos de tabla y las variables de tabla no se pueden declarar como una tabla de nodo o borde.
  • Las tablas de nodo y borde no se pueden crear como tablas temporales con versión del sistema.
  • Las tablas de nodo y borde no pueden ser tablas de memoria optimizada.
  • Los usuarios no pueden actualizar las columnas $ from_id y $ to_id de un borde utilizando la instrucción UPDATE.
  • Para actualizar los nodos que conecta un borde, los usuarios deberán insertar el nuevo borde que apunta a nuevos nodos y eliminar el anterior.
  • No se admiten consultas cruzadas de base de datos en objetos de gráficos.

Creando Graph Tables

Usando la base de datos Northwind, se va a crear dos Graph Tables, una para Personas, que va a ser el Nodo, y otra para Grupos, que será el Edge (Vértice) que tendrá las relaciones entre las personas.

use Northwind
go

Tablas tipo gráfico para relaciones muchos a muchos
Crear una tabla Node para Personas
. (Ver creación de tablas)

Create table dbo.Personas
(
PersonasID int,
PersonasCodigo nchar(3), PersonasPaterno nvarchar(100),
PersonasMaterno nvarchar(100),PersonasNombre nvarchar(100),
PersonasFechaNacimiento Date,
constraint PersonasPK Primary key (PersonasID)
) As Node
go

Insertar registros en la tabla Personas, note que se ha especificado
un campo código adicional a la PK. (Ver Insertar registros)

insert into Personas
values (1,’059′,’Luque’,’Sanchez’,’Fernando’,’23/07/1966′),
(2,’105′,’Pereda’,’Mendoza’,’Carlos’,’24/02/1996′),
(3,’078′,’Chavez’,’Alvarado’,’Ingrid’,’30/12/1994′),
(4,’450′,’Campos’,’Castro’,’Mario’,’16/06/1986′)
go

El resultado se puede notar en la siguiente figura
select * from Personas
go

Crear una tabla Edge para las relaciones entre personas
Create table Grupos
(
GrupoFormacion Date
) As Edge
go

Insertar relaciones en la Graph Table Personas y la tabla Edge Grupos.

La relación entre personas se forman con dos instrucciones select que representan las partes From y To de la relación.En cada instrucción se debe extraer el dato que representa al nodo usando la función $node_id.

Relación entre las personas con código 105, Carlos Pereda Mendoza y la que tiene el código 078, Ingrid Chavez Alvarado. Note que estas relaciones para este ejercicio definen la formación de un grupo y se ha incluido un campo adicional en el Edge que es la fecha de creación del grupo.

insert into Grupos values
((Select $node_id from Personas where PersonasCodigo = ‘105’),
(Select $node_id from Personas where PersonasCodigo = ‘078’),’21/01/2019′)
go

Insertar mas relaciones entre personas
insert into Grupos values
((Select $node_id from Personas where PersonasCodigo = ‘078’),
(Select $node_id from Personas where PersonasCodigo = ‘450’),’08/12/2018′)
go
insert into Grupos values
((Select $node_id from Personas where PersonasCodigo = ‘059’),
(Select $node_id from Personas where PersonasCodigo = ‘105’),’13/01/2019′)
go
insert into Grupos values
((Select $node_id from Personas where PersonasCodigo = ‘105’),
(Select $node_id from Personas where PersonasCodigo = ‘059’),’23/11/2018′)
go

Ver el contenido de la tabla Edge Grupos
select * from Grupos
go

Para visualizar las relaciones de Carlos Pereda (Cód. 105)

Select Personas2.PersonasPaterno, Personas2.PersonasMaterno,
Personas2.PersonasNombre, G.GrupoFormacion
from Personas As Personas1, Grupos As G, Personas As Personas2
where match(Personas1-(G)->Personas2)
and Personas1.PersonasCodigo = ‘105’
go

Cláusula Match del Select

Especifica una condición de búsqueda para un gráfico. MATCH solo se puede usar con el nodo gráfico y las tablas Edge, en la instrucción SELECT como parte de la cláusula WHERE.