serien hittills:

  1. SQL Server Graph-databaser-Del 1: Introduktion
  2. SQL Server Graph-databaser-del 2: Fråga Data i en grafdatabas
  3. SQL Server Graph-databaser-del 3: ändra Data i en grafdatabas
  4. SQL Server Graph – databaser – Del 4: Arbeta med hierarkiska data i en grafdatabas
  5. SQL Server Graph-databaser-Del 5: Importera relationsdata till en grafdatabas

med lanseringen av SQL Server 2017 har Microsoft lagt till stöd för grafdatabaser för att bättre hantera datamängder som innehåller komplexa entitetsrelationer, till exempel den typ av data som genereras av en webbplats för sociala medier, där du kan ha en blandning av många till många relationer som ändras ofta. Grafdatabaser använder samma tabellstrukturer som finns i traditionella SQL Server-databaser och stöder samma verktyg och T-SQL-satser, men de innehåller också funktioner för att lagra och navigera i komplexa relationer.

den här artikeln är den första i en serie om SQL Server graph-databaser. Artikeln introducerar dig till grundläggande grafkoncept och visar hur du skapar och fyller i graftabeller med SQL Server Management Studio (SSMS) och en lokal instans av SQL Server 2017. I artiklarna som ska följas kommer vi att gräva i hur man frågar en grafdatabas och ändrar dess data, men för den här artikeln börjar vi med grunderna.

SQL Server Graph Database

SQL Servers grafdatabaser kan hjälpa till att förenkla processen för modellering av data som innehåller komplexa många-till-många och hierarkiska relationer. Som mest grundläggande är en grafdatabas en samling noder och kanter som arbetar tillsammans för att definiera olika typer av relationer. En nod är en enhet som en person eller plats. En kant är en relation mellan två enheter. Till exempel kan det finnas ett förhållande mellan en plats som Toledo och en person som heter Chris, som bor i Toledo. Chris och Toledo är enheterna, och’ bor i ’ är förhållandet mellan de två.

en nodtabell i SQL Server är en samling liknande enheter, och en kanttabell är en samling liknande relationer. För att förstå hur detta fungerar, överväga grafmodellen som visas i följande figur, som bygger på ett fiktivt fiskälskare forum. Modellen innehåller tre noder (FishSpecies, FishLover och FishPost) och tre kanter (Likes, Posts och LinksTo).

rektanglarna representerar noderna, och pilarna som förbinder noderna representerar kanterna, med pilarna som pekar i riktning mot förhållandet. Till exempel kan likes-kanterna definiera någon av följande relationer:

  • en fiskälskare gillar en fiskart.
  • en fiskälskare gillar ett inlägg om fisk.
  • en fiskälskare gillar en annan fiskälskare.

du kan representera alla tre relationer som data i en enda kanttabell i grafdatabasen, med varje relation i sin egen rad. En nodtabell fungerar ungefär på samma sätt, förutom att den innehåller en rad för varje enhet. Du kan också associera egenskaper med både noder och kanter. En egenskap är ett nyckelvärdeattribut som definieras som en kolumn i en nod eller kanttabell. Till exempel kan noden FishSpecies innehålla egenskaper för lagring av de gemensamma och vetenskapliga namnen på varje art. Egenskaperna skapas som användardefinierade kolumner i tabellen FishSpecies. När du skapar en nodtabell måste du inkludera minst en egenskap.

för de flesta operationer fungerar node-och edge-tabeller precis som alla andra SQL Server-användardefinierade tabeller. Även om det finns några begränsningar—som att inte kunna deklarera tillfälliga tabeller eller tabellvariabler som nod—eller kanttabeller-kommer du oftast att upptäcka att arbeta med graftabeller kommer att vara bekant territorium.

där saker blir lite oklara är med själva grafdatabasen. Även om namnet antyder att du skapar en ny typ av databasobjekt är det inte så. En grafdatabas är bara en logisk konstruktion definierad i en användardefinierad databas, som inte kan stödja mer än en grafdatabas. Förekomsten av grafdatabasen är relativt transparent från utsidan och är för det mesta inte något du behöver oroa dig för. När du arbetar med grafdatabaser kommer ditt primära fokus att ligga på graftabellerna och de data de innehåller.

i allmänhet ger en grafdatabas inga funktioner som du inte kan uppnå genom att använda traditionella relationella funktioner. Löftet om grafdatabasen ligger i att kunna organisera och fråga vissa typer av data mer effektivt. Microsoft rekommenderar att du överväger att implementera en grafdatabas under följande omständigheter:

  • du måste analysera mycket sammankopplade data och relationerna mellan dessa data.
  • du stöder data med komplexa många-till-många relationer som kontinuerligt utvecklas.
  • du arbetar med hierarkiska data medan du försöker navigera i begränsningarna för datatypen Hierarkiid.

SQL Servers grafdatabasfunktioner är helt integrerade i databasmotorn och utnyttjar sådana komponenter som frågeprocessorn och lagringsmotorn. På grund av denna integration kan du använda grafdatabaser tillsammans med ett brett utbud av komponenter, inklusive kolumnstore-index, Maskininlärningstjänster, SSMS och olika andra funktioner och verktyg.

definiera Grafnodtabeller

om du vill skapa en grafdatabas baserad på modellen som visas i föregående figur måste du skapa tre nodtabeller och tre kanttabeller. Microsoft har uppdaterat CREATE TABLE-satsen i SQL Server 2017 för att inkludera alternativ för att definiera endera tabelltypen. Som redan nämnts kan du skapa tabellerna i alla användardefinierade databaser. För exemplen i den här artikeln skapade jag en grundläggande databas med namnet FishGraph, som visas i följande T-SQL-kod:

1
2
3
4
5
6

använd master;
släpp databas om det finns FishGraph;
skapa databas FishGraph;

som ni ser är det inget speciellt som händer här. Du skapar databasen precis som alla andra användardefinierade databas. Det finns inget speciellt du behöver göra för att ställa in det för att stödja en grafdatabas.

om du planerar att prova dessa exempel själv kan du använda FishGraph-databasen eller en av dina egna val. Vad du än bestämmer är nästa steg att skapa Nodtabellen FishSpecies med hjälp av följande skapa TABELLUTTALANDE:

1
2
3
4
5
6
7
8
9

använd FishGraph;
släpp tabell om det finns FishSpecies;
Skapa tabell FishSpecies (
FISHID int identitet primärnyckel,
CommonName NVARCHAR(100) inte NULL,
Vetenskapligt namn nvarchar(100) inte null
) som nod;

kolumndefinitionerna bör vara ganska enkla. Det som är viktigt här är AS-nodklausulen, som du måste inkludera för att skapa en nodtabell. När du anger den här klausulen lägger databasmotorn till två kolumner i tabellen (som vi kommer till inom kort) och skapar ett unikt, icke-grupperat index på en av dessa kolumner.

du kan kontrollera om tabellen har skapats som en nodtabell genom att fråga sys.tabeller visa. Med utgåvan av SQL Server 2017 uppdaterade Microsoft vyn för att inkludera is_node-och is_edge-bitkolumnerna. Om tabellen är en nodtabell sätts kolumnvärdet is_node till 1 och kolumnvärdet is_edge till 0. Om en kant tabell, är värdena omvända. I följande exempel används vyn för att bekräfta att tabellen FishSpecies har definierats korrekt:

1
2

välj is_node, is_edge från sys.tabeller
där namn = ’fiskarter’;

select-satsen returnerar resultaten som visas i följande figur, vilket indikerar att FishSpecies skapades som en nodtabell.

Microsoft uppdaterade också sys.kolumnvy för att inkludera kolumnerna graph_type och graph_type_desc. Du kan använda kolumnerna visa och nya för att lära dig mer om tabellen fiskarter:

1
2
3

välj namn, graph_type, graph_type_desc
från sys.kolumner
där object_id = OBJECT_ID (’fiskarter’);

följande bild visar kolumnerna som skapats för tabellen FishSpecies.

när du skapar en nodtabell lägger databasmotorn till kolumnerna graph_id_<hex_string> och $node_id_<hex_string> och skapar ett unikt, icke-grupperat index i kolumnen $node_id. Databasmotorn använder den första kolumnen för interna operationer och gör den andra kolumnen tillgänglig för extern åtkomst. Kolumnen $ node_id lagrar en unik identifierare för varje enhet, som du kan visa när du frågar data. Detta är den enda kolumnen av de två du behöver vara bekymrad över. Faktum är att om du skulle fråga tabellen direkt skulle du bara se kolumnen $node_id, inte kolumnen graph_id.

kolumnerna graph_type och graph_type_desc returneras av sys.kolumnvyn är specifik för de automatiskt genererade kolumnerna i en graftabell. Kolumnerna anger vilka typer av kolumner som databasmotorn genererade. Typen indikeras av ett fördefinierat numeriskt värde och dess relaterade beskrivning. Microsoft ger inte mycket detaljer om dessa koder och beskrivningar, men du kan hitta några detaljer i Microsoft document SQL Graph Architecture. Återigen är ditt primära problem med kolumnen $ node_id och de data som den innehåller.

när du har skapat tabellen kan du börja lägga till data. Att köra ett INSERT-uttalande mot en nodtabell fungerar precis som alla andra tabeller. Du anger målkolumnerna och deras värden, som visas i följande exempel:

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’),
(’gädda, Esox lucius’),
(’Pacific herring’, ’Clupea pallasi’),
(’regnbåge’, ’Oncorhynchus mykiss’),
(’Sole (Dover)’, ’Solea solea’),
(’vit bas’, ’Morone chrysops’);

Naturligtvis kan du lägga till vilken fiskart du har en viss förkärlek för. Mina val här var helt godtyckliga. Men om du håller fast vid mina data och sedan frågar FishSpecies-tabellen, ska dina resultat likna dem i följande figur.

som nämnts ovan visas kolumnen graph_id inte i resultaten, men kolumnen $ node_id gör det, komplett med automatiskt genererade värden. Databasmotorn skapar varje värde som en JSON-sträng som ger typen (nod eller kant), schema, tabell och ett BIGINT-värde som är unikt för varje rad. Som förväntat returnerar databasmotorn också värdena i de användardefinierade kolumnerna, precis som en typisk relationstabell.

nästa steg är att skapa och fylla i FishLover-nodtabellen med följande T-SQL-kod:

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

släpp tabell om det finns FishLover;
Skapa tabell FishLover (
FishLoverID int identitet primärnyckel,
användarnamn Nvarchar (50) inte NULL,
) som nod;
infoga i FishLover (användarnamn) värden
(’powerangler’),
(’jessie98’),
(’hooked’),
(’deepdive’),
(’underwatercasey’);

tabellen innehåller bara två användardefinierade kolumner-FishLoverID och användarnamn—men du kan definiera så många kolumner som behövs. Du kanske till exempel vill inkludera för-och efternamn, kontaktinformation och andra detaljer, beroende på applikationens Art. När du har skapat tabellen kan du sedan köra en fråga för att verifiera data. Dina resultat ska se ut som de som visas i följande figur.

du kan sedan ta samma steg för att skapa och fylla i FishPost-tabellen och passera in vilken meddelandetext du vill:

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

släpp tabell om det finns FishPost;
Skapa tabell FishPost (
PostID int identitet primärnyckel,
Titel NVARCHAR(50) inte NULL,
MessageText NVARCHAR(800) inte NULL
) som nod;
infoga i fishpost (titel, MESSAGETEXT) värden
(’den som kom undan’, ’vårt team är tillgängligt, vänligen kontakta oss. Aeneas fördel reserverade behov.’),
(’en studie om fisk’, ’penatibus venenatis, nascetur ridiculus mus.’),
(’Krok, linje och sänke ’, ’Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.’),
(’så många fiskar, så lite tid’, ’ Nullam dictum felis eu pede mollis pretium. Heltal tincidunt.’),
(’min favorit fisk’, ’ Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.’);

följande bild visar de resultat du skulle se om du fastnat med Lorem Ipsum data.

det är allt som finns för att skapa och fylla i dina nodtabeller. Med undantag för AS-nodklausulen I Create TABLE-uttalandet är det mesta allt annat som vanligt.

definiera Grafkanttabeller

att skapa en kanttabell liknar att skapa en nodtabell förutom att du måste ange as EDGE-klausulen snarare än AS NODE-klausulen. Om du till exempel vill skapa tabellen inlägg använder du följande uttalande Skapa tabell:

1
2
3
4
5

släpp tabell om det finns inlägg;
skapa tabellposter (
Viktigflagbit inte NULL standard 0
) som Kant;

tabelldefinitionen liknar en nodtabell förutom att den inte innehåller en primär nyckelkolumn (och det tar naturligtvis as EDGE-klausulen). I det här fallet är en primärnyckel inte nödvändig, men om du någon gång bestämmer att du behöver en primärnyckel kan du säkert lägga till en. (Du kommer snart att se varför primärnycklar är användbara för nodtabellerna.)

Lägg märke till att tabelldefinitionen också innehåller kolumnen ImportantFlag. Jag inkluderade detta främst för att visa att du kan lägga till användardefinierade kolumner i ditt kantbord, precis som med nodtabeller. Med det sagt är det inte ovanligt att skapa ett kantbord utan användardefinierade kolumner, till skillnad från en nodtabell, som måste innehålla minst en användardefinierad kolumn.

när du har skapat edge-tabellen kan du verifiera att den har definierats korrekt genom att fråga sys.tabellvy, som du såg tidigare:

1
2

välj is_node, is_edge från sys.tabeller
där namn = ’inlägg’;

om du gjorde allt rätt ska dina resultat se ut som i följande figur.

du kan också fråga sys.tabellvy för att verifiera kolumninformation, precis som du gjorde tidigare:

1
2
3

välj namn, graph_type, graph_type_desc
från sys.kolumner
där object_id = OBJECT_ID (’inlägg’);

följande bild visar resultaten som returneras på mitt system.

som du kan se lägger databasmotorn åtta kolumner till en kanttabell, snarare än de två du såg med nodtabeller. Återigen, se SQL Graph Architecture-dokumentet för beskrivningar av varje kolumntyp. Att majoriteten av dessa kolumner används av databasmotorn för interna operationer. Du måste vara bekymrad främst med följande tre kolumner:

  • kolumnen $ edge_id_<hex_string> identifierar unikt varje relation.
  • kolumnen $from_id_<hex_string > lagrar värdet $node_id som är associerat med entiteten i tabellen där förhållandet har sitt ursprung.
  • kolumnen $to_id_<hex_string > lagrar värdet $node_id som är associerat med entiteten i tabellen där förhållandet avslutas.

som med kolumnen $node_id i en nodtabell genererar databasmotorn automatiskt värden för kolumnen $edge_id. Du måste dock specifikt lägga till värden i kolumnerna $from_id och $to_id för att definiera en relation. För att visa hur detta fungerar börjar vi med en enda post:

1
2
3

infoga i inlägg ($from_id, $ to_id) värden (
(välj $node_id från FishLover där FishLoverID = 1),
(välj $node_id från FishPost där PostID = 3));

INSERT-satsen definierar en relation i tabellen inlägg mellan en FishLover-enhet vars Fishlover-värde är 1 och en FishPost-enhet vars PostID-värde är 3. Observera att du kan använda aliaserna $node_id, $from_id och $to_id för att referera till målkolumnerna utan att behöva komma med hex-strängarna.

för att lägga till data i kolumnen $from_id måste du ange värdet $node_id som är associerat med FishLover-enheten. Ett sätt att få detta värde är att inkludera en underfråga som riktar sig till enheten med hjälp av dess primära nyckelvärde. Du kan ta samma tillvägagångssätt för kolumnen $from_id.

infoga data på detta sätt visar varför det är användbart att lägga till primärnycklar i nodtabellerna, men inte nödvändigt för kanttabellerna. De primära tangenterna på nodtabellerna gör det mycket lättare att ange värdet $node_id till INSERT-satsen.

om du nu söker i tabellen inlägg ska dina resultat likna de som visas i följande figur.

tabellen ska innehålla den nya relationen, med ImportantFlag inställd på 0, standard. Du kan nu lägga till några fler rader med följande infoga satser:

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

infoga i inlägg ($from_id, $ to_id) värden (
(välj $node_id från FishLover där FishLoverID = 3),
(välj $node_id från FishPost där PostID = 2));
infoga i inlägg ($from_id, $ to_id) värden (
(välj $node_id från FishLover där FishLoverID = 2),
(välj $node_id från FishPost där PostID = 5));
infoga i inlägg ($from_id, $ to_id, ImportantFlag) värden (
(välj $node_id från FishLover där FishLoverID = 5),
(välj $node_id från FishPost där PostID = 4), 1);
infoga i inlägg ($from_id, $ to_id, ImportantFlag) värden (
(välj $node_id från FishLover där FishLoverID = 4),
(välj $node_id från FishPost där PostID = 1), 1);

Lägg märke till att de två sista insert-satserna också ger ett värde för kolumnen ImportantFlag. När du frågar tabellen inlägg ska dina resultat nu innehålla alla fem raderna.

nästa steg är att skapa och fylla i Likes-tabellen med följande T-SQL-kod:

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

släpp tabell om det finns gillar;
Skapa tabell Gillar som Kant;
infoga i Gillar ($from_id, $to_id) värden (
(välj $node_id från FishLover där FishLoverID = 3),
(välj $node_id från FishSpecies där FishID = 8));
infoga i Likes ($from_id, $to_id) värden (
(välj $node_id från FishLover där FishLoverID = 5),
(välj $node_id från FishPost där PostID = 4));
infoga i Likes ($from_id, $ to_id) värden (
(välj $node_id från FishLover där FishLoverID = 1),
(välj $node_id från FishLover där FishLoverID = 4));

du kan, självklart, definiera alla relationer du vill ha. Den viktiga punkten att märka här är att du inte är begränsad till någon uppsättning noder. Till exempel skapar det första INSERT-uttalandet en relation mellan FishLover och FishSpecies, det andra uttalandet skapar en relation mellan FishLover och FishPost, och det tredje uttalandet skapar en relation mellan FishLover och FishLover. Detta ger oss frågeresultaten som visas i följande figur.

du kan ta samma tillvägagångssätt när du skapar och fyller i linksto-tabellen:

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

släpp tabell om det finns LinksTo;
Skapa tabell LinksTo som Kant;
infoga i LinksTo ($from_id, $to_id) värden (
(välj $node_id från FishPost där PostID = 2),
(välj $node_id från FishSpecies där FishID = 6));
infoga i LinksTo ($from_id, $to_id) värden (
(välj $node_id från FishPost där PostID = 4),
(välj $node_id från FishLover där FishLoverID = 1));
infoga i LinksTo ($from_id, $to_id) värden (
(välj $node_id från FishPost där PostID = 3),
(välj $node_id från FishPost där PostID = 5));

följande bild visar hur data ska se ut efter att ha lagts till i tabellen, förutsatt att du följde exemplet.

med en grafdatabas kan du lägga till ett brett spektrum av relationer mellan ursprung och avslutande noder. Du kan också enkelt införliva ändringar i grafmodellen. Du kan till exempel välja att lägga till en FishRecipes-nodtabell för att lagra de fiskrecept som användarna lägger upp i forumet, i vilket fall kan du utnyttja befintliga inlägg, gillar och länkar till kanttabeller.

gå vidare med grafdatabaser

eftersom Microsoft innehåller grafdatabasfunktionerna som en del av SQL Server-databasmotorn kan du enkelt prova dem utan att behöva installera eller konfigurera om några komponenter. Bäst av allt kan du använda samma verktyg och procedurer som du har använt hela tiden för att skapa och fylla i nod-och kantbord. I artiklarna som ska följas täcker vi hur du frågar och ändrar grafdata och tittar närmare på att arbeta med hierarkiska data, så var noga med att hålla dig uppdaterad.

Lämna ett svar

Din e-postadress kommer inte publiceras.