serien indtil videre:

  1. Servergrafdatabaser-Del 1: Introduktion
  2. kvm-Servergrafdatabaser-Del 2: forespørgsel på Data i en grafdatabase
  3. kvm-Servergrafdatabaser-Del 3: Ændring af Data i en grafdatabase
  4. kvm-Servergrafdatabaser-Del 4: Arbejde med hierarkiske data i en grafdatabase
  5. kvm-Servergrafdatabaser – del 5: Import af relationsdata til en grafdatabase

med udgivelsen af graph-Databaser 2017 tilføjede Microsoft understøttelse af graph-Databaser for bedre at håndtere datasæt, der indeholder komplekse enhedsrelationer, f.eks. typen af data, der genereres af et socialt medieside, hvor du kan have en blanding af mange til mange relationer, der ændres ofte. Grafdatabaser bruger de samme tabelstrukturer, der findes i traditionelle DATABASESERVERDATABASER og understøtter de samme værktøjer og T-SKL-udsagn, men de inkluderer også funktioner til lagring og navigering af komplekse relationer.

denne artikel er den første i en serie om Servergrafdatabaser. Artiklen introducerer dig til grundlæggende grafkoncepter og viser, hvordan du opretter og udfylder graftabeller ved hjælp af SSMS (SSMS) og en lokal forekomst af Server 2017. I de artikler, der skal følges, undersøger vi, hvordan du forespørger en grafdatabase og ændrer dens data, men for denne artikel starter vi med det grundlæggende.

GRAFDATABASEN

grafdatabaser kan hjælpe med at forenkle processen med modellering af data, der indeholder komplekse mange-til-mange og hierarkiske relationer. På det mest grundlæggende er en grafdatabase en samling af noder og kanter, der arbejder sammen for at definere forskellige typer relationer. En node er en enhed som en person eller et sted. En kant er et forhold mellem to enheder. For eksempel, et forhold kan eksistere mellem et sted som Toledo og en person ved navn Chris, der bor i Toledo. Chris og Toledo er enhederne, og’ lives in ‘ er forholdet mellem de to.

en node-tabel er en samling af lignende enheder, og en edge-tabel er en samling af lignende relationer. For at hjælpe med at forstå, hvordan dette fungerer, skal du overveje grafmodellen vist i den følgende figur, som er baseret på et fiktivt forum for fiskelskere. Modellen indeholder tre noder (FishSpecies, Fishloverog FishPost) og tre kanter (Likes, Indlægog LinksTo).

rektanglerne repræsenterer knudepunkterne, og pilene, der forbinder knudepunkterne, repræsenterer kanterne, hvor pilene peger i retning af forholdet. For eksempel kan Likes-kanterne definere et af følgende forhold:

  • en fisk elsker kan lide en fiskeart.
  • en fisk elsker kan lide et indlæg om fisk.
  • en fisk elsker kan lide en anden fisk elsker.

du kan repræsentere alle tre relationer som data i en enkelt kanttabel i grafdatabasen med hver relation i sin egen række. En nodetabel fungerer meget på samme måde, bortset fra at den indeholder en række for hver enhed. Du kan også knytte egenskaber til både noder og kanter. En egenskab er en nøgle-værdi attribut, der er defineret som en kolonne i en node eller kant tabel. For eksempel kan FishSpecies node omfatte egenskaber til opbevaring af de fælles og videnskabelige navne på hver art. Egenskaberne oprettes som brugerdefinerede kolonner i tabellen fiskearter. Når du opretter en node-tabel, skal du medtage mindst en egenskab.

for de fleste operationer fungerer node-og edge-tabeller ligesom enhver anden brugerdefineret tabel. Selvom der er et par begrænsninger—såsom ikke at være i stand til at erklære midlertidige tabeller eller tabelvariabler som node—eller kanttabeller-finder du det meste af tiden, at arbejde med graftabeller vil være velkendt område.

hvor tingene bliver lidt uklare er med grafdatabasen selv. Selvom navnet måske antyder, at du opretter en ny type databaseobjekt, er det ikke tilfældet. En grafdatabase er blot en logisk konstruktion defineret i en brugerdefineret database, som ikke kan understøtte mere end en grafdatabase. Eksistensen af grafdatabasen er relativt gennemsigtig udefra og er for det meste ikke noget, du skal være bekymret for. Når du arbejder med grafdatabaser, vil dit primære fokus være på graftabellerne og de data, de indeholder.

generelt giver en grafdatabase ingen funktioner, som du ikke kan opnå ved hjælp af traditionelle relationelle funktioner. Løftet om grafdatabasen ligger i at være i stand til at organisere og forespørge bestemte typer data mere effektivt. Microsoft anbefaler, at du overvejer at implementere en grafdatabase under følgende omstændigheder:

  • du skal analysere stærkt sammenkoblede data og forholdet mellem disse data.
  • du understøtter data med komplekse mange-til-mange relationer, der konstant udvikler sig.
  • du arbejder med hierarkiske data, mens du forsøger at navigere i begrænsningerne for Hierarkiiddatatypen.

serverens grafdatabasefunktioner er fuldt integreret i databasemotoren og udnytter komponenter som forespørgselsprocessoren og lagringsmotoren. På grund af denne integration kan du bruge grafdatabaser sammen med en lang række komponenter, herunder columnstore-indekser, Maskinlæringstjenester, SSM ‘ er og forskellige andre funktioner og værktøjer.

definition af Grafnodetabeller

for at oprette en grafdatabase baseret på modellen vist i den foregående figur skal du oprette tre knudetabeller og tre kanttabeller. Microsoft har opdateret sætningen Opret tabel i Server 2017 for at inkludere muligheder for at definere begge tabeltyper. Som allerede nævnt kan du oprette tabellerne i alle brugerdefinerede databaser. For eksemplerne i denne artikel, Jeg oprettede en grundlæggende database med navnet FishGraph, som vist i den følgende kode:

1
2
3
4
5
6

brug master;
DROP DATABASE, hvis der findes FishGraph;
Opret DATABASE FishGraph;

som du kan se, sker der ikke noget særligt her. Du opretter databasen ligesom enhver anden brugerdefineret database. Der er ikke noget særligt, du skal gøre for at konfigurere det til at understøtte en grafdatabase.

hvis du planlægger at prøve disse eksempler for dig selv, kan du bruge FishGraph-databasen eller et af dine egne valg. Uanset hvad du beslutter, er det næste trin at oprette FishSpecies node-tabellen ved hjælp af følgende Opret TABELOPGØRELSE:

1
2
3
4
5
6
7
8
9

brug FishGraph;
DROP TABLE hvis der findes fiskearter;
Opret tabel fiskearter (
FishID int IDENTITY PRIMARY KEY,
CommonName NVARCHAR(100) IKKE NULL,
SCIENTIFICNAME Nvarchar(100) ikke null
) som node;

kolonnedefinitionerne skal være ret ligetil. Hvad der er vigtigt her er as NODE-klausulen, som du skal medtage for at oprette en node-tabel. Når du angiver denne klausul, tilføjer databasemotoren to kolonner til tabellen (som vi snart kommer til) og opretter et unikt, ikke-grupperet indeks på en af disse kolonner.

du kan kontrollere, om tabellen er oprettet som en nodetabel ved at forespørge sys.tabeller se. Med udgivelsen af Server 2017 opdaterede Microsoft visningen for at inkludere is_node-og is_edge-bitkolonnerne. Hvis tabellen er en node-tabel, er værdien is_node-kolonne indstillet til 1, og værdien is_edge-kolonne er indstillet til 0. Hvis en kanttabel, vendes værdierne. Følgende eksempel bruger visningen til at bekræfte, at tabellen fiskearter er defineret korrekt:

1
2

vælg is_node, is_edge fra sys.tabeller
hvor navn = ‘fiskearter’;

SELECT-sætningen returnerer resultaterne vist i følgende figur, som angiver, at fiskearter blev oprettet som en nodetabel.

Microsoft opdaterede også sys.kolonnevisning for at inkludere kolonnerne graph_type og graph_type_desc. Du kan bruge visningen og de nye kolonner til at lære mere om tabellen fiskearter:

1
2
3

Vælg navn, graph_type, graph_type_desc
fra sys.kolonner
hvor object_id = OBJECT_ID (‘fiskearter’);

følgende figur viser de kolonner, der er oprettet til tabellen fiskearter.

når du opretter en nodetabel, tilføjer databasemotoren kolonnerne graph_id_<heks_string> og $node_id_<heks_string> og opretter et unikt, ikke-grupperet indeks på kolonnen $node_id. Databasemotoren bruger den første kolonne til interne operationer og gør den anden kolonne tilgængelig for ekstern adgang. Kolonnen $ node_id gemmer en unik identifikator for hver enhed, som du kan se, når du spørger dataene. Dette er den eneste kolonne af de to, du skal være bekymret for. Faktisk, hvis du skulle forespørge tabellen direkte, ville du kun se kolonnen $node_id, ikke kolonnen graph_id.

kolonnerne graph_type og graph_type_desc returneres af sys.kolonnevisning er specifik for de automatisk genererede kolonner i en graftabel. Kolonnerne angiver de typer kolonner, som databasemotoren genererede. Typen er angivet med en foruddefineret numerisk værdi og dens relaterede beskrivelse. Microsoft giver ikke meget detaljer om disse koder og beskrivelser, men du kan finde nogle detaljer i Microsoft-dokumentets Grafarkitektur. Igen er din primære bekymring med kolonnen $node_id og de data, den indeholder.

når du har oprettet din tabel, kan du begynde at tilføje data. At køre en INSERT-sætning mod en node-tabel fungerer ligesom enhver anden tabel. Du angiver målkolonnerne og deres værdier, som vist i følgende eksempel:

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’),
(‘den nordlige gedde’),
(‘Pacific herring’, ‘Clupea pallasi’),
(‘regnbueørred’, ‘Oncorhynchus mykiss’),
(‘Sole (Dover)’),
(‘hvid bas’, ‘Morone chrysops’);

selvfølgelig kan du tilføje uanset fiskearter, du har en særlig kærlighed til. Mine valg her var helt vilkårlige. Men hvis du holder fast i mine data og derefter spørger FishSpecies-tabellen, dine resultater skal ligne dem i den følgende figur.

som nævnt ovenfor vises kolonnen graph_id ikke i resultaterne, men kolonnen $node_id gør det, komplet med automatisk genererede værdier. Databasemotoren opretter hver værdi som en JSON-streng, der giver typen (node eller kant), skema, tabel og en BIGINT-værdi, der er unik for hver række. Som forventet returnerer databasemotoren også værdierne i de brugerdefinerede kolonner, ligesom en typisk relationstabel.

det næste trin er at oprette og udfylde FishLover-nodetabellen ved hjælp af følgende kode:

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

DROP tabel hvis eksisterer FishLover;
Opret tabel FishLover (
FishLoverID int identitet primær nøgle,
brugernavn NVARCHAR (50) IKKE NULL,
) som NODE;
indsæt i FishLover (brugernavn) værdier
‘),
(‘jessie98’),
(‘hooked’),
(‘deepdive’),
(‘undertøjcasey’);

tabellen indeholder kun to brugerdefinerede kolonner-FishLoverID og brugernavn—men du kan definere så mange kolonner som nødvendigt. Du kan f.eks. medtage for-og efternavne, kontaktoplysninger og andre oplysninger afhængigt af programmets Art. Når du har oprettet tabellen, kan du derefter køre en forespørgsel for at bekræfte dataene. Dine resultater skal ligne dem, der er vist i følgende figur.

du kan derefter tage de samme trin for at oprette og udfylde FishPost-tabellen, passerer den beskedtekst, du ønsker:

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

DROP tabel, hvis der findes FishPost;
Opret tabel FishPost (
PostID int IDENTITY PRIMARY KEY,
Title NVARCHAR(50) IKKE NULL,
Messagetekst NVARCHAR(800) IKKE NULL
) som NODE;
indsæt i fishpost (titel, MESSAGETEKST) værdier
(‘den der slap væk’, ‘vores team er tilgængeligt, kontakt os venligst. Aeneas fordel reserverede behov.’),
(‘en undersøgelse af fisk’, ‘ penatibus venenatis, nascetur ridiculus mus.’),
(‘Hook, line og sinker’, ‘ Donec pede justo, fringilla vel, aliket nec, vulputate eget, arcu.’),
(‘så mange fisk, så lidt tid’, ‘Nullam dictum felis eu pede mollis pretium. Heltal tincidunt.’),
(‘Min favorit fisk’, ‘ Aenean leo ligula, porttitor eu, deraf vitae, eleifend ac, enim.’);

følgende figur viser de resultater, du ville se, hvis du sidder fast med Lorem Ipsum-dataene.

det er alt, hvad der er at oprette og udfylde dine node tabeller. Bortset fra as NODE-klausulen i opret TABELOPGØRELSEN, er det meste alt andet business as usual.

definition af Graph Edge-tabeller

oprettelse af en edge-tabel svarer til oprettelse af en node-tabel, bortset fra at du skal angive as EDGE-klausulen snarere end as-NODE-klausulen. Hvis du f. eks. vil oprette tabellen indlæg, skal du bruge følgende erklæring Opret tabel:

1
2
3
4
5

DROP tabel, hvis der findes indlæg;
Opret TABELINDLÆG (
Vigtigflag BIT IKKE NULL standard 0
) som kant;

tabeldefinitionen ligner en nodetabel bortset fra at den ikke indeholder en primær nøglekolonne (og selvfølgelig tager den as EDGE-klausulen). I dette tilfælde er en primær nøgle ikke nødvendig, men hvis du på et tidspunkt bestemmer, at du har brug for en primær nøgle, kan du helt sikkert tilføje en. (Du vil snart se, hvorfor primære nøgler er nyttige til nodetabellerne.)

Bemærk, at tabeldefinitionen også indeholder kolonnen Vigtigflag. Jeg inkluderede dette primært for at demonstrere, at du kan tilføje brugerdefinerede kolonner til din edge-tabel, ligesom med node-tabeller. Når det er sagt, er det ikke ualmindeligt at oprette en kanttabel uden brugerdefinerede kolonner, i modsætning til en nodetabel, som skal indeholde mindst en brugerdefineret kolonne.

når du har oprettet edge-tabellen, kan du kontrollere, at den er defineret korrekt ved at forespørge sys.tabelvisning, som du så tidligere:

1
2

vælg is_node, is_edge fra sys.tabeller
hvor name = ‘indlæg’;

hvis du gjorde alt rigtigt, skal dine resultater ligne dem i følgende figur.

du kan også forespørge sys.tabelvisning for at bekræfte kolonneoplysninger, ligesom du gjorde før:

1
2
3

Vælg navn, graph_type, graph_type_desc
fra sys.kolonner
hvor object_id = OBJECT_ID (‘indlæg’);

følgende figur viser de resultater, der returneres på mit system.

som du kan se, tilføjer databasemotoren otte kolonner til en kanttabel i stedet for de to, du så med nodetabeller. Igen henvises til dokumentet med Grafarkitektur for beskrivelser af hver kolonnetype. Størstedelen af disse kolonner bruges af databasemotoren til interne operationer. Du skal primært være bekymret over følgende tre kolonner:

  • kolonnen $ edge_id_<heks_string> identificerer entydigt hvert forhold.
  • kolonnen $from_id_< heks_string > gemmer værdien $node_id, der er knyttet til enheden i tabellen, hvor forholdet stammer fra.
  • kolonnen $to_id_< heks_string > gemmer værdien $node_id, der er knyttet til enheden i tabellen, hvor forholdet afsluttes.

som med kolonnen $node_id i en nodetabel genererer databasemotoren automatisk værdier for kolonnen $edge_id. Du skal dog specifikt tilføje værdier til kolonnerne $from_id og $ to_id for at definere en relation. For at demonstrere, hvordan dette fungerer, starter vi med en enkelt post:

1
2
3

indsæt i indlæg ($from_id, $to_id) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 1),
(vælg $node_id fra FishPost hvor PostID = 3));

indsæt-sætningen definerer et forhold i tabellen indlæg mellem en FishLover-enhed, hvis FishLoverID-værdi er 1 og en FishPost-enhed, hvis PostID-værdi er 3. Bemærk, at du kan bruge aliaserne $node_id, $from_id og $to_id til at henvise til målkolonnerne uden at skulle komme med sekskantstrengene.

hvis du vil føje data til kolonnen $from_id, skal du angive værdien $node_id, der er knyttet til FishLover-enheden. En måde at få denne værdi på er at inkludere en underforespørgsel, der er målrettet mod enheden, ved hjælp af dens primære nøgleværdi. Du kan tage den samme tilgang til kolonnen $from_id.

indsættelse af dataene på denne måde viser, hvorfor det er nyttigt at tilføje primære nøgler til node-tabellerne, men ikke nødvendigt for edge-tabellerne. De primære nøgler på nodetabellerne gør det meget nemmere at give $node_id-værdien til Indsæt-sætningen.

hvis du nu forespørger i tabellen indlæg, skal dine resultater ligne dem, der vises i følgende figur.

tabellen skal indeholde det nye forhold,med den vigtige flag indstillet til 0, standard. Du kan nu tilføje et par flere rækker ved hjælp af følgende indsæt udsagn:

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

indsæt i indlæg ($from_id, $to_id) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 3),
(vælg $node_id fra FishPost hvor PostID = 2));
indsæt i indlæg ($from_id, $to_id) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 2),
(vælg $node_id fra FishPost hvor PostID = 5));
indsæt i indlæg ($from_id, $to_id, Vigtigflag) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 5),
(vælg $node_id fra FishPost hvor PostID = 4), 1);
indsæt i indlæg ($from_id, $to_id, Vigtigflag) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 4),
(vælg $node_id fra FishPost hvor PostID = 1), 1);

Bemærk, at de sidste to indsæt udsagn også giver en værdi for kolonnen Vigtigflag. Når du forespørger tabellen indlæg, skal dine resultater nu omfatte alle fem rækker.

det næste trin er at oprette og udfylde tabellen Likes ved hjælp af følgende kode:

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

DROP TABLE hvis der findes Likes;
Opret TABLE Likes som EDGE;
indsæt i Likes ($from_id, $to_id) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 3),
(vælg $node_id fra FishSpecies hvor FishID = 8));
indsæt i Likes ($from_id, $to_id) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 5),
(vælg $node_id fra FishPost hvor PostID = 4));
indsæt i Likes ($from_id, $to_id) værdier (
(vælg $node_id fra FishLover hvor FishLoverID = 1),
(vælg $node_id fra FishLover hvor FishLoverID = 4));

du kan, selvfølgelig, definere eventuelle relationer, du ønsker. Det vigtige punkt at bemærke her er, at du ikke er begrænset til et sæt noder. For eksempel skaber den første INSERT-sætning et forhold mellem FishLover og FishSpecies, den anden erklæring skaber et forhold mellem FishLover og FishPost, og den tredje erklæring skaber et forhold mellem FishLover og FishLover. Dette giver os forespørgselsresultaterne vist i den følgende figur.

du kan tage den samme tilgang, når du opretter og udfylder LinksTo-tabellen:

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

DROP tabel hvis findes LinksTo;
Opret TABELLINKSTO som kant;
indsæt i LinksTo ($from_id, $to_id) værdier (
(vælg $node_id fra FishPost hvor PostID = 2),
(vælg $node_id fra FishSpecies hvor FishID = 6));
indsæt i LinksTo ($from_id, $to_id) værdier (
(vælg $node_id fra FishPost hvor PostID = 4),
(vælg $node_id fra FishLover hvor FishLoverID = 1));
indsæt i LinksTo ($from_id, $to_id) værdier (
(vælg $node_id fra FishPost hvor PostID = 3),
(vælg $node_id fra FishPost hvor PostID = 5));

følgende figur viser, hvordan dataene skal se ud, når de er føjet til tabellen, forudsat at du fulgte eksemplet.

med en grafdatabase kan du tilføje en lang række relationer mellem oprindelige og afsluttende noder. Du kan også nemt indarbejde ændringer i grafmodellen. Du kan f.eks. vælge at tilføje en fishrecipes-node-tabel til lagring af de fiskeopskrifter, som brugerne sender til forummet, og i så fald kan du udnytte de eksisterende indlæg, Likes og LinksTo edge-tabeller.

gå videre med Graph-Databaser

fordi Microsoft inkluderer graph-databasefunktionerne som en del af SERVERDATABASEMOTOREN, kan du nemt prøve dem uden at skulle installere eller omkonfigurere nogen komponenter. Bedst af alt, du kan bruge de samme værktøjer og procedurer, du har brugt hele tiden til at oprette og udfylde node-og kanttabeller. I de artikler, der skal følges, dækker vi, hvordan du forespørger og ændrer grafdata og ser nærmere på at arbejde med hierarkiske data, så sørg for at holde dig opdateret.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.