本文首發於 Nebula 公衆號:圖查詢語言的歷史回顧短文html
最近在對圖查詢語言 GQL 和國際標準草案作個梳理,調研過程當中找到下面這篇 mark 了沒細看的舊文(畢竟收藏就是看過)。作個簡單的記錄。git
本短文會涉及到的圖查詢語言有 Cypher、Gremlin、PGQL 和 G-CORE。程序員
本文主要摘錄翻譯自 [Tobias2018] (見參考文獻),並未涉及到 SPARQL 和 RDF,只討論了屬性圖。github
文章撰寫的時間是 2018 年,能夠看作 GQL(Graph Query Language)的一些前期準備。GQL 有多個相關的起源,參見下面這張圖。數據庫
由於 Cypher 的歷史和 Neo4j 緊密相關,本文會提一些 Neo4j 早期的歷史。[Angles2008](見參考文獻)和 [Wood2012](見參考文獻)是兩個不錯的關於圖模型和圖查詢語言的總結。express
Neo4j 和屬性圖這種數據模型,最先構想於 2000 年。Neo4j 的創始人們當時在開發一個媒體管理系統,所使用的數據庫的 schema 常常會發生重大變化。爲了支持這種靈活性,Neo4j 的聯合創始人 Peter Neubauer,受 Informix Cocoon 的啓發,但願將系統建模爲一些概念相互鏈接的網絡。印度理工學院孟買分校的一羣研究生們實現了最先的原型。Neo4j 的聯合創始人 Emil Eifrém 和這些學生們花了一週的時間,將 Peter 最初的想法擴展成爲這樣一個模型:節點經過關係鏈接,key-value 做爲節點和關係的屬性。這羣人開發了一個 Java API 來和這種數據模型交互,並在關係型數據庫之上實現了一個抽象層。服務器
雖然這種網絡模型極大的提升了生產力,可是性能一直不好。因此 Neo4j 聯合創始人 Johan Svensson 花精力,爲這種網絡模型實現了一個原生的數據管理系統。這個就成爲了 Neo4j。 在最初的幾年,Neo4j 做爲一個內部產品很成功。在 2007 年,Neo4j 的知識產權轉移給了一家獨立的數據庫公司。markdown
Neo4j 的第一個公開發行版中,數據模型由節點和有類型的邊構成,節點和邊都有 key-value 組成的屬性。Neo4j 的早期版本沒有任何的索引,應用程序只能從根節點開始本身構造查詢結構(search structure)。由於這樣對於應用程序很是笨重,Neo4j 2.0(2013 年 12 月發佈)引入了一個新概念——點上的標籤(label)。基於點標籤,Neo4j 能夠爲一些預約義的節點屬性創建索引。網絡
節點、關係、屬性、關係只能有一個標籤、節點能夠有零個或者多個標籤,以上這些構成了 Neo4j 屬性圖的數據模型定義。後來增長的索引功能,讓 Cypher 成爲了與 Neo4j 交互的主要方式。由於這樣應用開發者只須要關注於數據自己,而不是上段提到的那個開發者本身構建的查詢結構(search structure)。框架
圖或者說網絡類型的數據模型(多對多的關係)和其數據庫的歷史,能夠追溯到 80 年代。見 Kleppmann 2017第二章(見參考文獻部分)。
最初與 Neo4j 的查詢方式是經過 Java API。應用程序能夠將查詢引擎做爲庫嵌入到應用程序中,而後使用 API 查詢圖。若是是自定義查詢引擎,而後應用程序遠程訪問服務器,這樣就比較困難。
就在這段時間,NOSQL 這個概念開始出現。NOSQL 型的數據庫引擎通常用 REST 和 HTTP 來交互和查詢。Neo4j 的早期員工 Tobias Lindaaker(和 Ivarsson)考慮用 HTTP 的方式訪問 Neo4j 會是一種更好的辦法。他們觀察到不少的查詢語句能夠表達爲:圖到樹的投影映射(projection)。典型的,從根節點開始遍歷一個擴張樹(spanning tree),而後返回葉子節點。基於這樣的觀察,並參考一些樹結構的查詢語句,好比 XPath,也許能夠做爲一種圖的查詢方式。並且,XPath 的語法和通常 URI 的語法很像。這樣 XPath 查詢能夠很天然的做爲 HTTP GET 中 URI 的一部分。Neo4j 的聯合創始人 Peter Neubauer 喜歡這個想法,找了一個朋友 Marko Rodriguez 來幹。兩天後,Marko 作了一個原型,用 XPath 做爲圖查詢,Groovy 提供循環結構,分支,和計算。 這個就是 Gremlin 最初的原型。 2009 年 11 月發佈了第一個版本。
後來,Marko 發現同時用兩種不一樣的解析器(XPath和Groovy)有不少問題,就將 Gremlin 改成基於 Groovy 的一種內置的領域特定語言(DSL)。
Gremlin 和 Neo4j 的 Java API 同樣,最初用於表達如何查詢數據庫的一種過程(Procedural)。它容許更短的語法來表達查詢,也容許經過網絡遠程訪問數據庫。Gremlin 這種過程式的特性,須要用戶知道如何採用最好的辦法查詢結果,這樣對於應用程序開發人員來講仍舊有負擔。基於聲明式語言 SQL 的成功:SQL 能夠將獲取數據的聲明方式和引擎如何獲取數據分開,Neo4j 的工程師們但願開發一種聲明式的圖查詢語言。
2010 年,Andrés Taylor 做爲工程師加入 Neo4j,在此以前他是 SQL DBA。他開始了一個項目,受 SQL 啓發,其目標是開發圖查詢語言,而這種新語言 Cypher 於 2011 年 Neo4j 1.4 發佈。
Cypher 的語法基礎,是用 "ascii 藝術(ascii art)" 來描述圖模式。這種方式最初來源於 Neo4j 工程師團隊在源代碼中評註如何描述圖模式。能夠看下圖的例子:
ascii art 簡單說,就是如何用可打印文原本描述點和邊。Cypher 文本用()表示點,-[]->表示邊。(query)--[modeled as]->(drawing) 來表示起點 query,終點 drawing,邊 modeled as。
對於程序員來講,固然能夠設計一個 API 表示操做點,一個 API 表示操做邊. 但這樣就不是 SQL 這種聲明式語言的目的,對於非程序員使用也太困難。
Cypher 第一個版本實現了對圖的讀取,可是須要用戶說明從哪些節點開始查詢。只有從這些節點開始,才能夠支持圖的模式匹配。
略微學術一點的說, graph patterns(或者 motifs finding)和 navigational expression 是兩種不一樣的圖查詢操做[Renzo2017][databricks2020](見參考文獻部分)。不一樣語言這兩種操做的語義是有必定差異的。
在後面的版本,2012 年 10 月發佈的 Neo4j 1.8 中,Cypher 增長了修改圖的能力。但查詢仍是須要指明從哪些節點開始。
2013 年 12 月,Neo4j 2.0 引入了 label 的概念,label 本質上是個索引。這樣,查詢引擎就能夠利用索引,來選擇模式所匹配到的節點,而不須要用戶指定開始查詢的節點。
有沒有熟悉的感受?
隨着 Neo4j 的普及,Cypher 有着普遍的開發者羣體 ,和各行各業的使用。
圖查詢語言也有聲明式(Decalarative)和命令式(Imperative)的區別,前者(Cypher)相比後者(Gremlin)更強調目的和手段分離,更依賴於執行優化。但在工程上,二者思想並無那麼大的區別,後者也會有延遲計算和優化,前者也能夠部分命令式的思想。好的優化在工程上並非那麼容易,專業的用戶比查詢引擎更清楚如何求取、訪問、加工數據[Renzo2017][Deutsh2020]。
2015 年 9 月,Neo4j 開放了 Cypher 查詢語言,經過開源的方式來治理。這個新主體的治理主體是 openCypher Implementors Group(oCIG)。
2016 年,openCypher 項目發佈 EBNF 和 ANTLR4 ,Neo4j 也貢獻了不少基於 Apache 2.0 的語言功能測試集(openCypher Technology Compatibility Kit, TCK)。將這些做爲語言標準定義,任何人均可覺得該語言提交新的提議。2016 年,SAP HANA Graph 發佈了基於 Cypher 的查詢部分的實現,Agens Graph 和 Redis Graph 在 2017 年支持了 Cypher。2017 年 oCIG 也進行了一系列線上線下的會議,討論語言功能擴展等。
這個治理和討論方式能夠經過以下方式:github.com/opencypher/…
oCIG 發佈 openCypher,採用英語語言做爲規範,對應了 Neo4j 3.3.0 版本中的 Cypher。
2015 年,Oracle 爲 PGX 引擎開發了圖查詢語言 PGQL。PGQL 受 Cypher 的啓發,也和 Cypher 很接近。
Linked Data Benchmarking Council(LDBC)定義了一種廠商無關的基準測試。在開發這個基準測試的過程當中,他們發現市面上沒有標準的查詢語言來表達圖查詢。爲了處理這個問題,成立了一個特別工做組,調研市面上已經存在的圖查詢語言和框架,定義圖查詢必須的功能,而後爲現有語言提供修改建議。
2016 年,他們想設計一種新語言,而不是對於現有語言的修改。主要緣由是不想受現有語言的模型的限制。
G-CORE 是由 LDBC 工做組設計的,但主要受 Cypher 的啓發,採用同樣的語義。
Cypher 是 PGQL 和 G-CORE 的共同祖先。這幾個語言的語法和語義都很是的接近。PGQL 更接近一些早期的 Cypher,而 G-CORE 更指望語法和語義上都與 Cypher 兼容。
除去學術上的探索和一些零散的工程嘗試,以 Cypher 做爲主流屬性圖查詢語言工程實踐的歷史基準,也就 10 年的時間。在前面的幾年 2010-2013,Cypher 自身在基礎圖功能上還有很多缺失,好比索引、圖模式,迭代到 2014 年才產生當前使用的一個主流版本,而且還在持續演化 [Nadime2018](見參考文獻部分)。
重頭全新設計一種圖語言其實很難,極可能會把前人走過的路(坑)再走(掉)一遍(G-CORE 和 nGQL)。這是 GQL 第一個不容易的地方。
一個標準化組織中,有學術和商業機構,各自訴求也很不相同,商業機構已經各自有龐大的商業使用羣體,這是第二個不容易的地方。
制定完的標準,最後是否會被市場所接受和採納(vendor、custormer、developer、 goverment),又須要多少的佈道。這是 GQL 第三個不容易的地方。
除了核心基礎的圖操做之外的特性,好比 SQL、pregel [Grzegorz2010](見參考文獻部分)、GNN,每一個語言 PGQL、GSQL 甚至 Neo4j 本身都各自採用了徹底不一樣的方式來支持這些特性,要不要考慮這些新出現的特性。這是 GQL 第四個不容易的地方。
再想一想 GQL 和 Apache Tinkerpop/Gremlin 這兩條徹底不一樣的路,這是一個變化很快的時代,計算機又是一個更強調 de facto 標準的行業,GQL 並不容易。(打臉)
交流圖數據庫技術?加入 Nebula 交流羣請先填寫下你的 Nebulae 名片,Nebula 小助手會拉你進羣~~
查看大廠實踐案例?Follow Nebula 公衆號:NebulaGraphCommunity 回覆「PPT」掌握【美團的圖數據庫系統】、【微衆銀行的數據治理方案】以及其餘大廠的風控、知識圖譜實踐。