Cassandra 的數據存儲結構
Cassandra 的數據模型是基于列族(Column Family)的四維或五維模型。它借鑒了 Amazon 的 Dynamo 和 Google's BigTable 的數據結構和功能特點,采用 Memtable 和 SSTable 的方式進行存儲。在 Cassandra 寫入數據之前,需要先記錄日志 ( CommitLog ),然后數據開始寫入到 Column Family 對應的 Memtable 中,Memtable 是一種按照 key 排序數據的內存結構,在滿足一定條件時,再把 Memtable 的數據批量的刷新到磁盤上,存儲為 SSTable 。
圖 1. Cassandra 的數據模型圖:
- Cassandra 的數據模型的基本概念:
- Cluster : Cassandra 的節點實例,它可以包含多個 Keyspace
- Keyspace : 用于存放 ColumnFamily 的容器,相當于關系數據庫中的 Schema 或 database——類似mongodb里的namespace use xxx;
- ColumnFamily : 用于存放 Column 的容器,類似關系數據庫中的 table 的概念
- SuperColumn :它是一個特列殊的 Column, 它的 Value 值可以包函多個 Column
- Columns:Cassandra 的最基本單位。由 name , value , timestamp 組成
下面是關于數據模型實例分析 :
圖 2. 數據模型實例分析
?
說明:
(1) column family插入數據的方法
(2) Super column family插入數據的方法
從上圖可以看出,SCF能夠支持5維數據空間(分別為:keyspace,column family,super key, key, column name)。
下面摘自:http://www.justinablog.com/archives/882 可以看到,和上文的描述是一致的!
?
列(Column)
如果你對“列”的理解來自于關系型數據庫,那么很容易產生和我之前一樣的誤解,以為Cassandra是把關系型數據庫的行列進行了某種倒置而得到 的設計。其實不是這樣的,Cassandra的列是一組鍵值對,它的結構如下圖所示(事實上,這個數據結構是Cassandra 0.7.0,最新的2.0.3版本中ByteBuffer替代了byte[],long型的日期時間替代了IClock):
使用JSON描述的列結構:
{"name": "email", "value: "me@example.com", "timestamp": 1274654183103300 }
超級列(Super Column)的結構:
復合鍵(Composite Keys)
有時我們會遇到不同省份可能有同樣的城市名稱,或不同的城市有重名的街道,這時使用單一的城市名稱或街道名稱來作為Key就會無法識別。 Cassandra允許你使用Key1:Key2的結構來存儲一對值作為Key,一個常見的例子是使 用<userid:lastupdate>這樣的結構來存儲用戶ID及最后登錄時間。下面是一個例子:
HotelByCity (CF) Key: city:state { key: Phoenix:AZ {AZC_043: -, AZS_011: -} key: San Francisco:CA {CAS_021: -} key: New York:NY {NYN_042: -} }
最后讓我們來鞏固一下Cassandra和關系型數據庫的區別吧:
- 沒有查詢語言:No SQL (Structured Query Language);
- 沒有外鍵約束:關系型數據庫的最重要特征;
- 雙重簇索引:在關系型數據庫中,每個表只能指定一個簇索引,其它的索引查詢都會導致全表掃描,但在Cassandra中,我們可以有第二級的簇索引;
- 排序是在設計時決策:Cassandra不支持Order By,排序是需要設計時考慮,而不是像在關系型數據庫查詢時刻使用Order By;
- 無數據結構約定:這是Cassandra最大的優勢,在關系型數據庫中,我們設計數據庫結構時總是慎之又慎,但在Cassandra中不需要預先約定數據結構。
本文參考自《Cassandra: The Definitive Guide》
?
Cassandra數據模型
Colum / Colum Family, SuperColum / SuperColum Family
Column是數據增量最底層(也就是最小)的部分。它是一個包含名稱(name)、值(value)和時間戳(timestamp)的三重元組。
下面是一個用JSON格式表示的column:
{??//?這是一個Column
name:?"emailAddress",?
value:?"arin@example.com",
timestamp:?123456789??
}???????
需要注意的是,name和value都是二進制的(技術上指byte[]),并且可以是任意長度。
與HBase相比,除了Colum/Colum Family外,Cassandra還支持SuperColum/SuperColum Family。
SuperColum與Colum的區別就是,標準Column的value是一個“字符串”,而?SuperColumn的value是一個包含多個Column的map,另一個細微的差別是:SuperColumn沒有時間戳。
{?//?這是一個SuperColumn?
name:?"homeAddress",
//?無限數量的Column???
value:?{?
street:?{name:?"street",?value:?"1234?x?street",?timestamp:?123456789},
city:?{name:?"city",?value:?"san?francisco",?timestamp:?123456789},?
zip:?{name:?"zip",?value:?"94107",?timestamp:?123456789},
}
}
Column Family(CF)是某個特定Key的Colum集合,是一個行結構類型,每個CF物理上被存放在單獨的文件中。從概念上看,CF像數據庫中的Table。
SuperColum Family概念上和Column Family(CF)相似,只不過它是Super Colum的集合。
?
Colum排序
不同于數據庫可以通過Order by定義排序規則,Cassandra取出的數據順序是總是一定的,數據保存時已經按照定義的規則存放,所以取出來的順序已經確定了。另外,Cassandra按照column name而不是column value來進行排序。
Cassandra可以通過Colum Family的CompareWith屬性配置Colume值的排序,在SuperColum中,則是通過SuperColum Family的CompareSubcolumnsWith屬性配置Colum的排序。
Cassandra提供了以下一些選:BytesType,UTF8Type,LexicalUUIDType,TimeUUIDType,AsciiType,?Column name識別成為不同的類型,以此來達到靈活排序的目的。
本文轉自張昺華-sky博客園博客,原文鏈接:http://www.cnblogs.com/bonelee/p/6278657.html,如需轉載請自行聯系原作者