過去兩年的時間投入了數據平台的建置,希望可以打造一個所謂的現代化數據平台(Modern Data Platform),這中間可是比想像中困難多了。但兩年過去了團隊成員從也是從小貓幾隻,一路成長到十多人的團隊。講到現代化的數據平台,NoSQL的儲存方案肯定是會被考量到的一項技術,在一陣研究和討論後,我們決定採用Cassandra當作在數據平台服務中,擔任NoSQL的主要儲存技術。
在導入的過程中當然沒有這麼順利,特別是對於只用過Oracle或是SQL Server等RDBMS技術,完全沒有碰過NoSQL的開發團隊,大家對於使用Cassandra總是有錯誤的想像,或是在不熟悉與不合適的使用情境下,最後造成大家與Cassandra「不歡而散」。
這篇想開始談談實際使用Cassandra後會因為Cassandra的設計限制遇到的問題,希望大家在一頭熱投入Cassandra的研究前,可以評估使用情境是否適合。我特別推薦在準備DataStax的Cassandra Developer Certification時上到的一堂課,這堂DS220提到許多Cassandra在實在作data modeling會需要知道的技巧和特性。
回到這次想談的,CQL不是SQL。
在初期投入Cassandra技術評估,看到Cassandra支援CQL(Cassandra Query Language)時,肯定會讓RDBMS開發者眼睛一亮,這看起來多麼的熟悉,忍不住在比較NoSQL方案時在Cassandra蓋上一個優勝的章。當然我不能否認當初我們也這麼認為,一直到大家實際使用時,才會發現CQL和SQL有根本上的不同。
不是任意欄位都能FILTER
簡單來說,比起RDBMS的SQL查詢,Cassandra因為本身的設計,所以CQL本來就只能作到有限度的查詢。CQL不能像SQL一樣可以將任意欄位放在where條件執行查詢,而是只能針對設定成partition key和clustering key的欄位進行查詢,甚至對組成clustering key的欄位,還有查詢順序的限制。當然這裡我們就先不提建立secondary index或是materialize view的情況。
拿下面這個簡單的員工資料表來說明。
deptname | jobgrade | gender | emplid | name |
---|---|---|---|---|
HR | 1 | Male | 001 | Tom |
HR | 3 | Female | 002 | Amy |
Design | 2 | Male | 003 | John |
Design | 1 | Female | 004 | Alice |
HR | 1 | Male | 005 | Bob |
Design | 3 | Male | 006 | Henry |
在Cassandra的員工表作了以下設計,如果不說是Cassandra的話,看起來其實就和一般的RDBMS沒有差別。但在Cassandra中下面建立的員工表其實隱含了將deptName設定為partition key,clustering key設定為jobgrade、gender和emplid的意思。以下的語法可以把這個範例建起來,DataStax有提供線上的serverless database可以使用。
1 | -- create |
假設在RDBMS裡用以上建立的資料表,舉幾種查詢情境如下:
1 | -- 查詢jobgrade為1的員工資料 |
以上看起來很直覺的查詢,如果是在Cassandra的世界裡,執行第一支CQL會得到以下的錯誤:
1 | SELECT * |
Cassandra會將資料依partitiony key分散放到不同的partition存放,所以在CQL查詢中的第一個條件必須要帶partition key(也就是deptname),Cassandra才能直接到指定的partition取回資料,用來加速資料查詢的速度。因此在不給定partition key條件下直接用jobgrade作filter是不允許的。
第二支CQL執行則會得到以下的錯誤:
1 | SELECT name |
因為Cassandra的世界裡,會將一個partition內部的資料依據clustering key作排序。以員工資料表為例,會以deptname切partition後,再依序用jobgrade、gender和emplid排序。
Casssandra透過預先排序的方式,在查詢資料時就可以得到排序結果,和SQL查詢完才作order by不同。因此Cassandra嚴格限制clustering key的欄位必須要依順序作filter,所以跳過jobgrade先查詢gender是不允許的。
第三支CQL則因為符合partition和clustering限制所以可以成功執行。
1 | SELECT * |
由以上可以發現,CQL雖然和SQL語法非常相似,但本質上Cassandra就是NoSQL資料庫,也有本身的設計限制。因此對於SQL使用者來說,千萬不要因為看到很像SQL的語法,就覺得可以很容易的上手使用!