同样是查询语言,它和 SQL 竟然有这么多不同
摘要:這篇文章將介紹圖數(shù)據(jù)庫 Nebula Graph 的查詢語言 nGQL 和 SQL 的區(qū)別。
本文首發(fā)于 Nebula Graph 官方博客:https://nebula-graph.com.cn/posts/sql-vs-ngql-comparison/
雖然本文主要介紹 nGQL 和 SQL 的區(qū)別,但是我們不會深入探討這兩種語言,而是將這兩種語言做對比,以幫助你從 SQL 過渡到 nGQL。
SQL (Structured Query Language) 是具有數(shù)據(jù)操縱和數(shù)據(jù)定義等多種功能的數(shù)據(jù)庫語言,這種語言是一種特定目的編程語言,用于管理關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RDBMS),或在關(guān)系流數(shù)據(jù)管理系統(tǒng)(RDSMS)中進行流處理。
nGQL 是一種類 SQL 的聲明型的文本查詢語言,相比于 SQL, nGQL 為可擴展、支持圖遍歷、模式匹配、分布式事務(開發(fā)中)的圖數(shù)據(jù)庫查詢語言。
概念對比
| 點 | \ | 點 |
| 邊 | \ | 邊 |
| 點類型 | \ | tag |
| 邊類型 | \ | edge type |
| 點 ID | 主鍵 | vid |
| 邊 ID | 復合主鍵 | 起點、終點、rank |
| 列 | 列 | 點或邊的屬性 |
| 行 | 行 | 點或邊 |
語法對比
數(shù)據(jù)定義語言 (DDL)
數(shù)據(jù)定義語言(DDL)用于創(chuàng)建或修改數(shù)據(jù)庫的結(jié)構(gòu),也就是 schema。
| 創(chuàng)建圖空間(數(shù)據(jù)庫) | CREATE DATABASE <database_name> | CREATE SPACE <space_name> | |
| 列出圖空間(數(shù)據(jù)庫) | SHOW DATABASES | SHOW SPACES | |
| 使用圖空間(數(shù)據(jù)庫) | USE <database_name> | USE <space_name> | |
| 刪除圖空間(數(shù)據(jù)庫) | DROP DATABASE <database_name> | DROP SPACE <space_name> | |
| 修改圖空間(數(shù)據(jù)庫) | ALTER DATABASE <database_name> alter_option | \ | |
| 創(chuàng)建 tags/edges | \ | CREATE TAG | EDGE <tag_name> | |
| 創(chuàng)建表 | CREATE TABLE <tbl_name> (create_definition,...) | \ | |
| 列出表列名 | SHOW COLUMNS FROM <tbl_name> | \ | |
| 列出 tags/edges | \ | SHOW TAGS | EDGES | |
| Describe tags/edge | \ | DESCRIBE TAG | EDGE ` | edge_name>` |
| 修改 tags/edge | \ | ALTER TAG | EDGE ` | edge_name>` |
| 修改表 | ALTER TABLE <tbl_name> | \ |
索引
| 創(chuàng)建索引 | CREATE INDEX | CREATE {TAG | EDGE} INDEX |
| 刪除索引 | DROP INDEX | DROP {TAG | EDGE} INDEX |
| 列出索引 | SHOW INDEX FROM | SHOW {TAG | EDGE} INDEXES |
| 重構(gòu)索引 | ANALYZE TABLE | REBUILD {TAG | EDGE} INDEX <index_name> [OFFLINE] |
數(shù)據(jù)操作語言(DML)
數(shù)據(jù)操作語言(DML)用于操作數(shù)據(jù)庫中的數(shù)據(jù)。
| 插入數(shù)據(jù) | 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> ) | |
| 查詢數(shù)據(jù) | SELECT | GO, FETCH | |
| 更新數(shù)據(jù) | 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>] | |
| 刪除數(shù)據(jù) | DELETE FROM <tbl_name> [WHERE Clause] | DELETE EDGE <edge_type> <vid> -> <vid>[@<rank>] [, <vid> -> <vid> ...] DELETE VERTEX <vid_list> | |
| 拼接數(shù)據(jù) | JOIN | `\ | ` |
數(shù)據(jù)查詢語言(DQL)
數(shù)據(jù)查詢語言(DQL)語句用于執(zhí)行數(shù)據(jù)查詢。本節(jié)說明如何使用 SQL 語句和 nGQL 語句查詢數(shù)據(jù)。
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>] ...]數(shù)據(jù)控制語言(DCL)
數(shù)據(jù)控制語言(DCL)包含諸如 GRANT 和 REVOKE 之類的命令,這些命令主要用來處理數(shù)據(jù)庫系統(tǒng)的權(quán)限、其他控件。
| 創(chuàng)建用戶 | CREATE USER | CREATE USER |
| 刪除用戶 | DROP USER | DROP USER |
| 更改密碼 | SET PASSWORD | CHANGE PASSWORD |
| 授予權(quán)限 | GRANT <priv_type> ON [object_type] TO <user> | GRANT ROLE <role_type> ON <space> TO <user> |
| 刪除權(quán)限 | REVOKE <priv_type> ON [object_type] TO <user> | REVOKE ROLE <role_type> ON <space> FROM <user> |
數(shù)據(jù)模型
查詢語句基于以下數(shù)據(jù)模型:
RDBMS 關(guān)系結(jié)構(gòu)圖
Nebula Graph 最小模型圖
本文將使用 NBA 數(shù)據(jù)集。該數(shù)據(jù)集包含兩種類型的點,也就是兩個標簽,即 player 和 team ;兩種類型的邊,分別是 serve 和 follow。
在關(guān)系型數(shù)據(jù)管理系統(tǒng)中(RDBMS)中,我們用表來表示點以及與點相關(guān)的邊(連接表)。因此,我們創(chuàng)建了以下表格:player、team、serve 和 follow。在 Nebula Graph 中,基本數(shù)據(jù)單位是頂點和邊。兩者都可以擁有屬性,相當于 RDBMS 中的屬性。
在 Nebula Graph 中,點之間的關(guān)系由邊表示。每條邊都有一種類型,在 NBA 數(shù)據(jù)集中,我們使用邊類型 serve 和 follow 來區(qū)分兩種類型的邊。
示例數(shù)據(jù)
在 RDBMS 插入數(shù)據(jù)
首先,讓我們看看如何在 RDBMS 中插入數(shù)據(jù)。我們先創(chuàng)建一些表,然后為這些表插入數(shù)據(jù)。
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);然后插入數(shù)據(jù)。
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 插入數(shù)據(jù)
在 Nebula Graph 中插入數(shù)據(jù)與上述類似。首先,我們需要定義好數(shù)據(jù)結(jié)構(gòu),也就是創(chuàng)建好 schema。然后可以選擇手動或使用 Nebula Graph Studio (Nebula Graph 的可視化工具)導入數(shù)據(jù)。這里我們手動添加數(shù)據(jù)。
在下方的 INSERT 插入語句中,我們向圖空間 NBA 插入了球員數(shù)據(jù)(這和在 MySQL 中插入數(shù)據(jù)類似)。
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);考慮到篇幅限制,此處我們將跳過插入球隊和邊的重復步驟。你可以點擊此處下載示例數(shù)據(jù)親自嘗試。
增刪改查(CRUD)
本節(jié)介紹如何使用 SQL 和 nGQL 語句創(chuàng)建(C)、讀取(R)、更新(U)和刪除(D)數(shù)據(jù)。
插入數(shù)據(jù)
mysql> INSERT INTO player VALUES (100, 'Tim Duncan', 42);nebula> INSERT VERTEX player(name, age) VALUES 100: ('Tim Duncan', 42);查詢數(shù)據(jù)
查找 ID 為 100 的球員并返回其 name 屬性:
mysql> SELECT player.name FROM player WHERE player.id = 100;nebula> FETCH PROP ON player 100 YIELD player.name;更新數(shù)據(jù)
mysql> UPDATE player SET name = 'Tim';nebula> UPDATE VERTEX 100 SET player.name = "Tim";刪除數(shù)據(jù)
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 查詢有些不同,因為您必須在過濾屬性之前創(chuàng)建索引。更多信息請參見 索引文檔。
CREATE TAG INDEX player_age ON player(age); REBUILD TAG INDEX player_age OFFLINE; LOOKUP ON player WHERE player.age < 36;示例查詢
本節(jié)提供一些示例查詢供您參考。
示例 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 關(guān)鍵字獲取特定點或邊的屬性。本例中,屬性即為點 100 的名稱。nGQL 中的 YIELD 關(guān)鍵字相當于 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
以下查詢略復雜,現(xiàn)在我們來查詢球員 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 則使用管道將前一個子句的結(jié)果作為下一個子句的輸入。
GO FROM 100 OVER serve YIELD serve._dst AS Team | GO FROM $-.Team OVER serve REVERSELY YIELD $$.player.name;您可能已經(jīng)注意到了,我們僅在 SQL 中使用了 JOIN。這是因為 Nebula Graph 只是使用類似 Shell 的管道對子查詢進行嵌套,這樣更符合我們的閱讀習慣也更簡潔。
參考資料
我們建議您親自嘗試上述查詢語句,這將幫您更好地理解 SQL 和 nGQL,并節(jié)省您上手 nGQL 的學習時間。以下是一些參考資料:
- Nebula Graph Studio 用戶指南
- Nebula Graph GitHub 倉庫
- Nebula Graph 快速入門文檔
作者有話說:Hi,Hi ,大家好,我是 Amber,Nebula Graph 的文檔工程師,希望上述內(nèi)容可以給大家?guī)硇┰S啟發(fā)。限于水平,如有不當之處還請斧正,在此感謝^^
喜歡這篇文章?來來來,給我們的 GitHub 點個 star 表鼓勵啦~~ 🙇?♂?🙇?♀? [手動跪謝]
交流圖數(shù)據(jù)庫技術(shù)?交個朋友,Nebula Graph 官方小助手微信:NebulaGraphbot 拉你進交流群~~
原文鏈接:https://developer.aliyun.com/article/768559?
版權(quán)聲明:本文中所有內(nèi)容均屬于阿里云開發(fā)者社區(qū)所有,任何媒體、網(wǎng)站或個人未經(jīng)阿里云開發(fā)者社區(qū)協(xié)議授權(quán)不得轉(zhuǎn)載、鏈接、轉(zhuǎn)貼或以其他方式復制發(fā)布/發(fā)表。申請授權(quán)請郵件developerteam@list.alibaba-inc.com,已獲得阿里云開發(fā)者社區(qū)協(xié)議授權(quán)的媒體、網(wǎng)站,在轉(zhuǎn)載使用時必須注明"稿件來源:阿里云開發(fā)者社區(qū),原文作者姓名",違者本社區(qū)將依法追究責任。 如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,歡迎發(fā)送郵件至:developer2020@service.aliyun.com 進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容。總結(jié)
以上是生活随笔為你收集整理的同样是查询语言,它和 SQL 竟然有这么多不同的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蚂蚁集团网络通信框架 SOFABolt
- 下一篇: 高德智慧景区随身听播放器框架设计与实现