全面比較非關系型數據庫Cassandra與RDBMS的設計差別
Cassandra是一個混合型的非關系型數據庫,是一個網絡社交云計算方面理想的數據庫。Cassandra的模型和查詢方式與RDBMS有很多的不同,記住這些差異非常重要。本文我們主要對Cassandra和RDBMS的設計差別進行全面的比較,接下來就讓我們來一起了解一下吧。
沒有查詢語言
SQL是關系型數據庫的標準查詢語言,Cassandra卻沒有查詢語言。不過Cassandra確實也有自己的RPC序列化機制,Thrift。通過Thrift API,用戶可以訪問其中的數據。
沒有引用完整性
Cassandra沒有引用完整性的概念,因而沒有join的概念。在關系型數據庫中,你可以在一個表中指定一個外部鍵值, 以此引用另一個表中記錄的主鍵。但是,Cassandra并沒有提供這個功能。存儲其他表中的相關ID是一個通用需求,這仍然是被支持的,但Cassandra里沒有級聯刪除這樣的概念。
第二索引
第二索引確實是一個有用的功能,比如你需要找到具有某個屬性的酒店的唯一ID,在關系型數據庫里,可能這么查詢:
SELECT hotelID FROM Hotel WHERE name = 'Clarion Midtown';
當你知道酒店的名字卻不知道ID的時候,肯定想這么查詢這個酒店。關系型數據庫如果接到這個查詢,會進行一個全表掃描,檢查每行的name列,查找所需要的名字。如果表很大,這種查詢可能會很慢。對這種情況,關系型數據庫的解決方案就是為這列建一個索引,相當于這部分數據的一個副本,來幫助更快地檢索數據。因為HotelID已經是一個主鍵約束了,主鍵會自動進行索引,也就是主索引,所以,對name列建立的索引自然就是第二索引,目前Cassandra仍然不支持第二索引。
要在Cassandra中做到同樣的事情,需要創建另一個列族來存儲查詢信息。你可以創建一個列族來存儲酒店名,并將它們映射到酒店的ID。第二列族實際上起到一個顯式的第二索引的作用。
第二索引目前正在被加入到Cassandra 0.7之中來,允許為列值建立索引。所以,如果你希望找到所有居住在指定城市的用戶,第二索引的支持將會讓你不必費力手工建立第二索引列族了。
排序成為一種設計決策
在RDBMS中,可以在查詢中使用ORDER BY來輕松改變返回記錄的順序。默認的排序方法確實是不可配置的;默認情況下,記錄按照它們寫入的順序被讀出。如果希望改變順序,只要改變查詢語句即可,而且可以對任意一組列進行排序。但在Cassandra之中,排序就不同了,它變成了一個設計決策。列族的定義中包含一個CompareWith配置元素,這個配置指定了行在讀出的時候按照什么方式排序,它在查詢的時候是無法重新配置的。
RDBMS限制你只能基于存儲在列中的數據類型來進行排序,但Cassandra存儲的數據是字節數組,所以這種用指定數據類型排序的方法是行不通的。不過,你能做的是把列當作幾種可排序的類型之一(ASCII、LONG、integer、TimestampUUID、字典排序等)。如果需要,你還可以使用自己實現的比較器來進行排序。此外,Cassandra里沒有SQL里的ORDER BY和GROUP BY語句。
反范式化
在關系型數據庫設計中,我們經常強調范式化的重要性。但是當使用Cassandra時,這就不是一個優點了,因為只有當數據模型是反范式化的時候,它的性能才是***的。實際上,很多公司最終都會將關系型數據庫反范式化,這主要有兩個原因。其一是性能原因,當他們在其多年積累的海量有價值的數據上進行大量的join操作的時候,無法得到所需的性能,于是就按照已知的查詢內容來反范式化數據庫以優化查詢。這種方法最終可以工作,但和關系型數據庫的設計初衷相悖,最終引發的問題就是,在這種條件下,使用關系型數據庫是否還是***手段。
關系型數據庫進行反范式化的第二個原因是業務文檔結構有時需要留存。也就是說,你有一個外圍表,引用了很多的外部表,表的數據可能會隨時間發生變化,但你也需要以快照形式保存外圍文檔的歷史。常見的一個例子是收款信息。你已經有客戶和產品表了,而且認為可以在收款信息里引用這些表。但是實際不應該這么做,因為客戶和價格信息都可能發生變化,那時你就會丟失收款信息的完整性了,因為這些表的變動似乎在收款時也發生了,這可能會影響到審計、報告,甚至是違法的,還可能引發其他問題。
在關系型數據庫里, 反范式化會破壞Codd的范式, 我們需要盡力避免。但在Cassandra中,反范式化卻正好合乎規則。它在數據模型很簡單時并不必要,但也不需要害怕它。
重點在于,首先對數據建模、然后再寫查詢的方法不再適用了。Cassandra中,應該先定義好查詢,并圍繞查詢來組織數據。考慮一下應用使用的最基本的查詢路徑,之后根據查詢路徑來構建所需要的列族就可以了。
批評者們認為這是個非常嚴重的問題。不過在設計數據庫的時候能夠考慮應用如何查詢也并非沒有道理,實際上,一般在關系型數據庫里也是這么做的。如果不能正確預期查詢方式,那么不論是在Cassandra里還是在關系型數據庫里,都會遇到問題。當然,查詢方式可能會隨著時間推移而改變,那么就不得不更新數據了。不過這和在關系型數據庫里定義表時犯錯或需要新的附加表也沒什么區別。
關于Cassandra與RDBMS的比較就介紹到這里了,希望本次的介紹能夠給您帶來一些收獲!
【編輯推薦】