詳解Cassandra數(shù)據(jù)模型
Cassandra是一個(gè)開源的分布式數(shù)據(jù)庫,結(jié)合了Dynamo的Key/Value與Bigtable的面向列的特點(diǎn)。
Cassandra的特點(diǎn)如下:
1.靈活的schema:不需要象數(shù)據(jù)庫一樣預(yù)先設(shè)計(jì)schema,增加或者刪除字段非常方便(on the fly)。
2.支持range查詢:可以對(duì)Key進(jìn)行范圍查詢。
3.高可用,可擴(kuò)展:?jiǎn)吸c(diǎn)故障不影響集群服務(wù),可線性擴(kuò)展。
我們可以將Cassandra的數(shù)據(jù)模型想象成一個(gè)四維或者五維的Hash。
Column
Column是Cassandra中最小的數(shù)據(jù)單元。它是一個(gè)3元的數(shù)據(jù)類型,包含:name,value和timestamp。
將一個(gè)Column用JSON的形式表現(xiàn)出來如下:
- { // 這是一個(gè)column
- name: "逖靖寒的世界",
- value: "gpcuster@gmali.com",
- timestamp: 123456789
- }
為了簡(jiǎn)單起見,我們可以忽略timestamp。就把column想象成一個(gè)name/value即可。
注意,這里提到的name和value都是byte[]類型的,長(zhǎng)度不限。
SuperColumn
我們可以將SuperColumn想象成Column的數(shù)組,它包含一個(gè)name,以及一系列相應(yīng)的Column。
將一個(gè)SuperColumn用JSON的形式表現(xiàn)如下:
- {
- // 這是一個(gè)SuperColumn
- name: "逖靖寒的世界",
- // 包含一系列的Columns
- 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},
- }
- }
Columns和SuperColumns都是name與value的組合。最大的不同在于Column的value是一個(gè)“string”,而SuperColumn的value是Columns的Map。
還有一點(diǎn)需要注意的是:SuperColumn’本身是不包含timestamp的。
ColumnFamily
ColumnFamily是一個(gè)包含了許多Row的結(jié)構(gòu),你可以將它想象成RDBMS中的Table。
每一個(gè)Row都包含有client提供的Key以及和該Key關(guān)聯(lián)的一系列Column。
我們可以看看結(jié)構(gòu):
- UserProfile = {
- // 這是一個(gè)ColumnFamily
- phatduckk: {
- // 這是對(duì)應(yīng)ColumnFamily的key
- // 這是Key下對(duì)應(yīng)的Column
- username: "gpcuster",
- email: "gpcuster@gmail.com",
- phone: "6666"
- }, // 第一個(gè)row結(jié)束
- ieure: {
- // 這是ColumnFamily的另一個(gè)key
- //這是另一個(gè)Key對(duì)應(yīng)的column
- username: "pengguo",
- email: "pengguo@live.com",
- phone: "888"
- age: "66"
- },
- }
ColumnFamily的類型可以為Standard,也可以是Super類型。
我們剛剛看到的那個(gè)例子是一個(gè)Standard類型的ColumnFamily。Standard類型的ColumnFamily包含了一系列的Columns(不是SuperColumn)。
Super類型的ColumnFamily包含了一系列的SuperColumn,但是并不能像SuperColumn那樣包含一系列Standard ColumnFamily。
這是一個(gè)簡(jiǎn)單的例子:
- AddressBook = { // 這是一個(gè)Super類型的ColumnFamily
- phatduckk: { // key
- friend1: {street: "8th street", zip: "90210", city: "Beverley Hills", state: "CA"},
- John: {street: "Howard street", zip: "94404", city: "FC", state: "CA"},
- Kim: {street: "X street", zip: "87876", city: "Balls", state: "VA"},
- Tod: {street: "Jerry street", zip: "54556", city: "Cartoon", state: "CO"},
- Bob: {street: "Q Blvd", zip: "24252", city: "Nowhere", state: "MN"},
- ...
- }, // row結(jié)束
- ieure: { // key
- joey: {street: "A ave", zip: "55485", city: "Hell", state: "NV"},
- William: {street: "Armpit Dr", zip: "93301", city: "Bakersfield", state: "CA"},
- },
- }
Keyspace
Keyspace是我們的數(shù)據(jù)最外層,你所有的ColumnFamily都屬于某一個(gè)Keyspace。一般來說,我們的一個(gè)程序應(yīng)用只會(huì)有一個(gè)Keyspace。
簡(jiǎn)單測(cè)試
我們將Cassandra運(yùn)行起來以后,啟動(dòng)命令行,執(zhí)行如下操作:
- cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John'
- Value inserted.
- cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
- Value inserted.
- cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42'
- Value inserted.
這個(gè)時(shí)候,Cassandra中就已經(jīng)有3條數(shù)據(jù)了。
其中插入數(shù)據(jù)的各個(gè)字段含義如下:
接下來,我們執(zhí)行查詢操作:
- cassandra> get Keyspace1.Standard1['jsmith']
- (column=age, value=42; timestamp=1249930062801)
- (column=first, value=John; timestamp=1249930053103)
- (column=last, value=Smith; timestamp=1249930058345)
- Returned 3 rows.
這樣,我們就可以將之前插入的數(shù)據(jù)查詢出來了。
排序
有一點(diǎn)需要明確,我們使用Cassandra的時(shí)候,數(shù)據(jù)在寫入的時(shí)候就已經(jīng)排好順序了。
在某一個(gè)Key內(nèi)的所有Column都是按照它的Name來排序的。我們可以在storage-conf.xml文件中指定排序的類型。
目前Cassandra提供的排序類型有:BytesType, UTF8Type,LexicalUUIDType, TimeUUIDType, AsciiType,和LongType。
現(xiàn)在假設(shè)你的原始數(shù)據(jù)如下:
- {name: 123, value: "hello there"},
- {name: 832416, value: "kjjkbcjkcbbd"},
- {name: 3, value: "101010101010"},
- {name: 976, value: "kjjkbcjkcbbd"}
當(dāng)我們storage-conf.xml文件中指定排序的類型為L(zhǎng)ongType時(shí):
<!--
ColumnFamily 在 storage-conf.xml 中定義
-->
<ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/>
排序后的數(shù)據(jù)就是這樣的:
- {name: 3, value: "101010101010"},
- {name: 123, value: "hello there"},
- {name: 976, value: "kjjkbcjkcbbd"},
- {name: 832416, value: "kjjkbcjkcbbd"}
如果我們指定排序的類型為UTF8Type
- <!--
- ColumnFamily 在 storage-conf.xml 中定義
- -->
- <ColumnFamily CompareWith="UTF8Type" Name="CF_NAME_HERE"/>
排序后的數(shù)據(jù)就是這樣的:
- {name: 123, value: "hello there"},
- {name: 3, value: "101010101010"},
- {name: 832416, value: "kjjkbcjkcbbd"},
- {name: 976, value: "kjjkbcjkcbbd"}
大家可以看到,指定的排序類型不一樣,排序的結(jié)果也是完全不同的。
對(duì)于SuperColumn,我們有一個(gè)額外的排序維度,所以我們可以指定CompareSubcolumnsWith來進(jìn)行另一個(gè)維度的排序類型。
假設(shè)我們的原始數(shù)據(jù)如下:
- { // first SuperColumn from a Row
- name: "workAddress",
- // and the columns within it
- value: {
- street: {name: "street", value: "1234 x street"},
- city: {name: "city", value: "san francisco"},
- zip: {name: "zip", value: "94107"}
- }
- },
- { // another SuperColumn from same Row
- name: "homeAddress",
- // and the columns within it
- value: {
- street: {name: "street", value: "1234 x street"},
- city: {name: "city", value: "san francisco"},
- zip: {name: "zip", value: "94107"}
- }
- }
然后我們定義CompareSubcolumnsWith和CompareWith的排序類型都是UTF8Type,那么排序后的結(jié)果為:
- {
- // this one's first b/c when treated as UTF8 strings
- { // another SuperColumn from same Row
- // This Row comes first b/c "homeAddress" is before "workAddress"
- name: "homeAddress",
- // the columns within this SC are also sorted by their names too
- value: {
- // see, these are sorted by Column name too
- city: {name: "city", value: "san francisco"},
- street: {name: "street", value: "1234 x street"},
- zip: {name: "zip", value: "94107"}
- }
- },
- name: "workAddress",
- value: {
- // the columns within this SC are also sorted by their names too
- city: {name: "city", value: "san francisco"},
- street: {name: "street", value: "1234 x street"},
- zip: {name: "zip", value: "94107"}
- }
- }
再額外提一句,Cassandra的排序功能是允許我們自己實(shí)現(xiàn)的,只要你繼承org.apache.cassandra.db.marshal.IType就可以了。
原文標(biāo)題:大話Cassandra數(shù)據(jù)模型
鏈接: http://www.cnblogs.com/gpcuster/archive/2010/03/12/1684072.html