La serie finora:

  1. SQL Server Grafico basi di dati – Parte 1: Introduzione
  2. SQL Server Grafico basi di dati – Parte 2: l’Interrogazione di Dati in un Grafico Database
  3. SQL Server Grafico basi di dati – Parte 3: Modifica dei Dati in un Grafico Database
  4. SQL Server Grafico basi di dati – Parte 4: L’utilizzo dei dati gerarchici in un grafico database
  5. SQL Server Grafico basi di dati – Parte 5: Importazione di dati relazionali in un database Graph

Con il rilascio di SQL Server 2017, Microsoft ha aggiunto il supporto per i database graph per gestire meglio i set di dati che contengono relazioni di entità complesse, come il tipo di dati generati da un sito di social media, in cui è possibile disporre di un mix di relazioni I database grafici utilizzano le stesse strutture di tabelle presenti nei database SQL Server tradizionali e supportano gli stessi strumenti e le stesse istruzioni T-SQL, ma includono anche funzionalità per l’archiviazione e la navigazione di relazioni complesse.

Questo articolo è il primo di una serie sui database SQL Server graph. L’articolo introduce ai concetti di base del grafico e illustra come creare e popolare tabelle del grafico, utilizzando SQL Server Management Studio (SSMS) e un’istanza locale di SQL Server 2017. Negli articoli da seguire, approfondiremo come interrogare un database grafico e modificarne i dati, ma per questo articolo, stiamo iniziando con le basi.

Il database SQL Server Graph

I database graph di SQL Server possono semplificare il processo di modellazione dei dati che contengono complesse relazioni molti-a-molti e gerarchiche. Nella sua forma più elementare, un database grafico è una raccolta di nodi e bordi che lavorano insieme per definire vari tipi di relazioni. Un nodo è un’entità come una persona o una posizione. Un bordo è una relazione tra due entità. Ad esempio, potrebbe esistere una relazione tra un luogo come Toledo e una persona di nome Chris, che vive a Toledo. Chris e Toledo sono le entità, e’ vive in ‘ è il rapporto tra i due.

Una tabella node in SQL Server è una raccolta di entità simili e una tabella edge è una raccolta di relazioni simili. Per aiutare a capire come funziona, considera il modello grafico mostrato nella figura seguente, che si basa su un forum fittizio di amanti dei pesci. Il modello include tre nodi (FishSpecies, FishLover e FishPost) e tre bordi (Mi piace, Post e LinksTo).

I rettangoli rappresentano i nodi e le frecce che collegano i nodi rappresentano i bordi, con le frecce che puntano nella direzione della relazione. Ad esempio, i bordi Mi piace possono definire una delle seguenti relazioni:

  • Un amante del pesce ama una specie di pesce.
  • Un amante del pesce ama un post sul pesce.
  • Un amante del pesce ama un altro amante del pesce.

È possibile rappresentare tutte e tre le relazioni come dati in una singola tabella di bordo nel database grafico, con ciascuna relazione nella propria riga. Una tabella di nodi funziona più o meno allo stesso modo, tranne che include una riga per ogni entità. È inoltre possibile associare le proprietà sia ai nodi che ai bordi. Una proprietà è un attributo chiave-valore definito come una colonna in una tabella nodo o bordo. Ad esempio, il nodo FishSpecies potrebbe includere proprietà per memorizzare i nomi comuni e scientifici di ciascuna specie. Le proprietà vengono create come colonne definite dall’utente nella tabella FishSpecies. Quando si crea una tabella di nodi, è necessario includere almeno una proprietà.

Per la maggior parte delle operazioni, le tabelle node e edge funzionano come qualsiasi altra tabella definita dall’utente di SQL Server. Sebbene ci siano alcune limitazioni, come non essere in grado di dichiarare tabelle temporanee o variabili di tabella come tabelle di nodi o bordi, la maggior parte delle volte scoprirai che lavorare con le tabelle dei grafici sarà un territorio familiare.

Dove le cose diventano un po ‘ poco chiare è con il database grafico stesso. Anche se il nome potrebbe suggerire che stai creando un nuovo tipo di oggetto database, questo non è il caso. Un database grafico è semplicemente un costrutto logico definito all’interno di un database definito dall’utente, che può supportare non più di un database grafico. L’esistenza del database grafico è relativamente trasparente dall’esterno e, per la maggior parte, non è qualcosa di cui devi preoccuparti. Quando si lavora con i database dei grafici, l’attenzione principale sarà sulle tabelle dei grafici e sui dati che contengono.

In generale, un database grafico non fornisce funzionalità che non è possibile ottenere utilizzando le funzionalità relazionali tradizionali. La promessa del database grafico sta nell’essere in grado di organizzare e interrogare determinati tipi di dati in modo più efficiente. Microsoft consiglia di prendere in considerazione l’implementazione di un database grafico nelle seguenti circostanze:

  • È necessario analizzare i dati altamente interconnessi e le relazioni tra tali dati.
  • Stai supportando i dati con complesse relazioni molti-a-molti in continua evoluzione.
  • Si sta lavorando con i dati gerarchici, durante il tentativo di navigare le limitazioni del tipo di dati HierarchyID.

Le funzionalità del database grafico di SQL Server sono completamente integrate nel motore di database, sfruttando componenti come il processore di query e il motore di archiviazione. Grazie a questa integrazione, è possibile utilizzare i database graph in combinazione con una vasta gamma di componenti, tra cui indici columnstore, servizi di apprendimento automatico, SSMS e varie altre funzionalità e strumenti.

Definizione delle tabelle Nodo grafico

Per creare un database grafico basato sul modello mostrato nella figura precedente, è necessario creare tre tabelle nodo e tre tabelle bordo. Microsoft ha aggiornato l’istruzione CREATE TABLE in SQL Server 2017 per includere le opzioni per la definizione di entrambi i tipi di tabella. Come già notato, è possibile creare le tabelle in qualsiasi database definito dall’utente. Per gli esempi in questo articolo, ho creato un database di base denominato FishGraph, come mostrato nel seguente codice T-SQL:

1
2
3
4
5
6

UTILIZZARE master;
VAI
DROP DATABASE SE ESISTE FishGraph;
VAI
CREA DATABASE FishGraph;
VAI

Come puoi vedere, non c’è niente di speciale qui. Si crea il database proprio come qualsiasi altro database definito dall’utente. Non c’è niente di speciale che devi fare per configurarlo per supportare un database grafico.

Se hai intenzione di provare questi esempi per te stesso, puoi utilizzare il database FishGraph o uno di tua scelta. Qualunque cosa tu decida, il passo successivo è creare la tabella dei nodi FishSpecies, utilizzando la seguente istruzione CREATE TABLE:

1
2
3
4
5
6
7
8
9

UTILIZZARE FishGraph;
VAI
DROP TABLE IF EXISTS FishSpecies;
VAI
CREATE TABLE FishSpecies (
FishID INT IDENTITY CHIAVE PRIMARIA,
CommonName di tipo NVARCHAR(100) NOT NULL,
ScientificName di tipo NVARCHAR(100) NOT NULL
) COME NODO;

Le definizioni delle colonne dovrebbero essere abbastanza semplici. Ciò che è importante qui è la clausola AS NODE, che è necessario includere per creare una tabella node. Quando si specifica questa clausola, il motore di database aggiunge due colonne alla tabella (che arriveremo a breve) e crea un indice univoco, non cluster su una di quelle colonne.

È possibile verificare se la tabella è stata creata come tabella dei nodi interrogando il sys.vista tabelle. Con il rilascio di SQL Server 2017, Microsoft ha aggiornato la vista per includere le colonne di bit is_node e is_edge. Se la tabella è una tabella di nodi, il valore della colonna is_node è impostato su 1 e il valore della colonna is_edge è impostato su 0. Se una tabella di bordo, i valori sono invertiti. L’esempio seguente utilizza la visualizzazione per confermare che il FishSpecies tabella è stata definita correttamente:

1
2

SELEZIONARE is_node, is_edge DA sys.tabelle
DOVE name = ‘FishSpecies’;

L’istruzione SELECT restituisce i risultati mostrati nella figura seguente, che indicano che FishSpecies è stato creato come tabella dei nodi.

Microsoft ha anche aggiornato il sistema.vista colonne per includere le colonne graph_type e graph_type_desc. È possibile utilizzare la visualizzazione e nuove colonne per saperne di più sul FishSpecies tabella:

1
2
3

SELECT nome, graph_type, graph_type_desc
DA sys.colonne
DOVE object_id = OBJECT_ID (‘FishSpecies’);

La figura seguente mostra le colonne create per la tabella FishSpecies.

Quando si crea una tabella di nodi, il motore di database aggiunge le colonne graph_id_<hex_string> e nod node_id_<hex_string> e crea un indice univoco, non cluster sulla colonna nod node_id. Il motore di database utilizza la prima colonna per le operazioni interne e rende la seconda colonna disponibile per l’accesso esterno. La colonna nod node_id memorizza un identificatore univoco per ogni entità, che è possibile visualizzare quando si interrogano i dati. Questa è l’unica colonna dei due è necessario essere preoccupati. Infatti, se si dovesse interrogare direttamente la tabella, si vedrebbe solo la colonna nod node_id, non la colonna graph_id.

Le colonne graph_type e graph_type_desc restituite dal sys.le viste colonne sono specifiche per le colonne generate automaticamente in una tabella del grafico. Le colonne indicano i tipi di colonne generate dal motore di database. Il tipo è indicato da un valore numerico predefinito e dalla relativa descrizione. Microsoft non fornisce una grande quantità di specifiche su questi codici e descrizioni, ma è possibile trovare alcuni dettagli nell’architettura Microsoft document SQL Graph. Di nuovo, la tua preoccupazione principale è con la colonna nod node_id e i dati che contiene.

Dopo aver creato la tabella, è possibile iniziare ad aggiungere dati. L’esecuzione di un’istruzione INSERT contro una tabella node funziona proprio come qualsiasi altra tabella. Specificare le colonne di destinazione e i relativi valori, come illustrato nell’esempio seguente:

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’),
(‘luccio del Nord’, ‘Esox lucius’),
(‘aringa del Pacifico’, ‘Clupea pallasi’),
(‘la trota Arcobaleno’, ‘Oncorhynchus mykiss’),
(‘Sole (Dover)’, ‘Solea solea’),
(‘basso Bianco’, ‘Morone chrysops’);

naturalmente, è possibile aggiungere qualsiasi specie di pesce è avere una particolare predilezione per. Le mie scelte qui sono state completamente arbitrarie. Ma se ti attieni ai miei dati e poi interroghi la tabella FishSpecies, i tuoi risultati dovrebbero essere simili a quelli nella figura seguente.

Come accennato in precedenza, la colonna graph_id non viene visualizzata nei risultati, ma la colonna nod node_id lo fa, completa di valori generati automaticamente. Il motore di database crea ogni valore come una stringa JSON che fornisce il tipo (nodo o bordo), schema, tabella e un valore BIGINT univoco per ogni riga. Come previsto, il motore di database restituisce anche i valori nelle colonne definite dall’utente, proprio come una tipica tabella relazionale.

Il passo successivo consiste nel creare e popolare la tabella dei nodi FishLover, utilizzando il seguente codice T-SQL:

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

DROP TABLE IF EXISTS FishLover;
VAI
CREATE TABLE FishLover (
FishLoverID INT IDENTITY CHIAVE PRIMARIA,
nome utente di tipo NVARCHAR(50) NOT NULL,
) COME NODO;
INSERT INTO FishLover (nome utente) VALORI
(‘powerangler’),
(‘jessie98’),
(‘agganciato’),
(‘deepdive’),
(‘underwatercasey’);

La tabella comprende solo due colonne definite dall’utente—FishLoverID e nome utente, ma è possibile definire il numero di colonne necessarie. Ad esempio, è possibile includere nome e cognome, informazioni di contatto e altri dettagli, a seconda della natura dell’applicazione. Una volta creata la tabella, è possibile eseguire una query per verificare i dati. I risultati dovrebbero essere simili a quelli mostrati nella figura seguente.

quindi, Si può prendere la stessa procedura per creare e popolare il FishPost tavola, passando in qualsiasi messaggio di testo che si desidera:

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

DROP TABLE IF EXISTS FishPost;
VAI
CREATE TABLE FishPost (
PostID INT IDENTITY CHIAVE PRIMARIA,
Titolo NVARCHAR(50) NOT NULL,
Testomessaggio di tipo NVARCHAR(800) NOT NULL
) COME NODO;
INSERT INTO FishPost (Titolo, Testomessaggio) VALORI
(‘The one that got away’, “Il nostro team è disponibile, si prega di contattarci. Enea vantaggio esigenze riservate.’),
(‘Uno studio sul pesce’, ‘ penatibus venenatis, nascetur ridiculus mus.’),
(‘Gancio, lenza e zavorra”, ” Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.’),
(‘Tanti pesci, così poco tempo’, ‘ Nullam dictum felis eu pede mollis pretium. Intero tincidunt.’),
(‘Il mio pesce preferito’, ‘ Enea leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.’);

La figura seguente mostra i risultati che si vedrebbe se bloccato con i dati Lorem Ipsum.

Questo è tutto ciò che c’è da creare e compilare le tabelle dei nodi. Ad eccezione della clausola AS NODE nell’istruzione CREATE TABLE, la maggior parte di tutto il resto è come al solito.

Definizione delle tabelle dei bordi del grafico

La creazione di una tabella dei bordi è simile alla creazione di una tabella dei nodi, tranne per il fatto che è necessario specificare la clausola AS EDGE anziché la clausola AS NODE. Per esempio, per creare Posti di tabella, è necessario utilizzare la seguente istruzione CREATE TABLE:

1
2
3
4
5

DROP TABLE IF EXISTS Post;
VAI
CREATE TABLE Post (
ImportantFlag PO ‘ NOT NULL DEFAULT 0
) COME EDGE;

La definizione della tabella è simile a un nodo tabella, tranne che non include una colonna di chiave primaria (e, naturalmente, si prende COME EDGE clausola). In questo caso, una chiave primaria non è necessaria, ma se a un certo punto si determina che è necessaria una chiave primaria, è certamente possibile aggiungerne una. (Vedrai a breve perché le chiavi primarie sono utili per le tabelle dei nodi.)

Si noti che la definizione della tabella include anche la colonna ImportantFlag. Ho incluso questo principalmente per dimostrare che è possibile aggiungere colonne definite dall’utente alla tabella edge, proprio come con le tabelle dei nodi. Detto questo, non è raro creare una tabella edge senza colonne definite dall’utente, a differenza di una tabella node, che deve includere almeno una colonna definita dall’utente.

Dopo aver creato la tabella edge, è possibile verificare che sia stata definita correttamente interrogando il sys.vista tabelle, come hai visto in precedenza:

1
2

SELEZIONARE is_node, is_edge DA sys.tabelle
DOVE name = ‘Posts’;

Se hai fatto tutto bene, i risultati dovrebbero assomigliare a quelli nella figura seguente.

È anche possibile interrogare il sys.vista tabelle per verificare i dettagli delle colonne, proprio come hai fatto prima:

1
2
3

SELEZIONARE name, graph_type, graph_type_desc
DA sys.colonne
DOVE object_id = OBJECT_ID(‘Messaggi’);

La figura seguente mostra i risultati restituiti sul mio sistema.

Come puoi vedere, il motore di database aggiunge otto colonne a una tabella edge, piuttosto che le due che hai visto con le tabelle dei nodi. Di nuovo, fare riferimento al documento Architettura grafico SQL per le descrizioni di ciascun tipo di colonna. La maggior parte di queste colonne viene utilizzata dal motore di database per le operazioni interne. È necessario essere interessati principalmente alle seguenti tre colonne:

  • La colonna hex edge_id_<hex_string> identifica in modo univoco ogni relazione.
  • La colonna hex from_id_< hex_string> memorizza il valore nod node_id associato all’entità nella tabella in cui ha origine la relazione.
  • La colonna hex to_id_< hex_string> memorizza il valore nod node_id associato all’entità nella tabella in cui termina la relazione.

Come con la colonna nod node_id in una tabella di nodi, il motore di database genera automaticamente i valori per la colonna ed edge_id. Tuttavia, è necessario aggiungere in modo specifico i valori alle colonne from from_id e to to_id per definire una relazione. Per dimostrare come funziona, inizieremo con un singolo record:

1
2
3

INSERT INTO Messaggi ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 1),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 3));

L’istruzione INSERT è la definizione di un rapporto di Posti di tavolo tra un FishLover entità la cui FishLoverID valore è 1 e un FishPost entità la cui PostID valore è 3. Si noti che è possibile utilizzare gli alias nod node_id, from from_id e to to_id per fare riferimento alle colonne di destinazione, senza dover creare le stringhe esadecimali.

Per aggiungere dati alla colonna from from_id, è necessario specificare il valore nod node_id associato all’entità FishLover. Un modo per ottenere questo valore è includere una subquery che si rivolge all’entità, utilizzando il suo valore della chiave primaria. Puoi adottare lo stesso approccio per la colonna from from_id.

L’inserimento dei dati in questo modo dimostra perché è utile aggiungere chiavi primarie alle tabelle dei nodi, ma non è necessario per le tabelle edge. Le chiavi primarie nelle tabelle dei nodi rendono molto più semplice fornire il valore nod node_id all’istruzione INSERT.

Se ora si interroga la tabella Post, i risultati dovrebbero essere simili a quelli mostrati nella figura seguente.

La tabella deve contenere la nuova relazione, con ImportantFlag impostato su 0, il valore predefinito. È ora possibile aggiungere alcune righe in più, utilizzando le seguenti istruzioni INSERT:

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

INSERT INTO Messaggi ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 3),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 2));
INSERT INTO Messaggi ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 2),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 5));
INSERT INTO Messaggi ($from_id, $to_id, ImportantFlag) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 5),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 4), 1);
INSERT INTO Messaggi ($from_id, $to_id, ImportantFlag) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 4),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 1), 1);

si Noti che le ultime due istruzioni INSERT, inoltre, fornire un valore per il ImportantFlag colonna. Quando si interroga la tabella Post, i risultati dovrebbero ora includere tutte e cinque le righe.

Il prossimo passo è creare e popolare la tabella Mi piace, utilizzando il seguente codice T-SQL:

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

DROP TABLE IF EXISTS Piace;
VAI
CREATE TABLE Piace COME EDGE;
INSERT INTO Piace ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 3),
(SELEZIONARE $node_id DA FishSpecies DOVE FishID = 8));
INSERT INTO Piace ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 5),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 4));
INSERT INTO Piace ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishLover DOVE FishLoverID = 1),
(SELEZIONARE $node_id DA FishLover DOVE FishLoverID = 4));

È possibile, naturalmente, definire le relazioni che si desidera. Il punto importante da notare qui è che non sei limitato a nessun insieme di nodi. Ad esempio, la prima istruzione INSERT crea una relazione tra FishLover e FishSpecies, la seconda istruzione crea una relazione tra FishLover e FishPost e la terza istruzione crea una relazione tra FishLover e FishLover. Questo ci dà i risultati della query mostrati nella figura seguente.

È possibile adottare lo stesso approccio durante la creazione e la compilazione della tabella LinksTo:

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

DROP TABLE IF EXISTS LinksTo;
VAI
CREATE TABLE LinksTo COME EDGE;
INSERT INTO LinksTo ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishPost DOVE PostID = 2),
(SELEZIONARE $node_id DA FishSpecies DOVE FishID = 6));
INSERT INTO LinksTo ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishPost DOVE PostID = 4),
(SELEZIONARE $node_id DA FishLover DOVE FishLoverID = 1));
INSERT INTO LinksTo ($from_id, $to_id) VALUES (
(SELECT $node_id DA FishPost DOVE PostID = 3),
(SELEZIONARE $node_id DA FishPost DOVE PostID = 5));

La figura che segue mostra quello che i dati di come dovrebbe apparire dopo essere stato aggiunto alla tabella, ipotizzando di aver seguito l’esempio.

Con un database grafico, è possibile aggiungere una vasta gamma di relazioni tra i nodi di origine e di terminazione. È inoltre possibile incorporare facilmente le modifiche al modello grafico. Ad esempio, potresti decidere di aggiungere una tabella nodo FishRecipes per memorizzare le ricette di pesce che gli utenti pubblicano nel forum, nel qual caso puoi sfruttare i post, i Mi piace e le tabelle edge di LinksTo esistenti.

Andare avanti con i database Graph

Poiché Microsoft include le funzionalità del database graph come parte del motore di database SQL Server, è possibile provarle facilmente senza dover installare o riconfigurare alcun componente. Meglio di tutti, è possibile utilizzare gli stessi strumenti e le procedure che hai utilizzato per tutto il tempo per creare e popolare nodo e tabelle di bordo. Negli articoli a seguire, tratteremo come interrogare e modificare i dati del grafico e dare un’occhiata più da vicino a lavorare con i dati gerarchici, in modo da essere sicuri di rimanere sintonizzati.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.