De serie zo ver:

  1. SQL Server Graph Databases – Deel 1: Inleiding
  2. SQL Server Graph Databases – Deel 2: het Opvragen van Gegevens in een Grafiek Database
  3. SQL Server Graph Databases – Deel 3: het Wijzigen van Gegevens in een Grafiek Database
  4. SQL Server Graph Databases – Deel 4: Werken met hiërarchische gegevens in een grafiek database
  5. SQL Server Graph Databases – Deel 5: Relationele gegevens importeren in een Graph Database

met de release van SQL Server 2017 heeft Microsoft Ondersteuning toegevoegd voor graph databases om beter om te gaan met datasets die complexe entiteitsrelaties bevatten, zoals het type gegevens dat wordt gegenereerd door een social media site, waar u een mix van vele-tot-vele relaties kunt hebben die vaak veranderen. Graph databases gebruiken dezelfde tabelstructuren in traditionele SQL Server databases en ondersteunen dezelfde tools en T-SQL statements, maar ze bevatten ook functies voor het opslaan en navigeren van complexe relaties.

dit artikel is het eerste in een reeks over SQL Server graph databases. Het artikel introduceert u fundamentele grafiekconcepten en laat zien hoe u grafiektabellen kunt maken en bevolken met behulp van SQL Server Management Studio (SSMS) en een lokale instantie van SQL Server 2017. In de artikelen te volgen, we zullen graven in hoe je een grafiek database query en de gegevens te wijzigen, maar voor dit artikel, we beginnen met de basis.

de grafiekendatabase van SQL Server

de grafiekendatabases van SQL Server kunnen helpen bij het vereenvoudigen van het modelleren van gegevens die complexe veel-tot-veel en hiërarchische relaties bevatten. Op zijn meest basale, een grafiek database is een verzameling van knooppunten en randen die samenwerken om verschillende soorten relaties te definiëren. Een knooppunt is een entiteit zoals een persoon of locatie. Een rand is een relatie tussen twee entiteiten. Bijvoorbeeld, een relatie zou kunnen bestaan tussen een locatie zoals Toledo en een persoon genaamd Chris, die woont in Toledo. Chris en Toledo zijn de entiteiten, en ‘woont in’ is de relatie tussen de twee.

een knooppunttabel in SQL Server is een verzameling van soortgelijke entiteiten, en een randtabel is een verzameling van soortgelijke relaties. Om te helpen begrijpen hoe dit werkt, overwegen de grafiek model weergegeven in de volgende figuur, die is gebaseerd op een fictieve fish-lovers forum. Het model bevat drie knooppunten (FishSpecies, FishLover, en FishPost) en drie randen (Likes, berichten, en LinksTo).

de rechthoeken vertegenwoordigen de knopen, en de pijlen die de knopen verbinden vertegenwoordigen de randen, met de pijlen die in de richting van de relatie wijzen. Bijvoorbeeld, de Likes randen kunnen een van de volgende relaties definiëren:

  • een visliefhebber houdt van een vissoort.
  • een visliefhebber houdt van een artikel over vis.
  • een visliefhebber houdt van een andere visliefhebber.

u kunt alle drie de relaties weergeven als gegevens in een enkele randtabel in de grafiekendatabase, met elke relatie in zijn eigen rij. Een node tabel werkt ongeveer op dezelfde manier, behalve dat het een rij voor elke entiteit bevat. U kunt ook eigenschappen koppelen aan zowel knooppunten als Randen. Een eigenschap is een sleutelwaarde-attribuut dat wordt gedefinieerd als een kolom in een knooppunt-of randtabel. Bijvoorbeeld, de FishSpecies knooppunt kan eigenschappen bevatten voor het opslaan van de gemeenschappelijke en wetenschappelijke namen van elke soort. De eigenschappen worden gemaakt als door de gebruiker gedefinieerde kolommen in de FishSpecies tabel. Wanneer u een knooppuntentabel maakt, moet u ten minste één eigenschap opnemen.

voor de meeste bewerkingen werken knooppunt-en randtabellen net als elke andere door de gebruiker gedefinieerde SQL Server-tabel. Hoewel er een paar beperkingen zijn—zoals het niet kunnen declareren van tijdelijke tabellen of tabelvariabelen als knooppunt—of randtabellen-zul je meestal merken dat het werken met grafiektabellen vertrouwd gebied zal zijn.

waar dingen een beetje onduidelijk worden is met de graph database zelf. Hoewel de naam zou kunnen suggereren dat u een nieuw type database object aan het maken bent, is dat niet het geval. Een grafiekdatabase is slechts een logische constructie gedefinieerd binnen een door de gebruiker gedefinieerde database, die niet meer dan één grafiekdatabase kan ondersteunen. Het bestaan van de grafiek database is relatief transparant van buitenaf en, voor het grootste deel, is niet iets waar je je zorgen over hoeft te maken. Bij het werken met graph databases, uw primaire focus zal zijn op de grafiektabellen en de gegevens die ze bevatten.

in het algemeen biedt een grafiekendatabase geen mogelijkheden die u niet kunt bereiken met behulp van traditionele relationele functies. De belofte van de grafiek database ligt in de mogelijkheid om te organiseren en query bepaalde soorten gegevens efficiënter. Microsoft raadt u aan om in de volgende omstandigheden een grafiekdatabase te implementeren:

  • je moet zeer onderling verbonden gegevens analyseren en de relaties tussen die gegevens.
  • u ondersteunt gegevens met complexe veel-tot-veel relaties die voortdurend evolueren.
  • u werkt met hiërarchische gegevens, terwijl u probeert door de beperkingen van het Hiërarchyid-gegevenstype te navigeren.

SQL Server ‘ s graph database features zijn volledig geïntegreerd in de database engine, gebruik makend van componenten zoals de query processor en storage engine. Vanwege deze integratie kunt u grafiekdatabases gebruiken in combinatie met een breed scala aan componenten, waaronder columnstore-indexen, Machine Learning-diensten, SSM ‘ s en diverse andere functies en hulpmiddelen.

defining Graph Node Tables

om een grafiekdatabase te maken op basis van het model in de vorige figuur, moet u drie knooppunttabellen en drie randtabellen maken. Microsoft heeft het statement tabel maken in SQL Server 2017 bijgewerkt om opties op te nemen voor het definiëren van een van beide tabeltypen. Zoals reeds opgemerkt, kunt u de tabellen maken in alle door de gebruiker gedefinieerde databases. Voor de voorbeelden in dit artikel heb ik een basisdatabase aangemaakt met de naam FishGraph, zoals weergegeven in de volgende T-SQL code:

1
2
3
4
5
6

gebruik master;
GO
DROP-DATABASE indien aanwezig FishGraph;
GO
DATABASE aanmaken FishGraph;
GO

zoals je kunt zien, is er hier niets bijzonders aan de hand. U maakt de database net als elke andere door de gebruiker gedefinieerde database. Er is niets speciaals wat je hoeft te doen om het op te zetten om een grafiek database te ondersteunen.

als u van plan bent deze voorbeelden zelf uit te proberen, kunt u gebruik maken van de FishGraph database of een van uw eigen keuze. Wat u ook beslist, de volgende stap is om de FishSpecies node table te maken, met behulp van de volgende CREATE TABLE statement:

1
2
3
4
5
6
7
8
9

GEBRUIK FishGraph;
NAAR
DROP TABLE INDIEN AANWEZIG FishSpecies;
NAAR
CREATE TABLE FishSpecies (
FishID INT IDENTITEIT PRIMAIRE SLEUTEL,
CommonName NVARCHAR(100) not NULL,
ScientificName NVARCHAR(100) not NULL
) ALS KNOOPPUNT;

de definities van de kolommen moeten vrij eenvoudig zijn. Wat hier belangrijk is, is de als knooppunt clausule, die je moet opnemen om een knooppunttabel te maken. Wanneer u deze clausule opgeeft, voegt de database-engine twee kolommen toe aan de tabel (waar we binnenkort aan zullen komen) en creëert een unieke, niet-geclusterde index op een van die kolommen.

u kunt controleren of de tabel is gemaakt als een knooppunttabel door het systeem te bevragen.tafels bekijken. Met de release van SQL Server 2017 heeft Microsoft de weergave bijgewerkt om de is_node-en is_edge-bitkolommen op te nemen. Als de tabel een knooppunttabel is, is de kolomwaarde is_node ingesteld op 1 en de kolomwaarde is_edge ingesteld op 0. Bij een randtabel worden de waarden omgekeerd. Het volgende voorbeeld gebruikt de view om te bevestigen dat de tabel met vissoorten correct is gedefinieerd:

1
2

selecteer is_node, is_edge uit sys.tabellen
waarbij naam = “Visspecies”;

de SELECT statement retourneert de resultaten in de volgende figuur, die aangeven dat vissoorten is gemaakt als een knooppunt tabel.

Microsoft heeft ook de sys bijgewerkt.kolommen weergave om de graph_type en graph_type_desc kolommen op te nemen. U kunt de view en nieuwe kolommen gebruiken om meer te weten te komen over de tabel vissoorten:

1
2
3

selecteer name, graph_type, graph_type_desc
uit sys.kolommen
waarbij object_id = OBJECT_ID (‘Visspecies’);

de volgende figuur toont de kolommen gemaakt voor de vissoorten tabel.

wanneer u een knooppunttabel maakt, voegt de database-engine de kolommen graph_id_<hex_string> en $node_id_<hex_string> toe en maakt een unieke, niet-geclusterde index aan op de kolom $node_id. De database-engine gebruikt de eerste kolom voor interne bewerkingen en maakt de tweede kolom beschikbaar voor externe toegang. De kolom $node_id slaat een unieke identifier op voor elke entiteit, die u kunt bekijken bij het opvragen van de gegevens. Dit is de enige kolom van de twee waar je je zorgen over moet maken. In feite, als je de tabel direct zou opvragen, zou je alleen de kolom $node_id zien, niet de kolom graph_id.

de kolommen graph_type en graph_type_desc die door het systeem worden geretourneerd.de kolomweergave is specifiek voor de automatisch gegenereerde kolommen in een grafiektabel. De kolommen geven de typen kolommen aan die door de database-engine zijn gegenereerd. Het type wordt aangegeven door een vooraf gedefinieerde numerieke waarde en de bijbehorende beschrijving. Microsoft biedt niet veel details over deze codes en beschrijvingen, maar u kunt enkele details vinden in de Microsoft document SQL Graph Architecture. Nogmaals, uw primaire zorg is met de $ node_id kolom en de gegevens die het bevat.

nadat u uw tabel hebt aangemaakt, kunt u beginnen met het toevoegen van gegevens. Het uitvoeren van een INSERT statement tegen een knooppunttabel werkt net als elke andere tabel. U specificeert de doelkolommen en hun waarden, zoals getoond in het volgende voorbeeld:

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’),
(‘Noord-snoek’, ‘Esox lucius’),
(‘Pacifische haring’, ‘Clupea pallasi’),
(‘regenboogforel’, ‘Oncorhynchus mykiss’),
(‘Enige (Dover)’, ‘Solea solea’),
(‘Witte bass’, ‘Morone chrysops’);

natuurlijk kunt u toevoegen wat vissen hebben een voorliefde voor. Mijn keuzes waren volkomen willekeurig. Maar als je vasthouden aan mijn gegevens en vervolgens vraag de vissoorten tabel, uw resultaten moeten lijken op die in de volgende figuur.

zoals hierboven vermeld, wordt de kolom graph_id niet weergegeven in de resultaten, maar de kolom $node_id wel, compleet met automatisch gegenereerde waarden. De database-engine creëert elke waarde als een JSON-tekenreeks die het type (knooppunt of rand), schema, tabel en een BIGINT-waarde biedt die uniek is voor elke rij. Zoals verwacht retourneert de database-engine ook de waarden in de door de gebruiker gedefinieerde kolommen, net als een typische relationele tabel.

de volgende stap is het aanmaken en bevolken van de FishLover node tabel, met behulp van de volgende T-SQL code:

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

DROP TABLE INDIEN AANWEZIG FishLover;
NAAR
CREATE TABLE FishLover (
FishLoverID INT IDENTITEIT PRIMAIRE SLEUTEL,
Gebruikersnaam NVARCHAR(50) not NULL,
) ALS KNOOPPUNT;
INVOEGEN IN FishLover (Gebruikersnaam) WAARDEN
(‘powerangler’),
(‘jessie98’),
(‘verslaafd’),
(‘deepdive’),
(‘underwatercasey’);

De tabel bevat alleen de twee door de gebruiker gedefinieerde kolommen—FishLoverID en Gebruikersnaam, maar u kunt definiëren zoveel kolommen als dat nodig is. U kunt bijvoorbeeld voor-en achternaam, contactgegevens en andere gegevens toevoegen, afhankelijk van de aard van de toepassing. Zodra u de tabel hebt gemaakt, kunt u vervolgens een query uitvoeren om de gegevens te verifiëren. Uw resultaten moeten lijken op die in de volgende figuur.

vervolgens kunt U dezelfde stappen voor het maken en vullen van de FishPost tabel doorgeven in welke tekst u wenst:

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

DROP TABLE INDIEN AANWEZIG FishPost;
GO
CREATE TABLE FishPost (
POSTID int IDENTITY PRIMARY KEY,
Title NVARCHAR(50) NOT NULL,
MessageText nvarchar(800) NOT NULL
) AS NODE;
INSERT INTO FishPost (Title, MessageText) VALUES
(’the one that got away’, ‘ons team is beschikbaar, neem contact met ons op. Aeneas voordeel voorbehouden behoeften.’),
(‘A study on fish’, ‘ penatibus venenatis, nascetur ridiculus mus.’),
(‘haak, lijn en zinklood”, ” Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.’),
(‘zo veel vissen, zo weinig tijd”, ” Nullam dictum felis eu pede mollis pretium. Integer tincidunt.’),
(‘Mijn favoriete vis’, ‘ Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.’);

de volgende figuur toont de resultaten die je zou zien als je geplakt met de Lorem Ipsum gegevens.

dat is alles wat er is om het creëren en bevolken van uw knooppunt tabellen. Met uitzondering van de as NODE clausule in het CREATE TABLE statement, is de meeste rest business as usual.

het definiëren van Grafiekrandtabellen

het maken van een randtabel is vergelijkbaar met het maken van een knooppunttabel, behalve dat u de als Rand-clausule moet specificeren in plaats van de als-knooppunt-clausule. Bijvoorbeeld, om de Posts tabel te maken, gebruikt u het volgende CREATE TABLE statement:

1
2
3
4
5

DROP TABLE als er berichten zijn;
GO
TABELPOSTEN aanmaken (
ImportantFlag BIT NOT NULL standaard 0
) als Rand;

de tabeldefinitie is vergelijkbaar met een knooppunttabel, behalve dat het geen primaire sleutelkolom bevat (en, natuurlijk, het neemt de as EDGE clausule). In dit geval is een primaire sleutel niet nodig, maar als u op een bepaald moment vaststelt dat u een primaire sleutel nodig hebt, kunt u er zeker een toevoegen. (Je zult kort zien waarom primaire sleutels nuttig zijn voor de knooppunttabellen.)

merk op dat in de definitie van de tabel ook de kolom met belangrijke cijfers is opgenomen. Ik heb dit in de eerste plaats opgenomen om aan te tonen dat u door de gebruiker gedefinieerde kolommen aan uw randtabel kunt toevoegen, net als bij knooppunttabellen. Dat gezegd hebbende, het is niet ongewoon om een rand tabel zonder door de gebruiker gedefinieerde kolommen te maken, in tegenstelling tot een knooppunt tabel, die ten minste één door de gebruiker gedefinieerde kolom moet bevatten.

na het maken van de randtabel, kunt u controleren of deze correct is gedefinieerd door het systeem te bevragen.tabellen bekijken, zoals je eerder zag:

1
2

selecteer is_node, is_edge uit sys.tabellen
waar Naam = “posten’;

als je alles goed hebt gedaan, moeten je resultaten eruit zien als die in de volgende figuur.

u kunt ook de sys opvragen.tabelsweergave om kolomdetails te verifiëren, net als voorheen:

1
2
3

selecteer name, graph_type, graph_type_desc
uit sys.kolommen
waarbij object_id = OBJECT_ID (‘Posts’);

de volgende figuur toont de resultaten terug op mijn systeem.

zoals u kunt zien, voegt de database-engine acht kolommen toe aan een randtabel, in plaats van de twee die u zag met knooppunttabellen. Nogmaals, refereer naar het sql Graph Architecture document voor beschrijvingen van elk kolomtype. Die meerderheid van deze kolommen worden gebruikt door de database engine voor interne operaties. U moet zich vooral zorgen maken over de volgende drie kolommen:

  • de kolom $edge_id_<hex_string> identificeert elke relatie uniek.
  • de kolom $from_id_<hex_string> slaat de waarde $node_id op die geassocieerd is met de entiteit in de tabel waar de relatie vandaan komt.
  • de kolom $to_id_<hex_string> slaat de waarde $node_id op die geassocieerd is met de entiteit in de tabel waar de relatie eindigt.

net als bij de kolom $node_id in een knooppunttabel, genereert de database-engine automatisch waarden voor de kolom $edge_id. U moet echter specifiek waarden toevoegen aan de kolommen $from_id en $to_id om een relatie te definiëren. Om te laten zien hoe dit werkt, beginnen we met een enkel record:

1
2
3

INVOEGEN IN Berichten ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 1),
(SELECTEER $node_id VAN FishPost WAAR PostID = 3));

De instructie INSERT is de definitie van een relatie in de Berichten tabel tussen een FishLover entiteit waarvan de FishLoverID waarde 1 en een FishPost entiteit waarvan de PostID waarde is 3. Merk op dat je de aliassen $node_id, $from_id en $to_id kunt gebruiken om de doelkolommen te refereren, zonder dat je de hex strings hoeft te gebruiken.

om gegevens toe te voegen aan de kolom $from_id, moet u de waarde $node_id opgeven die geassocieerd is met de FishLover-entiteit. Een manier om deze waarde te krijgen is om een subquery op te nemen die de entiteit richt, met behulp van de primaire sleutelwaarde. Je kunt dezelfde aanpak gebruiken voor de $ from_id kolom.

het op deze manier invoegen van de gegevens laat zien waarom het nuttig is om primaire sleutels toe te voegen aan de knooppunttabellen, maar niet noodzakelijk voor de randtabellen. De primaire sleutels op de knooppunttabellen maken het veel gemakkelijker om de waarde $node_id aan het INSERT statement te geven.

als u nu de Postentabel opvraagt, moeten uw resultaten er vergelijkbaar uitzien met die in de volgende figuur.

de tabel moet de nieuwe relatie bevatten, met de ImportantFlag ingesteld op 0, de standaard. U kunt nu nog een paar rijen toevoegen met behulp van de volgende INSERT statements:

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

INVOEGEN IN Berichten ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 3),
(SELECTEER $node_id VAN FishPost WAAR PostID = 2));
INVOEGEN IN Berichten ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 2),
(SELECTEER $node_id VAN FishPost WAAR PostID = 5));
INVOEGEN IN Berichten ($from_id, $to_id, ImportantFlag) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 5),
(SELECTEER $node_id VAN FishPost WAAR PostID = 4), 1);
INSERT INTO Posts ($from_id, $to_id, ImportantFlag) VALUES (
(SELECT $node_id FROM FishLover WHERE FishLoverID = 4),
(selecteer $node_id van FishPost waar PostID = 1), 1);

merk op dat de laatste twee INSERT statements ook een waarde bieden voor de ImportantFlag-kolom. Wanneer u de Posts-tabel opvraagt, moeten uw resultaten nu alle vijf rijen bevatten.

de volgende stap is het maken en bevolken van de Likes tabel, met behulp van de volgende T-SQL code:

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

DROP TABLE INDIEN AANWEZIG Graag;
NAAR
CREATE TABLE Graag ALS RAND;
INVOEGEN IN Wil ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 3),
(SELECTEER $node_id VAN FishSpecies WAAR FishID = 8));
INVOEGEN IN Wil ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 5),
(SELECTEER $node_id VAN FishPost WAAR PostID = 4));
INVOEGEN van Houdt ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishLover WAAR FishLoverID = 1),
(SELECTEER $node_id VAN FishLover WAAR FishLoverID = 4));

U kunt, natuurlijk, het definiëren van de relaties die u wilt. Het belangrijke punt om hier op te merken is dat je niet beperkt bent tot een set van knooppunten. Bijvoorbeeld, de eerste INSERT statement creëert een relatie tussen FishLover en vissoorten, de tweede statement creëert een relatie tussen FishLover en FishPost, en de derde statement creëert een relatie tussen FishLover en FishLover. Dit geeft ons de zoekresultaten weergegeven in de volgende figuur.

u kunt dezelfde aanpak volgen bij het maken en vullen van de LinksTo-tabel:

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

DROP TABLE INDIEN AANWEZIG LinksTo;
NAAR
CREATE TABLE LinksTo ALS RAND;
INVOEGEN IN LinksTo ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishPost WAAR PostID = 2),
(SELECTEER $node_id VAN FishSpecies WAAR FishID = 6));
INVOEGEN IN LinksTo ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishPost WAAR PostID = 4),
(SELECTEER $node_id VAN FishLover WAAR FishLoverID = 1));
PLAATS IN LinksTo ($from_id, $to_id) WAARDEN (
(SELECT $node_id VAN FishPost WAAR PostID = 3),
(SELECTEER $node_id VAN FishPost WAAR PostID = 5));

De volgende figuur laat zien hoe de gegevens eruit moeten zien na wordt toegevoegd aan de tabel, in de veronderstelling dat je volgde het voorbeeld.

met een grafiekdatabase kunt u een breed scala aan relaties tussen oorspronkelijke en terminerende knooppunten toevoegen. U kunt ook gemakkelijk wijzigingen in de grafiek model. Bijvoorbeeld, je zou kunnen besluiten om een FishRecipes knooppunt tabel toe te voegen voor het opslaan van de vis recepten die gebruikers posten op het forum, in welk geval, kunt u gebruik maken van de bestaande berichten, Likes, en LinksTo edge tabellen.

verder gaan met Graph Databases

omdat Microsoft de graph database functies bevat als onderdeel van de SQL Server database engine, kunt u ze eenvoudig uitproberen zonder componenten te hoeven installeren of opnieuw te configureren. Het beste van alles is dat u dezelfde tools en procedures kunt gebruiken die u de hele tijd hebt gebruikt om knooppunt-en randtabellen te maken en te vullen. In de artikelen die volgen, zullen we behandelen hoe u grafiekgegevens kunt opvragen en wijzigen en een kijkje nemen op het werken met hiërarchische gegevens, dus zorg ervoor dat u op de hoogte blijft.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.