關係型資料庫查詢語言 SQL 和圖資料庫查詢語言 nGQL 對比

nebulagraph發表於2020-07-23

摘要:這篇文章將介紹圖資料庫 Nebula Graph 的查詢語言 nGQL 和 SQL 的區別。

本文首發於 Nebula Graph 官方部落格:https://nebula-graph.com.cn/posts/sql-vs-ngql-comparison/

sql-vs-ngql

雖然本文主要介紹 nGQL 和 SQL 的區別,但是我們不會深入探討這兩種語言,而是將這兩種語言做對比,以幫助你從 SQL 過渡到 nGQL。

SQL (Structured Query Language) 是具有資料操縱和資料定義等多種功能的資料庫語言,這種語言是一種特定目的程式語言,用於管理關聯式資料庫管理系統(RDBMS),或在關係流資料管理系統(RDSMS)中進行流處理。

nGQL 是一種類 SQL 的宣告型的文字查詢語言,相比於 SQL, nGQL 為可擴充套件、支援圖遍歷、模式匹配、分散式事務(開發中)的圖資料庫查詢語言。

概念對比

對比項 SQL nGQL
\
\
點型別 \ tag
邊型別 \ edge type
點 ID 主鍵 vid
邊 ID 複合主鍵 起點、終點、rank
點或邊的屬性
點或邊

語法對比

資料定義語言 (DDL)

資料定義語言(DDL)用於建立或修改資料庫的結構,也就是 schema。

對比項 SQL nGQL
建立圖空間(資料庫) CREATE DATABASE <database_name> CREATE SPACE <space_name>
列出圖空間(資料庫) SHOW DATABASES SHOW SPACES
使用圖空間(資料庫) USE <database_name> USE <space_name>
刪除圖空間(資料庫) DROP DATABASE <database_name> DROP SPACE <space_name>
修改圖空間(資料庫) ALTER DATABASE <database_name> alter_option \
建立 tags/edges \ CREATE TAG | EDGE <tag_name>
建立表 CREATE TABLE <tbl_name> (create_definition,...) \
列出表列名 SHOW COLUMNS FROM <tbl_name> \
列出 tags/edges \ SHOW TAGS | EDGES
Describe tags/edge \ DESCRIBE TAG | EDGE <tag_name | edge_name>
修改 tags/edge \ ALTER TAG | EDGE <tag_name | edge_name>
修改表 ALTER TABLE <tbl_name> \

索引

對比項 SQL nGQL
建立索引 CREATE INDEX CREATE {TAG | EDGE} INDEX
刪除索引 DROP INDEX DROP {TAG | EDGE} INDEX
列出索引 SHOW INDEX FROM SHOW {TAG | EDGE} INDEXES
重構索引 ANALYZE TABLE REBUILD {TAG | EDGE} INDEX <index_name> [OFFLINE]

資料操作語言(DML)

資料操作語言(DML)用於運算元據庫中的資料。

對比項 SQL nGQL
插入資料 INSERT IGNORE INTO <tbl_name> [(col_name [, col_name] ...)] {VALUES | VALUE} [(value_list) [, (value_list)] INSERT VERTEX <tag_name> (prop_name_list[, prop_name_list]) {VALUES | VALUE} vid: (prop_value_list[, prop_value_list]) INSERT EDGE <edge_name> ( <prop_name_list> ) VALUES | VALUE <src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> )
查詢資料 SELECT GO, FETCH
更新資料 UPDATE <tbl_name> SET field1=new-value1, field2=new-value2 [WHERE Clause] UPDATE VERTEX <vid> SET <update_columns> [WHEN <condition>] UPDATE EDGE <edge> SET <update_columns> [WHEN <condition>]
刪除資料 DELETE FROM <tbl_name> [WHERE Clause] DELETE EDGE <edge_type> <vid> -> <vid>[@<rank>] [, <vid> -> <vid> ...] DELETE VERTEX <vid_list>
拼接資料 JOIN |

資料查詢語言(DQL)

資料查詢語言(DQL)語句用於執行資料查詢。本節說明如何使用 SQL 語句和 nGQL 語句查詢資料。

SELECT
 [DISTINCT]
 select_expr [, select_expr] ...
 [FROM table_references]
 [WHERE where_condition]
 [GROUP BY {col_name | expr | position}]
 [HAVING  where_condition]
 [ORDER BY {col_name | expr | position} [ASC | DESC]]
GO [[<M> TO] <N> STEPS ] FROM <node_list>
 OVER <edge_type_list> [REVERSELY] [BIDIRECT]
 [WHERE where_condition]
 [YIELD [DISTINCT] <return_list>]
 [| ORDER BY <expression> [ASC | DESC]]
 [| LIMIT [<offset_value>,] <number_rows>]
 [| GROUP BY {col_name | expr | position} YIELD <col_name>]

<node_list>
   | <vid> [, <vid> ...]
   | $-.id

<edge_type_list>
   edge_type [, edge_type ...]

<return_list>
    <col_name> [AS <col_alias>] [, <col_name> [AS <col_alias>] ...]

資料控制語言(DCL)

資料控制語言(DCL)包含諸如 GRANTREVOKE 之類的命令,這些命令主要用來處理資料庫系統的許可權、其他控制元件。

對比項 SQL nGQL
建立使用者 CREATE USER CREATE USER
刪除使用者 DROP USER DROP USER
更改密碼 SET PASSWORD CHANGE PASSWORD
授予許可權 GRANT <priv_type> ON [object_type] TO <user> GRANT ROLE <role_type> ON <space> TO <user>
刪除許可權 REVOKE <priv_type> ON [object_type] TO <user> REVOKE ROLE <role_type> ON <space> FROM <user>

資料模型

查詢語句基於以下資料模型:

RDBMS 關係結構圖

RDBMS

Nebula Graph 最小模型圖

Studio

本文將使用 NBA 資料集。該資料集包含兩種型別的點,也就是兩個標籤,即 playerteam ;兩種型別的邊,分別是 servefollow

在關係型資料管理系統中(RDBMS)中,我們用表來表示點以及與點相關的邊(連線表)。因此,我們建立了以下表格:playerteamservefollow。在 Nebula Graph 中,基本資料單位是頂點和邊。兩者都可以擁有屬性,相當於 RDBMS 中的屬性。

Nebula Graph 中,點之間的關係由邊表示。每條邊都有一種型別,在 NBA 資料集中,我們使用邊型別 servefollow 來區分兩種型別的邊。

示例資料

在 RDBMS 插入資料

首先,讓我們看看如何在 RDBMS 中插入資料。我們先建立一些表,然後為這些表插入資料。

CREATE TABLE player (id INT, name VARCHAR(100), age INT);
CREATE TABLE team (id INT, name VARCHAR(100));
CREATE TABLE serve (player_id INT, team_id INT, start_year INT, end_year INT);
CREATE TABLE follow (player_id1 INT, player_id2 INT, degree INT);

然後插入資料。

INSERT INTO player
VALUES
   (100, 'Tim Duncan', 42),
   (101, 'Tony Parker', 36),
   (102, 'LaMarcus Aldridge', 33),
   (103, 'Rudy Gay',32),
   (104, 'Marco Belinelli', 32),
   (105, 'Danny Green', 31),
   (106, 'Kyle Anderson', 25),
   (107, 'Aron Baynes', 32),
   (108, 'Boris Diaw', 36),
   (109, 'Tiago Splitter', 34),
   (110, 'Cory Joseph', 27);

INSERT INTO team
VALUES
   (200, 'Warriors'),
   (201, 'Nuggets'),
   (202, 'Rockets'),
   (203, 'Trail'),
   (204, 'Spurs'),
   (205, 'Thunders'),
   (206, 'Jazz'),
   (207, 'Clippers'),
   (208, 'Kings');

INSERT INTO serve
VALUES
   (100,200,1997,2016),
   (101,200,1999,2010),
   (102,200,2001,2005),
   (106,200,2000,2011),
   (107,200,2001,2009),
   (103,201,1999,2018),
   (104,201,2006,2015),
   (107,201,2007,2010),
   (108,201,2010,2016),
   (109,201,2011,2015),
   (105,202,2015,2019),
   (109,202,2017,2019),
   (110,202,2007,2009);

INSERT INTO follow
VALUES
   (100,101,95),
   (100,102,91),
   (100,106,90),
   (101,100,95),
   (101,102,91),
   (102,101,75),
   (103,102,70),
   (104,103,50),
   (104,105,60),
   (105,104,83),
   (105,110,87),
   (106,100,88),
   (106,107,81),
   (107,106,92),
   (107,108,97),
   (108,109,95),
   (109,110,78),
   (110,109,72),
   (110,105,85);

在 Nebula Graph 插入資料

Nebula Graph 中插入資料與上述類似。首先,我們需要定義好資料結構,也就是建立好 schema。然後可以選擇手動或使用 Nebula Graph Studio (Nebula Graph 的視覺化工具)匯入資料。這裡我們手動新增資料。

在下方的 INSERT 插入語句中,我們向圖空間 NBA 插入了球員資料(這和在 MySQL 中插入資料類似)。

INSERT VERTEX player(name, age) VALUES
100: ('Tim Duncan', 42),
101: ('Tony Parker', 36),
102: ('LaMarcus Aldridge', 33),
103: ('Rudy Gay', 32),
104: ('Marco Belinelli', 32),
105: ('Danny Green', 31),
106: ('Kyle Anderson', 25),
107: ('Aron Baynes', 32),
108: ('Boris Diaw', 36),
109: ('Tiago Splitter', 34),
110: ('Cory Joseph', 27);

考慮到篇幅限制,此處我們將跳過插入球隊和邊的重複步驟。你可以點選此處下載示例資料親自嘗試。

Nebula-Graph-Studio

增刪改查(CRUD)

本節介紹如何使用 SQL 和 nGQL 語句建立(C)、讀取(R)、更新(U)和刪除(D)資料。

插入資料

mysql> INSERT INTO player VALUES (100, 'Tim Duncan', 42);

nebula> INSERT VERTEX player(name, age) VALUES 100: ('Tim Duncan', 42);

查詢資料

查詢 ID 為 100 的球員並返回其 name 屬性:

mysql> SELECT player.name FROM player WHERE player.id = 100;

nebula> FETCH PROP ON player 100 YIELD player.name;

更新資料

mysql> UPDATE player SET name = 'Tim';

nebula> UPDATE VERTEX 100 SET player.name = "Tim";

刪除資料

mysql> DELETE FROM player WHERE name = 'Tim';

nebula> DELETE VERTEX 121;
nebula> DELETE EDGE follow 100 -> 200;

建立索引

返回年齡超過 36 歲的球員。

SELECT player.name
FROM player
WHERE player.age < 36;

使用 nGQL 查詢有些不同,因為您必須在過濾屬性之前建立索引。更多資訊請參見 索引文件

CREATE TAG INDEX player_age ON player(age);
REBUILD TAG INDEX player_age OFFLINE;
LOOKUP ON player WHERE player.age < 36;

示例查詢

本節提供一些示例查詢供您參考。

示例 1

在表 player 中查詢 ID 為 100 的球員並返回其 name 屬性。

SELECT player.name
FROM player
WHERE player.id = 100;

接下來使用 Nebula Graph 查詢 ID 為 100 的球員並返回其 name 屬性。

FETCH PROP ON player 100 YIELD player.name;

Nebula Graph 使用 FETCH 關鍵字獲取特定點或邊的屬性。本例中,屬性即為點 100 的名稱。nGQL 中的 YIELD 關鍵字相當於 SQL 中的 SELECT

示例 2

查詢球員 Tim Duncan 並返回他效力的所有球隊。

SELECT a.id, a.name, c.name
FROM player a
JOIN serve b ON a.id=b.player_id
JOIN team c ON c.id=b.team_id
WHERE a.name = 'Tim Duncan'

使用如下 nGQL 語句完成相同操作:

CREATE TAG INDEX player_name ON player(name);
REBUILD TAG INDEX player_name OFFLINE;
LOOKUP ON player WHERE player.name == 'Tim Duncan' YIELD player.name AS name | GO FROM $-.VertexID OVER serve YIELD $-.name, $$.team.name;

這裡需要注意一下,在 nGQL 中的等於操作採用的是 C 語言風格的 ==,而不是SQL風格的 =

示例 3

以下查詢略複雜,現在我們來查詢球員 Tim Duncan 的隊友。

SELECT a.id, a.name, c.name
FROM player a
JOIN serve b ON a.id=b.player_id
JOIN team c ON c.id=b.team_id
WHERE c.name IN (SELECT c.name
FROM player a
JOIN serve b ON a.id=b.player_id
JOIN team c ON c.id=b.team_id
WHERE a.name = 'Tim Duncan')

nGQL 則使用管道將前一個子句的結果作為下一個子句的輸入。

GO FROM 100 OVER serve YIELD serve._dst AS Team | GO FROM $-.Team OVER serve REVERSELY YIELD $$.player.name;

您可能已經注意到了,我們僅在 SQL 中使用了 JOIN。這是因為 Nebula Graph 只是使用類似 Shell 的管道對子查詢進行巢狀,這樣更符合我們的閱讀習慣也更簡潔。

參考資料

我們建議您親自嘗試上述查詢語句,這將幫您更好地理解 SQL 和 nGQL,並節省您上手 nGQL 的學習時間。以下是一些參考資料:

作者有話說:Hi,Hi ,大家好,我是 Amber,Nebula Graph 的文件工程師,希望上述內容可以給大家帶來些許啟發。限於水平,如有不當之處還請斧正,在此感謝^^

喜歡這篇文章?來來來,給我們的 GitHub 點個 star 表鼓勵啦~~ ?‍♂️?‍♀️ [手動跪謝]

交流圖資料庫技術?交個朋友,Nebula Graph 官方小助手微信:NebulaGraphbot 拉你進交流群~~

相關文章