Sdílet prostřednictvím


Vytvoření grafové databáze a spuštění některých vzorových odpovídajících dotazů pomocí T-SQL

platí pro: SQL Server 2017 (14.x) a novější verze Azure SQL DatabaseAzure SQL Managed Instancesql database v Microsoft Fabric

Tato ukázka poskytuje Transact-SQL skript pro vytvoření grafové databáze s uzly a hrany a následné použití nové klauzule POZVYHLEDAT k porovnání některých vzorů a procházení grafem. Tento ukázkový skript funguje v Azure SQL Database i SQL Serveru 2017 (14.x) a novějších verzích.

Ukázkové schéma

Tato ukázka vytvoří schéma grafu pro hypotetickou sociální síť, která má People, Restauranta City uzly. Tyto uzly jsou vzájemně propojené pomocí Friends, Likes, LivesIna LocatedIn hran. Následující diagram znázorňuje ukázkové schéma s restaurant, city, uzly person a LivesIn, LocatedIn, Likes hrany.

diagram znázorňující ukázkové schéma s okraji restaurace, města, osob a LivesIn, LocatedIn, Likes

Ukázkový skript

Následující ukázkový skript používá novou syntaxi T-SQL k vytvoření uzlu a hraničních tabulek. Naučte se vkládat data do uzlu a hraničních tabulek pomocí příkazu INSERT a také ukazuje, jak použít klauzuli MATCH pro porovnávání vzorů a navigaci.

Tento skript provede následující kroky:

  1. Vytvořte databázi s názvem GraphDemo.
  2. Vytvořte tabulky uzlů.
  3. Vytvořte hraniční tabulky.
-- 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;

Teď vložíme data, která představují relace.

  1. Vložte data do tabulek uzlů.
    1. Vložení do tabulky uzlů je stejné jako vložení do běžné tabulky.
  2. V tomto případě vložte data do hraničních tabulek, pro které se každému člověku líbí likes hrana.
    1. Při vkládání do hraniční tabulky zadejte $node_id ze sloupců $from_id a $to_id.
  3. Vložte data do hraničního livesIn a přidružte osoby k městu, kde žijí.
  4. Vložte data do hraničního locatedIn a přidružte restaurace k městu, kde se nacházejí.
  5. Vložte data do okraje friendOf přidruženým přátelům.
-- 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));

V dalším kroku se dotazujeme na data, abychom našli přehledy z dat.

  1. Pomocí grafu FUNKCE POZVYHLEDAT zjistíte, které restaurace se Jan líbí.
  2. Najde restaurace, které john přátelé rádi.
  3. Najděte lidi, kteří mají rádi restauraci ve stejném městě, ve kterém žijí.
-- 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);

A konečně, pokročilejší dotaz najde přátele přátel přátel. Tento dotaz vyloučí případy, kdy se relace "vrátí zpět". Alice je například přítel Johna; Jan je přítel Marie; a Mary je zase přítel Alice. To způsobí návrat smyčky zpět do Alice. V mnoha případech je nutné explicitně zkontrolovat takové smyčky a vyloučit výsledky.

-- 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;

Odklidit

Vyčistěte schéma a databázi vytvořenou pro ukázku na SQL Serveru.

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

Vyčistěte schéma a databázi vytvořenou pro ukázku ve službě 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

Další kroky