La serie hasta ahora:

  1. Bases de datos de gráficos SQL Server-Parte 1: Introducción
  2. Bases de datos de gráficos SQL Server-Parte 2: Consulta de datos en una Base de datos de gráficos
  3. Bases de datos de gráficos SQL Server-Parte 3: Modificación de datos en una base de datos de gráficos
  4. Bases de datos de gráficos SQL Server-Parte 4: Trabajo con datos jerárquicos en una base de datos de gráficos
  5. Bases de datos de gráficos SQL Server-Parte 5: Importación de Datos relacionales en una base de datos de gráficos

Con el lanzamiento de SQL Server 2017, Microsoft agregó compatibilidad con bases de datos de gráficos para manejar mejor conjuntos de datos que contienen relaciones de entidad complejas, como el tipo de datos generados por un sitio de redes sociales, donde puede tener una combinación de relaciones de muchos a muchos que cambian con frecuencia. Las bases de datos de gráficos utilizan las mismas estructuras de tabla que se encuentran en las bases de datos tradicionales de SQL Server y admiten las mismas herramientas y sentencias T-SQL, pero también incluyen funciones para almacenar y navegar por relaciones complejas.

Este artículo es el primero de una serie sobre bases de datos de gráficos de SQL Server. El artículo presenta conceptos básicos de gráficos y demuestra cómo crear y rellenar tablas de gráficos mediante SQL Server Management Studio (SSMS) y una instancia local de SQL Server 2017. En los artículos a continuación, profundizaremos en cómo consultar una base de datos de gráficos y modificar sus datos, pero para este artículo, comenzaremos con lo básico.

La base de datos de gráficos de SQL Server

Las bases de datos de gráficos de SQL Server pueden ayudar a simplificar el proceso de modelado de datos que contienen relaciones jerárquicas complejas de muchos a muchos. En su forma más básica, una base de datos de gráficos es una colección de nodos y bordes que trabajan juntos para definir varios tipos de relaciones. Un nodo es una entidad, como una persona o lugar. Una arista es una relación entre dos entidades. Por ejemplo, podría existir una relación entre un lugar como Toledo y una persona llamada Chris, que vive en Toledo. Chris y Toledo son las entidades ,y ‘vive en’ es la relación entre los dos.

Una tabla de nodos en SQL Server es una colección de entidades similares, y una tabla de bordes es una colección de relaciones similares. Para ayudar a entender cómo funciona esto, considere el modelo de gráfico que se muestra en la siguiente figura, que se basa en un foro ficticio de amantes de los peces. El modelo incluye tres nodos (Fishspecie, FishLover y FishPost) y tres bordes (Me gusta, Posts y LinksTo).

Los rectángulos representan los nodos, y las flechas que conectan los nodos representan los bordes, con las flechas apuntando en la dirección de la relación. Por ejemplo, los bordes de Likes pueden definir cualquiera de las siguientes relaciones:

  • A un amante de los peces le gustan las especies de peces.
  • A un amante de los peces le gusta una publicación sobre peces.
  • A un amante de los peces le gusta otro amante de los peces.

Puede representar las tres relaciones como datos en una sola tabla de aristas en la base de datos de gráficos, con cada relación en su propia fila. Una tabla de nodos funciona de la misma manera, excepto que incluye una fila para cada entidad. También puede asociar propiedades con nodos y bordes. Una propiedad es un atributo clave-valor que se define como una columna en un nodo o tabla de bordes. Por ejemplo, el nodo de la especie de pez podría incluir propiedades para almacenar los nombres comunes y científicos de cada especie. Las propiedades se crean como columnas definidas por el usuario en la tabla FishSpecies. Al crear una tabla de nodos, debe incluir al menos una propiedad.

Para la mayoría de las operaciones, las tablas de nodos y bordes funcionan como cualquier otra tabla definida por el usuario de SQL Server. Aunque hay algunas limitaciones, como no poder declarar tablas temporales o variables de tabla como tablas de nodos o aristas, la mayoría de las veces encontrará que trabajar con tablas de gráficos será un territorio familiar.

Donde las cosas se ponen un poco confusas es con la propia base de datos de gráficos. Aunque el nombre puede sugerir que está creando un nuevo tipo de objeto de base de datos, ese no es el caso. Una base de datos de gráficos es simplemente una construcción lógica definida dentro de una base de datos definida por el usuario, que no puede admitir más de una base de datos de gráficos. La existencia de la base de datos de gráficos es relativamente transparente desde el exterior y, en su mayor parte, no es algo de lo que deba preocuparse. Al trabajar con bases de datos de gráficos, su enfoque principal estará en las tablas de gráficos y los datos que contienen.

En general, una base de datos de gráficos no proporciona capacidades que no pueda lograr mediante el uso de características relacionales tradicionales. La promesa de la base de datos de gráficos radica en poder organizar y consultar ciertos tipos de datos de manera más eficiente. Microsoft recomienda que considere implementar una base de datos de gráficos en las siguientes circunstancias:

  • Es necesario analizar datos altamente interconectados y las relaciones entre esos datos.
  • Admite datos con relaciones complejas de muchos a muchos que evolucionan continuamente.
  • Está trabajando con datos jerárquicos, mientras intenta navegar por las limitaciones del tipo de datos HierarchyID.

Las funciones de base de datos de gráficos de SQL Server están completamente integradas en el motor de base de datos, aprovechando componentes como el procesador de consultas y el motor de almacenamiento. Gracias a esta integración, puede usar bases de datos de gráficos junto con una amplia gama de componentes, incluidos índices de almacén de columnas, Servicios de aprendizaje automático, SSM y otras funciones y herramientas.

Definición de tablas de nodos de gráfico

Para crear una base de datos de gráficos basada en el modelo que se muestra en la figura anterior, debe crear tres tablas de nodos y tres tablas de aristas. Microsoft ha actualizado la instrucción CREATE TABLE en SQL Server 2017 para incluir opciones para definir cualquiera de los tipos de tabla. Como ya se ha señalado, puede crear tablas en cualquier base de datos definida por el usuario. Para los ejemplos de este artículo, creé una base de datos básica llamada FishGraph, como se muestra en el siguiente código T-SQL:

1
2
3
4
5
6

USAR maestro;
IR
SOLTAR LA BASE DE DATOS SI EXISTE FishGraph;
IR
CREAR FishGraph DE BASE DE DATOS;
IR

Como puedes ver, no está pasando nada especial aquí. La base de datos se crea como cualquier otra base de datos definida por el usuario. No hay nada especial que necesite hacer para configurarlo para que admita una base de datos de gráficos.

Si planea probar estos ejemplos por sí mismo, puede usar la base de datos FishGraph o una de su elección. Decida lo que decida, el siguiente paso es crear la tabla de nodos FishSpecies, utilizando la siguiente instrucción CREATE TABLE:

1
2
3
4
5
6
7
8
9

USO FishGraph;
IR
DROP TABLE IF EXISTS FishSpecies;
IR
CREAR TABLA FishSpecies (
FishID INT IDENTIDAD de CLAVE PRINCIPAL,
CommonName de tipo NVARCHAR(100) not NULL,
ScientificName de tipo NVARCHAR(100) not NULL
) COMO NODO;

Las definiciones de columna debe ser bastante sencillo. Lo importante aquí es la cláusula AS NODE, que debe incluir para crear una tabla de nodos. Cuando especifica esta cláusula, el motor de base de datos agrega dos columnas a la tabla (a las que veremos en breve) y crea un índice único y no agrupado en una de esas columnas.

Puede verificar si la tabla se ha creado como una tabla de nodos consultando el sys.vista de tablas. Con el lanzamiento de SQL Server 2017, Microsoft actualizó la vista para incluir las columnas de bits is_node e is_edge. Si la tabla es una tabla de nodos, el valor de la columna is_node se establece en 1 y el valor de la columna is_edge en 0. Si se trata de una tabla de bordes, los valores se invierten. El siguiente ejemplo utiliza la vista para confirmar que la tabla de especies de peces se ha definido correctamente:

1
2

SELECCIONE is_node, is_edge DE sys.cuadros
DONDE name = «Especie de pez»;

La instrucción SELECT devuelve los resultados que se muestran en la siguiente figura, que indican que FishSpecies se creó como una tabla de nodos.

Microsoft también actualizó el sistema.vista de columnas para incluir las columnas graph_type y graph_type_desc. Puede usar la vista y las columnas nuevas para obtener más información sobre la tabla de especies de peces:

1
2
3

SELECCIONE name, graph_type, graph_type_desc
DE sys.columnas
DONDE object_id = OBJECT_ID(‘FishSpecies’);

La siguiente figura muestra las columnas creadas para la FishSpecies tabla.

Al crear una tabla de nodos, el motor de base de datos agrega las columnas graph_id_<hex_string> y hex node_id_<hex_string> y crea un índice único y no agrupado en la columna $node_id. El motor de base de datos utiliza la primera columna para operaciones internas y hace que la segunda columna esté disponible para acceso externo. La columnaid node_id almacena un identificador único para cada entidad, que puede ver al consultar los datos. Esta es la única columna de las dos que necesita preocuparse. De hecho, si se consulta la tabla directamente, solo verá los $node_id columna, no la graph_id columna.

Las columnas graph_type y graph_type_desc devueltas por el sys.las vistas de columnas son específicas de las columnas generadas automáticamente en una tabla de gráficos. Las columnas indican los tipos de columnas que generó el motor de base de datos. El tipo se indica mediante un valor numérico predefinido y su descripción relacionada. Microsoft no proporciona una gran cantidad de detalles sobre estos códigos y descripciones, pero puede encontrar algunos detalles en el documento de Microsoft SQL Graph Architecture. De nuevo, su principal preocupación es con la columna $node_id y los datos que contiene.

Después de crear la tabla, puede comenzar a agregar datos. Ejecutar una instrucción INSERT contra una tabla de nodos funciona como cualquier otra tabla. Especifique las columnas de destino y sus valores, como se muestra en el siguiente ejemplo:

1
2
3
4
5
6
7
8
9
10
11

INSERT INTO FishSpecies (CommonName, ScientificName) VALUES
(‘Atlantic halibut’, ‘Hippoglossus hippoglossus’),
(‘Chinook salmon’, ‘Oncorhynchus tshawytscha’),
(‘European seabass’, ‘Morone (Decentrarchus) labrax’),
(‘Gizzard shad’, ‘Dorosoma cepedianum’),
(‘Japanese striped knife jaw’, «Oplegnathus faciatus’),
(‘Lucio del norte», «Esox lucius’),
(‘Arenque del pacífico», «Clupea pallasi’),
(‘Trucha arco iris», «Oncorhynchus mykiss’),
(‘Lenguado (Dover)», «Solea solea’),
(‘Bajo blanco», «Morone chrysops’);

Por supuesto, puede agregar cualquier especie de pescado que le guste en particular. Mis elecciones aquí fueron completamente arbitrarias. Pero si sigue con mis datos y luego consulta la tabla de especies de peces, sus resultados deberían ser similares a los de la siguiente figura.

Como se mencionó anteriormente, la columna graph_id no aparece en los resultados, pero la columna $node_id sí, completa con valores generados automáticamente. El motor de base de datos crea cada valor como una cadena JSON que proporciona el tipo (nodo o borde), el esquema, la tabla y un valor BIGINT único para cada fila. Como era de esperar, el motor de base de datos también devuelve los valores de las columnas definidas por el usuario, al igual que una tabla relacional típica.

El siguiente paso es crear y rellenar la tabla de nodos de FishLover, utilizando el siguiente código T-SQL:

1
2
3
4
5
6
7
8
9
10
11
12

DROP TABLE IF EXISTS FishLover;
IR
CREAR TABLA FishLover (
FishLoverID INT IDENTIDAD de CLAVE PRINCIPAL,
nombre de Usuario de tipo NVARCHAR(50) not NULL,
) COMO NODO;
INSERT INTO FishLover (nombre de Usuario) VALORES
(‘powerangler’),
(‘jessie98’),
(‘enganchado’),
(‘deepdive’),
(‘underwatercasey’);

La tabla incluye sólo dos definido por el usuario columnas—FishLoverID y nombre de Usuario, pero se puede definir como tantas columnas como sea necesario. Por ejemplo, es posible que desee incluir nombres y apellidos, información de contacto y otros detalles, según la naturaleza de la aplicación. Una vez que haya creado la tabla, puede ejecutar una consulta para verificar los datos. Sus resultados deben ser similares a los que se muestran en la siguiente figura.

a continuación, puede tomar los mismos pasos para crear y llenar el FishPost la mesa, pasando en cualquier mensaje de texto que usted desee:

1
2
3
4
5
6
7
8
9
10
11
12
13

DROP TABLE IF EXISTS FishPost;
IR
CREAR TABLA FishPost (
PostID INT IDENTIDAD de CLAVE PRINCIPAL,
Título de tipo NVARCHAR(50) not NULL,
MessageText NVARCHAR(800) not NULL
) COMO NODO;
INSERT INTO FishPost (Título, MessageText) VALORES
(‘La que se escapó’, «Nuestro equipo está disponible, póngase en contacto con nosotros. Eneas advantage necesidades reservadas.’),
(‘A study on fish’, ‘ penatibus venenatis, nascetur ridiculus mus.’),
(‘Anzuelo, sedal y plomada», » Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.’),
(‘Tantos peces, tan poco tiempo», «Nullam dictum felis eu pede mollis pretium. Tincidunt entero.’),
(‘Mi pescado favorito, Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.’);

La siguiente figura muestra los resultados que vería si se quedara con los datos de Lorem Ipsum.

Eso es todo lo que hay que hacer para crear y rellenar las tablas de nodos. A excepción de la cláusula AS NODE de la instrucción CREATE TABLE, casi todo lo demás es como de costumbre.

Definir tablas de bordes de gráficos

Crear una tabla de bordes es similar a crear una tabla de nodos, excepto que debe especificar la cláusula AS EDGE en lugar de la cláusula AS NODE. Por ejemplo, para crear los Puestos de la tabla, utilice la siguiente instrucción CREATE TABLE:

1
2
3
4
5

DROP TABLE IF EXISTS Puestos;
IR
CREAR mensajes DE TABLA (
BIT DE FLAG importante NO NULO PREDETERMINADO 0
) COMO BORDE;

La definición de tabla es similar a una tabla de nodos, excepto que no incluye una columna de clave primaria (y, por supuesto, toma la cláusula AS EDGE). En este caso, no es necesaria una clave primaria, pero si en algún momento determina que necesita una clave primaria, ciertamente puede agregar una. (Verá en breve por qué las claves primarias son útiles para las tablas de nodos.)

Observe que la definición de tabla también incluye la columna ImportantFlag. Incluí esto principalmente para demostrar que puede agregar columnas definidas por el usuario a su tabla de bordes, al igual que con las tablas de nodos. Dicho esto, no es raro crear una tabla de bordes sin columnas definidas por el usuario, a diferencia de una tabla de nodos, que debe incluir al menos una columna definida por el usuario.

Después de crear la tabla edge, puede verificar que se ha definido correctamente consultando el sys.vista de tablas, como vio anteriormente:

1
2

SELECCIONE is_node, is_edge DE sys.cuadros
DONDE name = ‘Mensajes’;

Si hiciste todo bien, tus resultados deberían parecerse a los de la siguiente figura.

También puede consultar el sistema.vista de tablas para verificar los detalles de las columnas, tal como lo hizo antes:

1
2
3

SELECT nombre, graph_type, graph_type_desc
FROM sys.columnas
DONDE object_id = OBJECT_ID(‘Posts’);

La siguiente figura muestra los resultados devueltos en mi sistema.

Como puede ver, el motor de base de datos agrega ocho columnas a una tabla de bordes, en lugar de las dos que vio con tablas de nodos. Una vez más, consulte el documento de Arquitectura de gráficos SQL para obtener descripciones de cada tipo de columna. La mayoría de estas columnas son utilizadas por el motor de base de datos para operaciones internas. Debe preocuparse principalmente por las siguientes tres columnas:

  • La columna hex edge_id_<hex_string> identifica de forma única cada relación.
  • La columna hex from_id_<hex_string> almacena el valor associated node_id asociado a la entidad en la tabla donde se origina la relación.
  • La columna hex to_id_<hex_string> almacena el valor associated node_id asociado a la entidad en la tabla donde termina la relación.

Al igual que con la columna $node_id en una tabla de nodos, el motor de base de datos genera automáticamente valores para la columna ed edge_id. Sin embargo, debe agregar valores específicos a las columnas from from_id y columns to_id para definir una relación. Para demostrar cómo funciona esto, comenzaremos con un solo registro:

1
2
3

INSERTAR EN Mensajes (from from_id, to to_id) VALORES (
(SELECCIONAR $node_id DE FishLover DONDE FishLoverID = 1),
(SELECCIONE $node_id DE FishPost DONDE PostID = 3));

La instrucción INSERT define una relación en la tabla Posts entre una entidad FishLover cuyo valor FishLoverID es 1 y una entidad FishPost cuyo valor PostID es 3. Observe que puede usar los alias nod node_id ,from from_id y to to_id para hacer referencia a las columnas de destino, sin tener que crear cadenas hexadecimales.

Para agregar datos a la columna from from_id, debe especificar el valor associated node_id asociado a la entidad FishLover. Una forma de obtener este valor es incluir una subconsulta que se dirija a la entidad, utilizando su valor de clave primaria. Puede adoptar el mismo enfoque para la columna from from_id.

Insertar los datos de esta manera demuestra por qué es útil agregar claves primarias a las tablas de nodos, pero no es necesario para las tablas de bordes. Las claves principales de las tablas de nodos hacen que sea mucho más fácil proporcionar el valor INSERT node_id a la instrucción INSERT.

Si ahora consulta la tabla Posts, sus resultados deben ser similares a los que se muestran en la siguiente figura.

La tabla debe contener la nueva relación, con el ImportantFlag establecido en 0, el valor predeterminado. Ahora puede agregar algunas filas más, utilizando las siguientes instrucciones de INSERCIÓN:

1
2
3
4
5
6
7
8
9
10
11
12

INSERT INTO Mensajes ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishLover DONDE FishLoverID = 3),
(SELECCIONE $node_id DE FishPost DONDE PostID = 2));
INSERT INTO Mensajes ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishLover DONDE FishLoverID = 2),
(SELECCIONE $node_id DE FishPost DONDE PostID = 5));
INSERT INTO Mensajes ($from_id, $to_id, ImportantFlag) VALUES (
(SELECT $node_id DE FishLover DONDE FishLoverID = 5),
(SELECCIONE $node_id DE FishPost DONDE PostID = 4), 1);
INSERTAR EN mensajes (Posts from_id, to to_id, ImportantFlag) VALORES (
(SELECCIONAR $node_id DE FishLover DONDE FishLoverID = 4),
(SELECCIONE $node_id DE FishPost DONDE PostID = 1), 1);

Observe que las dos últimas instrucciones INSERT también proporcionan un valor para la columna ImportantFlag. Cuando consultes la tabla Posts, los resultados ahora deben incluir las cinco filas.

El siguiente paso es crear y rellenar la tabla Likes, utilizando el siguiente código T-SQL:

1
2
3
4
5
6
7
8
9
10
11
12

DROP TABLE IF EXISTS le Gusta;
IR
CREAR TABLA Gusta COMO BORDE;
INSERT INTO le Gusta ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishLover DONDE FishLoverID = 3),
(SELECCIONE $node_id DE FishSpecies DONDE FishID = 8));
INSERT INTO le Gusta ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishLover DONDE FishLoverID = 5),
(SELECCIONE $node_id DE FishPost DONDE PostID = 4));
INSERT INTO le Gusta ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishLover DONDE FishLoverID = 1),
(SELECCIONE $node_id DE FishLover DONDE FishLoverID = 4));

Usted puede, por supuesto, definir las relaciones que desea. El punto importante a tener en cuenta aquí es que no está limitado a un conjunto de nodos. Por ejemplo, la primera instrucción INSERT crea una relación entre FishLover y FishSpecies, la segunda instrucción crea una relación entre FishLover y FishPost, y la tercera instrucción crea una relación entre FishLover y FishLover. Esto nos da los resultados de la consulta que se muestran en la siguiente figura.

Puede adoptar el mismo enfoque al crear y rellenar la tabla LinksTo:

1
2
3
4
5
6
7
8
9
10
11
12

DROP TABLE IF EXISTS LinksTo;
IR
CREAR TABLA LinksTo COMO BORDE;
INSERT INTO LinksTo ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishPost DONDE PostID = 2),
(SELECCIONE $node_id DE FishSpecies DONDE FishID = 6));
INSERT INTO LinksTo ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishPost DONDE PostID = 4),
(SELECCIONE $node_id DE FishLover DONDE FishLoverID = 1));
INSERT INTO LinksTo ($from_id, $to_id) VALUES (
(SELECT $node_id DE FishPost DONDE PostID = 3),
(SELECCIONE $node_id DE FishPost DONDE PostID = 5));

La siguiente figura muestra lo que los datos deben verse como después de ser añadido a la tabla, suponiendo que siguieron el ejemplo.

Con una base de datos de gráficos, puede agregar una amplia gama de relaciones entre los nodos de origen y de terminación. También puede incorporar fácilmente cambios en el modelo de gráfico. Por ejemplo, puede decidir agregar una tabla de nodos FishRecipes para almacenar las recetas de pescado que los usuarios publican en el foro, en cuyo caso, puede aprovechar las Publicaciones, los Me gusta y los enlaces existentes en las tablas de bordes.

Seguir adelante con las bases de datos de gráficos

Dado que Microsoft incluye las características de la base de datos de gráficos como parte del motor de base de datos de SQL Server, puede probarlas fácilmente sin tener que instalar o reconfigurar ningún componente. Lo mejor de todo es que puede utilizar las mismas herramientas y procedimientos que ha estado utilizando todo el tiempo para crear y rellenar tablas de nodos y bordes. En los artículos a continuación, veremos cómo consultar y modificar datos de gráficos y analizaremos más de cerca el trabajo con datos jerárquicos, así que asegúrese de estar atento.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.