Delen via


Een grafiekdatabase maken en een aantal patroonquery's uitvoeren met behulp van T-SQL

Van toepassing op: SQL Server 2017 (14.x) en latere versies Azure SQL DatabaseAzure SQL Managed InstanceSQL-database in Microsoft Fabric

Dit voorbeeld bevat een Transact-SQL script voor het maken van een grafiekdatabase met knooppunten en randen en vervolgens de nieuwe MATCH-component om bepaalde patronen te vinden en door de grafiek te bladeren. Dit voorbeeldscript werkt op zowel Azure SQL Database als SQL Server 2017 (14.x) en latere versies.

Voorbeeldschema

In dit voorbeeld wordt een grafiekschema gemaakt voor een hypothetisch sociaal netwerk met People, Restauranten City knooppunten. Deze knooppunten zijn met elkaar verbonden met behulp van Friends, Likes, LivesInen LocatedIn randen. In het volgende diagram ziet u een voorbeeldschema met restaurant, city, person knooppunten en LivesIn, LocatedIn, Likes randen.

diagram met een voorbeeldschema met restaurant-, plaats-, persoonsknooppunten en LivesIn, LocatedIn, Vind ik leuk aan randen.

Voorbeeldscript

In het volgende voorbeeldscript wordt de nieuwe T-SQL-syntaxis gebruikt om knooppunt- en edge-tabellen te maken. Meer informatie over het invoegen van gegevens in knooppunt- en edge-tabellen met behulp van INSERT instructie en laat ook zien hoe u MATCH component gebruikt voor patroonkoppeling en navigatie.

Met dit script worden de volgende stappen uitgevoerd:

  1. Maak een database met de naam GraphDemo.
  2. Knooppunttabellen maken.
  3. Edge-tabellen maken.
-- Create a GraphDemo database
IF NOT EXISTS (SELECT * FROM sys.databases WHERE NAME = 'graphdemo')
    CREATE DATABASE GraphDemo;
GO

USE GraphDemo;
GO

-- Create NODE tables
CREATE TABLE Person (
  ID INTEGER PRIMARY KEY,
  name VARCHAR(100)
) AS NODE;

CREATE TABLE Restaurant (
  ID INTEGER NOT NULL,
  name VARCHAR(100),
  city VARCHAR(100)
) AS NODE;

CREATE TABLE City (
  ID INTEGER PRIMARY KEY,
  name VARCHAR(100),
  stateName VARCHAR(100)
) AS NODE;

-- Create EDGE tables.
CREATE TABLE likes (rating INTEGER) AS EDGE;
CREATE TABLE friendOf AS EDGE;
CREATE TABLE livesIn AS EDGE;
CREATE TABLE locatedIn AS EDGE;

Nu voegen we gegevens in die de relaties vertegenwoordigen.

  1. Gegevens invoegen in knooppunttabellen.
    1. Invoegen in een knooppunttabel is hetzelfde als invoegen in een gewone tabel.
  2. Voeg gegevens in randtabellen in, in dit geval, waarvoor elke persoon de likes rand leuk vindt.
    1. Geef tijdens het invoegen in een randtabel de $node_id op uit $from_id en $to_id kolommen.
  3. Voeg gegevens in de livesIn rand in om personen te koppelen aan de stad waar ze wonen.
  4. Voeg gegevens in de locatedIn rand in om restaurants te koppelen aan de stad waar ze zich bevinden.
  5. Voeg gegevens in de friendOf edge toe aan gekoppelde vrienden.
-- Insert data into node tables. Inserting into a node table is same as inserting into a regular table
INSERT INTO Person (ID, name)
    VALUES (1, 'John')
         , (2, 'Mary')
         , (3, 'Alice')
         , (4, 'Jacob')
         , (5, 'Julie');

INSERT INTO Restaurant (ID, name, city)
    VALUES (1, 'Taco Dell','Bellevue')
         , (2, 'Ginger and Spice','Seattle')
         , (3, 'Noodle Land', 'Redmond');

INSERT INTO City (ID, name, stateName)
    VALUES (1,'Bellevue','WA')
         , (2,'Seattle','WA')
         , (3,'Redmond','WA');

-- Insert into edge table. While inserting into an edge table,
-- you need to provide the $node_id from $from_id and $to_id columns.
/* Insert which restaurants each person likes */
INSERT INTO likes
    VALUES ((SELECT $node_id FROM Person WHERE ID = 1), (SELECT $node_id FROM Restaurant WHERE ID = 1), 9)
         , ((SELECT $node_id FROM Person WHERE ID = 2), (SELECT $node_id FROM Restaurant WHERE ID = 2), 9)
         , ((SELECT $node_id FROM Person WHERE ID = 3), (SELECT $node_id FROM Restaurant WHERE ID = 3), 9)
         , ((SELECT $node_id FROM Person WHERE ID = 4), (SELECT $node_id FROM Restaurant WHERE ID = 3), 9)
         , ((SELECT $node_id FROM Person WHERE ID = 5), (SELECT $node_id FROM Restaurant WHERE ID = 3), 9);

/* Associate in which city live each person*/
INSERT INTO livesIn
    VALUES ((SELECT $node_id FROM Person WHERE ID = 1), (SELECT $node_id FROM City WHERE ID = 1))
         , ((SELECT $node_id FROM Person WHERE ID = 2), (SELECT $node_id FROM City WHERE ID = 2))
         , ((SELECT $node_id FROM Person WHERE ID = 3), (SELECT $node_id FROM City WHERE ID = 3))
         , ((SELECT $node_id FROM Person WHERE ID = 4), (SELECT $node_id FROM City WHERE ID = 3))
         , ((SELECT $node_id FROM Person WHERE ID = 5), (SELECT $node_id FROM City WHERE ID = 1));

/* Insert data where the restaurants are located */
INSERT INTO locatedIn
    VALUES ((SELECT $node_id FROM Restaurant WHERE ID = 1), (SELECT $node_id FROM City WHERE ID =1))
         , ((SELECT $node_id FROM Restaurant WHERE ID = 2), (SELECT $node_id FROM City WHERE ID =2))
         , ((SELECT $node_id FROM Restaurant WHERE ID = 3), (SELECT $node_id FROM City WHERE ID =3));

/* Insert data into the friendOf edge */
INSERT INTO friendOf
    VALUES ((SELECT $NODE_ID FROM Person WHERE ID = 1), (SELECT $NODE_ID FROM Person WHERE ID = 2))
         , ((SELECT $NODE_ID FROM Person WHERE ID = 2), (SELECT $NODE_ID FROM Person WHERE ID = 3))
         , ((SELECT $NODE_ID FROM Person WHERE ID = 3), (SELECT $NODE_ID FROM Person WHERE ID = 1))
         , ((SELECT $NODE_ID FROM Person WHERE ID = 4), (SELECT $NODE_ID FROM Person WHERE ID = 2))
         , ((SELECT $NODE_ID FROM Person WHERE ID = 5), (SELECT $NODE_ID FROM Person WHERE ID = 4));

Vervolgens doorzoeken we de gegevens om inzichten uit de gegevens te vinden.

  1. Gebruik de grafiek functie VERGELIJKEN om te vinden welke restaurants John leuk vindt.
  2. Vindt de restaurants die Johns vrienden leuk vinden.
  3. Zoek mensen die een restaurant leuk vinden in dezelfde stad waarin ze wonen.
-- Find Restaurants that John likes
SELECT Restaurant.name
FROM Person, likes, Restaurant
WHERE MATCH (Person-(likes)->Restaurant)
AND Person.name = 'John';

-- Find Restaurants that John's friends like
SELECT Restaurant.name
FROM Person person1, Person person2, likes, friendOf, Restaurant
WHERE MATCH(person1-(friendOf)->person2-(likes)->Restaurant)
AND person1.name='John';

-- Find people who like a restaurant in the same city they live in
SELECT Person.name
FROM Person, likes, Restaurant, livesIn, City, locatedIn
WHERE MATCH (Person-(likes)->Restaurant-(locatedIn)->City AND Person-(livesIn)->City);

Ten slotte vindt een meer geavanceerde query de vrienden van vrienden van vrienden. Deze query sluit de gevallen uit waarin de relatie 'terugloopt'. Alice is bijvoorbeeld een vriend van John; John is een vriend van Mary. En Mary is een vriend van Alice. Dit veroorzaakt een 'lus' terug naar Alice. In veel gevallen is het nodig om expliciet te controleren op dergelijke lussen en de resultaten uit te sluiten.

-- Find friends-of-friends-of-friends, excluding those cases where the relationship "loops back".
-- For example, Alice is a friend of John; John is a friend of Mary; and Mary in turn is a friend of Alice.
-- This causes a "loop" back to Alice. In many cases, it is necessary to explicitly check for such loops and exclude the results.
SELECT CONCAT(Person.name, '->', Person2.name, '->', Person3.name, '->', Person4.name)
FROM Person, friendOf, Person as Person2, friendOf as friendOffriend, Person as Person3, friendOf as friendOffriendOfFriend, Person as Person4
WHERE MATCH (Person-(friendOf)->Person2-(friendOffriend)->Person3-(friendOffriendOfFriend)->Person4)
AND Person2.name != Person.name
AND Person3.name != Person2.name
AND Person4.name != Person3.name
AND Person.name != Person4.name;

Opschonen

Schoon het schema en de database op die zijn gemaakt voor het voorbeeld in SQL Server.

USE graphdemo;
go

DROP TABLE IF EXISTS likes;
DROP TABLE IF EXISTS Person;
DROP TABLE IF EXISTS Restaurant;
DROP TABLE IF EXISTS City;
DROP TABLE IF EXISTS friendOf;
DROP TABLE IF EXISTS livesIn;
DROP TABLE IF EXISTS locatedIn;

USE master;
go
DROP DATABASE graphdemo;
go

Schoon het schema en de database op die zijn gemaakt voor het voorbeeld in Azure SQL Database.

--Connect to the graphdemo database
DROP TABLE IF EXISTS likes;
DROP TABLE IF EXISTS Person;
DROP TABLE IF EXISTS Restaurant;
DROP TABLE IF EXISTS City;
DROP TABLE IF EXISTS friendOf;
DROP TABLE IF EXISTS livesIn;
DROP TABLE IF EXISTS locatedIn;

--Connect to the master database
DROP DATABASE graphdemo;
go

Volgende stappen