Skip to content

Commit 96f947b

Browse files
segovoniperrysk-msft
authored andcommitted
SQL Server 2017, Thanks to Graph Database, can express certain kinds of queries more easily than a relational database by transforming complex relationships into graphs (#354)
* Added some media for incoming demos on SQL Graph database * Added the file README.md and the first demo of the session SQL Server 2017 Graph Database that I have done at SQL Saturday Parma 2017 #sqlsat675 * Fixed a bug in SQL text visualization * Deleted some Unicode characters * Update file README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md added the demo "Build a sample recommendation system using SQL Graph" * Added the file sqlsat675 40 Recommendation system.sql that contains source code of the demo "Build a sample recommendation system using SQL Graph" * Update README.md * Added the file sqlsat675 30 Many-to-many relationships.sql * Delete folder sql-saturday-675-parma-italy * Add folder recommendation-system * Rename files * Update README.md * Update README.md * Update media file related to SQL Graph demos * Used function JSON_VALUE instead of OPENJSON to extract the first language of a Person * Update README.md * Update README.md * Update README.md * Update README.md
1 parent af5b694 commit 96f947b

10 files changed

Lines changed: 715 additions & 0 deletions
74 KB
Loading
69.9 KB
Loading
108 KB
Loading
67.6 KB
Loading
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# SQL Server 2017 Graph Database
2+
3+
SQL Server has always provided tools to manage hierarchies and relationships, facilitating query execution on hierarchical data, but sometimes relationships can become complex. Think about many-to-many relationships, relational databases don't have a native solution for many-to-many associations. A common approach to realize many-to-many associations is to introduce a table that holds such relationships.
4+
5+
SQL Server 2017, thanks to Graph Database, can express certain kinds of queries more easily than a relational database by transforming complex relationships into graphs.
6+
7+
These demos, based on [WideWorldImporters](https://github.com/Microsoft/sql-server-samples/tree/master/samples/databases/wide-world-importers) sample database, are related to the session that [Sergio Govoni](https://mvp.microsoft.com/it-it/PublicProfile/4029181?fullName=Sergio%20Govoni) has done at the PASS SQL Saturday 675 in Parma (Italy).
8+
9+
For those who don't already know the [SQL Saturday](http://www.sqlsaturday.com) events: Since 2007, the PASS SQL Saturday program provides to users around the world the opportunity to organize free training sessions on SQL Server and related technologies. SQL Saturday is an event sponsored by PASS and therefore offers excellent opportunities for training, professional exchange and networking. You can find all details in this page: [About PASS SQL Saturday](http://www.sqlsaturday.com/about.aspx).
10+
11+
12+
### Contents
13+
14+
[About this sample](#about-this-sample)<br/>
15+
[Before you begin](#before-you-begin)<br/>
16+
[Run this sample](#run-this-sample)<br/>
17+
[Disclaimers](#disclaimers)<br/>
18+
[Related links](#related-links)<br/>
19+
20+
<a name=about-this-sample></a>
21+
22+
## About this sample
23+
24+
1. **Applies to:**
25+
- Azure SQL Database v12 (or higher)
26+
- SQL Server 2017 (or higher)
27+
2. **Demos:**
28+
- Build and populating nodes and edges tables
29+
- The new MATCH function
30+
- Build a recommendation system for sales offers
31+
3. **Workload:** Queries executed on [WideWorldImporters](https://github.com/Microsoft/sql-server-samples/releases/tag/wide-world-importers-v1.0)
32+
4. **Programming Language:** T-SQL
33+
5. **Author:** [Sergio Govoni](https://mvp.microsoft.com/it-it/PublicProfile/4029181?fullName=Sergio%20Govoni)
34+
35+
<a name=before-you-begin></a>
36+
37+
## Before you begin
38+
39+
To run these demos, you need the following prerequisites.
40+
41+
**Account and Software prerequisites:**
42+
43+
1. Either
44+
- Azure SQL Database v12 (or higher)
45+
- SQL Server 2017 (or higher)
46+
2. SQL Server Management Studio 17.x (or higher)
47+
48+
**Azure prerequisites:**
49+
50+
1. An Azure subscription. If you don't already have an Azure subscription, you can get one for free here: [get Azure free trial](https://azure.microsoft.com/en-us/free/)
51+
52+
2. When your Azure subscription is ready to use, you have to create an Azure SQL Database, to do that, you must have completed the first three steps explained in [Design your first Azure SQL database](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-design-first-database)
53+
54+
<a name=run-this-sample></a>
55+
56+
## Run this sample
57+
58+
### Setup
59+
60+
#### Azure SQL Database Setup
61+
62+
1. Download the **WideWorldImporters-Standard.bacpac** from the WideWorldImporters database [page](https://github.com/Microsoft/sql-server-samples/releases/tag/wide-world-importers-v1.0)
63+
64+
2. Import the **WideWorldImporters-Standard.bacpac** bacpac file to your Azure subscription. This [article](https://www.sqlshack.com/import-sample-bacpac-file-azure-sql-database/) on SQL Shack explains how to import WideWorldImporters database to an Azure SQL Database, anyway, the instructions are valid for any bacpac file
65+
66+
3. Launch SQL Server Management Studio and connect to the newly created WideWorldImporters-Standard database
67+
68+
#### SQL Server Setup
69+
70+
1. Download **WideWorldImporters-Full.bak** from the WideWorldImporters database [page](https://github.com/Microsoft/sql-server-samples/releases/tag/wide-world-importers-v1.0)
71+
72+
2. Launch SQL Server Management Studio, connect to your SQL Server instance (2017) and restore **WideWorldImporters-Full.bak**. For further information about how to restore a database backup using SQL Server Management Studio, you can refer to this article: [Restore a Database Backup Using SSMS](https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/restore-a-database-backup-using-ssms). Once you have restored the WideWorldImporters database, you can connect it using the **USE** command like this:
73+
74+
```SQL
75+
USE [WideWorldImporters]
76+
```
77+
78+
The purpose of the file [before-you-begin.sql](./before-you-begin.sql) is to connect the database WideWorldImporters and create two new schema: **Edges** and **Nodes**.
79+
80+
81+
### Create and populate graph objects
82+
83+
The first demo consists in creating graph objects such as Nodes and Edges, this is the purpose of the file [demo1-create-and-populate-nodes-and-edges.sql](./demo1-create-and-populate-nodes-and-edges.sql). Let's start with the Node table named **Nodes.Person**. A node table represents an entity in a Graph DB, every time a node is created, in addition to the user defined columns, SQL Server Engine will create an implicit column named **$node_id** that uniquely identifies a given node in the database, it contains a combination of the **object_id** of the node and an internally bigint stored in an hidden column named **graph_id**.
84+
85+
The following picture shows the CREATE statement with the new DDL extension **AS NODE**, this extension tells to the engine that we want to create a Node table.
86+
87+
![Picture 1](../../../../media/demos/sql-graph/Create%20a%20Node%20Table.png)
88+
89+
Now, it's the time to create the Edge table named **Edges.Friends**. Every Edge represents a relationship in a graph, it may or may not have any user defined attributes, Edges are always directed and connected with two nodes. In the first release of SQL Graph, constraints are not available on the Edge table, so an Edge table can connect any two nodes on the graph. Every time an Edge table is created, in addition to the user defined columns, the Engine will create three implicit columns:
90+
91+
1. **$edge_id** is a combination of the **object_id** of the Edge and an internally bigint stored in an hidden column named **graph_id**
92+
93+
2. **$from_id** stores the **$node_id** of the node where the Edge starts from
94+
95+
3. **$to_id** stores the **$node_id** of the node at which the Edge ends
96+
97+
The following picture shows the CREATE statement with the new DDL extension **AS EDGE**, this extension tells to the engine that we want to create an Edge table.
98+
99+
![Picture 2](../../../../media/demos/sql-graph/Create%20an%20Edge%20Table.png)
100+
101+
The node **Nodes.Person** and the edge **Edges.Friends** are populated starting from the table **Application.People** of WideWorldImporters DB.
102+
103+
### The first look to the MATCH clause
104+
105+
The second demo allows you to do a first look to the MATCH clause used to perform some query on Nodes and Edges we have just created (in the first demo).
106+
107+
The new T-SQL MATCH function allows you to specify the search pattern for a graph schema, it can be used only with graph Node and Edge tables in SELECT statements as a part of the WHERE clause. Based on the node **Nodes.Person** and the edge **Edges.Friends**, the file [demo2-using-the-match-clause.sql](./demo2-using-the-match-clause.sql) contains the following sample queries:
108+
109+
1. List of all guys that speak finnish with friends (Pattern: Node > Relationship > Node)
110+
111+
2. List of the top 5 people who have friends that speak Greek in the first and second connections
112+
113+
3. People who have common friends that speak Croatian
114+
115+
The search pattern, provided in the MATCH function, goes through one node to another by an edge, in the direction provided by the arrow. Edge names or aliases are provided inside parenthesis. Node names or aliases appear at the two ends of the arrow.
116+
117+
118+
### Build a sample recommendation system using SQL Graph
119+
120+
Supposing to have a customer (of the table Sales.Customers) connected to our e-commerce, this customer is looking for the product (of the table Warehouse.StockItems) "USB food flash drive - pizza slice" or he/she has just bought that product. Our goal is finding the similar products to the one he/she is looking at, based on the behavior of other customers. In short words, we have to find products that are recommended for another one.
121+
122+
The following picture shows a possible scenario for our sales recommendation system.
123+
124+
![Picture 3](../../../../media/demos/sql-graph/Sales%20Recommendation%20Scenario.png)
125+
126+
This is the algorithm:
127+
128+
1. Identify the customer and the product he/she is purchasing
129+
130+
2. Identify the other customers who have purchased the same item he/she is looking for
131+
132+
3. Find the other products that customers, at step two, have purchased
133+
134+
4. Recommend to the current customer the top items from the previous step, ordered by the number of times they were purchased
135+
136+
The following picture shows the graphical representation of the algorithm.
137+
138+
![Picture 4](../../../../media/demos/sql-graph/Sales%20Recommendation%20System.png)
139+
140+
The file [demo3-create-and-populate-nodes-and-edges.sql](./demo3-create-and-populate-nodes-and-edges.sql) contains the statements to create and populate the nodes **Nodes.Customers**, **Nodes.StockItems** and the edge **Edges.Bought** starting from the tables of WideWorldImporters DB.
141+
142+
How can Graph Database helps us to implement this algorithm?
143+
144+
MATCH clause can express certain kinds of queries more easily than relational JOINs; let's start, we will use the counts to prioritize the recommendations that is the simplest possible algorithm for a recommendation service, in reality more complex filters are applied on top, for example text analysis of the product reviews to arrive at similarly measures.
145+
146+
The file [demo3-recommendation-system-for-sales.sql](./demo3-recommendation-system-for-sales.sql) contains the query that is able to extract top 5 products that are recommended for "USB food flash drive - pizza slice" using the MATCH clause.
147+
148+
The last query of the file [demo3-recommendation-system-for-sales.sql](./demo3-recommendation-system-for-sales.sql) shows you the implementation of the algorithm in the relational database using JOINs.. so you will know how many lines of code you would have wrote prior to SQL Graph Database.
149+
150+
<a name=disclaimers></a>
151+
152+
## Disclaimers
153+
154+
The code included in this sample is not intended to be a set of best practices on how to build scalable enterprise grade applications. This is beyond the scope of this quick start sample.
155+
156+
<a name=related-links></a>
157+
158+
## Related Links
159+
160+
For more information about Graph DB in SQL Server 2017, see these articles:
161+
162+
1. [Graph processing with SQL Server and Azure SQL Database](https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-overview)
163+
164+
2. [SQL Graph Architecture](https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-architecture)
165+
166+
3. [Arvind Shyamsundar's Blog](https://blogs.msdn.microsoft.com/arvindsh/)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
------------------------------------------------------------------------
2+
-- Event: SQL Saturday #675 Parma, November 18 2017 -
3+
-- http://www.sqlsaturday.com/675/EventHome.aspx -
4+
-- Session: SQL Server 2017 Graph Database -
5+
-- Demo: Setup -
6+
-- Author: Sergio Govoni -
7+
-- Notes: -- -
8+
------------------------------------------------------------------------
9+
10+
-- Full backup of WideWorldImporters sample database is available on GitHub
11+
-- https://github.com/Microsoft/sql-server-samples/releases/tag/wide-world-importers-v1.0
12+
13+
-- Documentation about WideWorldImporters sample database for SQL Server
14+
-- and Azure SQL Database
15+
-- https://github.com/Microsoft/sql-server-samples/tree/master/samples/databases/wide-world-importers
16+
17+
18+
USE [WideWorldImporters];
19+
GO
20+
21+
CREATE SCHEMA [Nodes];
22+
GO
23+
24+
CREATE SCHEMA [Edges];
25+
GO
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
------------------------------------------------------------------------
2+
-- Event: SQL Saturday #675 Parma, November 18 2017 -
3+
-- http://www.sqlsaturday.com/675/EventHome.aspx -
4+
-- Session: SQL Server 2017 Graph Database -
5+
-- Demo: Demo1: Create and populate Nodes and Edges -
6+
-- Author: Sergio Govoni -
7+
-- Notes: -- -
8+
------------------------------------------------------------------------
9+
10+
USE [WideWorldImporters];
11+
GO
12+
13+
------------------------------------------------------------------------
14+
-- Nodes -
15+
------------------------------------------------------------------------
16+
17+
DROP TABLE IF EXISTS Nodes.Person;
18+
GO
19+
20+
-- Create a node table
21+
CREATE TABLE Nodes.Person
22+
(
23+
PersonID INTEGER NOT NULL PRIMARY KEY
24+
,FullName NVARCHAR(50) NOT NULL
25+
,[Language] NVARCHAR(50) NOT NULL
26+
) AS NODE;
27+
GO
28+
29+
30+
SELECT * FROM sys.tables WHERE is_node = 1;
31+
GO
32+
33+
SELECT
34+
*
35+
FROM
36+
INFORMATION_SCHEMA.COLUMNS
37+
WHERE
38+
Table_Schema = 'Nodes'
39+
AND Table_Name = 'Person';
40+
GO
41+
42+
43+
/*
44+
SELECT FullName, CustomFields, *
45+
FROM [Application].[People];
46+
GO
47+
*/
48+
49+
INSERT INTO Nodes.Person
50+
(
51+
PersonID
52+
,FullName
53+
,[Language]
54+
)
55+
SELECT
56+
PersonID
57+
,FullName
58+
,[Language] = (SELECT JSON_VALUE(CustomFields, '$.OtherLanguages[0]'))
59+
FROM
60+
[Application].[People]
61+
WHERE
62+
(CustomFields IS NOT NULL)
63+
AND ((SELECT JSON_VALUE(CustomFields, '$.OtherLanguages[0]')) <> '');
64+
GO
65+
66+
67+
SELECT * FROM Nodes.Person
68+
69+
70+
------------------------------------------------------------------------
71+
-- Edges -
72+
------------------------------------------------------------------------
73+
74+
DROP TABLE IF EXISTS Edges.Friends;
75+
76+
-- Create an edge table
77+
CREATE TABLE Edges.Friends
78+
(
79+
StartDate DATETIME NOT NULL
80+
)
81+
AS EDGE;
82+
GO
83+
84+
85+
SELECT * FROM sys.tables WHERE is_edge = 1;
86+
GO
87+
88+
SELECT
89+
C.*
90+
FROM
91+
sys.tables AS T
92+
JOIN
93+
INFORMATION_SCHEMA.COLUMNS AS C ON C.Table_Name = T.[name] AND C.Table_Schema = SCHEMA_NAME(T.[schema_id])
94+
WHERE
95+
(T.is_edge = 1)
96+
ORDER BY
97+
C.Table_Schema, C.Table_Name
98+
GO
99+
100+
101+
102+
-- Insert friends who speak the same language
103+
-- (one direction)
104+
-- If a person speaks Finnish, I take for granted that
105+
-- their friends speak Finnish
106+
WITH Friends_Same_Language AS
107+
(
108+
SELECT
109+
P1.$node_id AS From_Node_Id
110+
,P2.$node_id AS To_Node_Id
111+
,GETDATE() AS StartDate
112+
,Direction = ROW_NUMBER() OVER (PARTITION BY P1.[Language], P2.[language] ORDER BY (SELECT NULL))
113+
,From_FullName = P1.FullName
114+
,From_Language = P1.[Language]
115+
,To_FullName = P2.FullName
116+
,To_Language = P2.[Language]
117+
FROM
118+
Nodes.Person AS P1
119+
INNER JOIN
120+
Nodes.Person AS P2 ON P1.[Language] = P2.[Language]
121+
WHERE
122+
-- The person itself isn't included
123+
(P1.$node_id <> P2.$node_id)
124+
)
125+
INSERT INTO Edges.Friends
126+
(
127+
$from_id
128+
,$to_id
129+
,StartDate
130+
)
131+
SELECT
132+
From_Node_Id
133+
,To_Node_Id
134+
,StartDate
135+
FROM
136+
Friends_Same_Language
137+
WHERE
138+
(Direction = 1);
139+
GO
140+
141+
142+
SELECT * FROM Nodes.Person;
143+
GO
144+
145+
146+
-- Insert some random connections
147+
INSERT INTO Edges.Friends
148+
(
149+
$from_id
150+
,$to_id
151+
,StartDate
152+
)
153+
SELECT
154+
From_Node_Id
155+
,To_Node_Id
156+
,StartDate
157+
FROM
158+
(
159+
SELECT DISTINCT TOP 40
160+
New_ID = NEWID()
161+
,P1.$node_id AS From_Node_Id
162+
,P2.$node_id AS To_Node_Id
163+
,GETDATE() AS StartDate
164+
FROM
165+
Nodes.Person AS P1
166+
INNER JOIN
167+
Nodes.Person AS P2 ON P1.[Language] < P2.[Language]
168+
WHERE
169+
(P1.$node_id <> P2.$node_id)
170+
ORDER BY
171+
New_ID
172+
) AS T;
173+
GO

0 commit comments

Comments
 (0)