大話Cassandra資料模型

來源:互聯網
上載者:User

Cassandra是一個開源的分散式資料庫,結合了Dynamo的Key/Value與Bigtable的面向列的特點。

Cassandra的特點如下:

1.靈活的schema:不需要象資料庫一樣預先設計schema,增加或者刪除欄位非常方便(on the fly)。

2.支援range查詢:可以對Key進行範圍查詢。

3.高可用,可擴充:單點故障不影響叢集服務,可線性擴充。

我們可以將Cassandra的資料模型想象成一個四維或者五維的Hash。

Column

Column是Cassandra中最小的資料單元。它是一個3元的資料類型,包含:name,value和timestamp。

將一個Column用JSON的形式表現出來如下:

   1: {  // 這是一個column

   2:     name: "逖靖寒的世界",

   3:     value: "gpcuster@gmali.com",

   4:     timestamp: 123456789

   5: } 

為了簡單起見,我們可以忽略timestamp。就把column想象成一個name/value即可。

注意,這裡提到的name和value都是byte[]類型的,長度不限。

SuperColumn

我們可以將SuperColumn想象成Column的數組,它包含一個name,以及一系列相應的Column。

將一個SuperColumn用JSON的形式表現如下:

   1: {   // 這是一個SuperColumn

   2:     name: "逖靖寒的世界",

   3:     // 包含一系列的Columns

   4:     value: {

   5:         street: {name: "street", value: "1234 x street", timestamp: 123456789},

   6:         city: {name: "city", value: "san francisco", timestamp: 123456789},

   7:         zip: {name: "zip", value: "94107", timestamp: 123456789},

   8:     }

   9: }

 

Columns和SuperColumns都是name與value的組合。最大的不同在於Column的value是一個“string”,而SuperColumn的value是Columns的Map。

還有一點需要注意的是:SuperColumn’本身是不包含timestamp的。

ColumnFamily

ColumnFamily是一個包含了許多Row的結構,你可以將它想象成RDBMS中的Table。

每一個Row都包含有client提供的Key以及和該Key關聯的一系列Column。

我們可以看看結構:

   1: UserProfile = { // 這是一個ColumnFamily

   2:     phatduckk: {   // 這是對應ColumnFamily的key

   3:         // 這是Key下對應的Column

   4:         username: "gpcuster",

   5:         email: "gpcuster@gmail.com",

   6:         phone: "6666"

   7:     }, // 第一個row結束

   8:     ieure: {   // 這是ColumnFamily的另一個key

   9:         //這是另一個Key對應的column

  10:         username: "pengguo",

  11:         email: "pengguo@live.com",

  12:         phone: "888"

  13:         age: "66"

  14:     },

  15: }

ColumnFamily的類型可以為Standard,也可以是Super類型。

我們剛剛看到的那個例子是一個Standard類型的ColumnFamily。Standard類型的ColumnFamily包含了一系列的Columns(不是SuperColumn)。

Super類型的ColumnFamily包含了一系列的SuperColumn,但是並不能像SuperColumn那樣包含一系列Standard ColumnFamily。

這是一個簡單的例子:

   1: AddressBook = { // 這是一個Super類型的ColumnFamily

   2:     phatduckk: {    // key

   3:         friend1: {street: "8th street", zip: "90210", city: "Beverley Hills", state: "CA"}, 

   4:         John: {street: "Howard street", zip: "94404", city: "FC", state: "CA"},

   5:         Kim: {street: "X street", zip: "87876", city: "Balls", state: "VA"},

   6:         Tod: {street: "Jerry street", zip: "54556", city: "Cartoon", state: "CO"},

   7:         Bob: {street: "Q Blvd", zip: "24252", city: "Nowhere", state: "MN"},

   8:         ...

   9:     }, // row結束

  10:     ieure: {     // key

  11:         joey: {street: "A ave", zip: "55485", city: "Hell", state: "NV"},

  12:         William: {street: "Armpit Dr", zip: "93301", city: "Bakersfield", state: "CA"},

  13:     },

  14: }

Keyspace

Keyspace是我們的資料最外層,你所有的ColumnFamily都屬於某一個Keyspace。一般來說,我們的一個程式應用只會有一個Keyspace。

簡單測試

我們將Cassandra運行起來以後,啟動命令列,執行如下操作:

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.

這個時候,Cassandra中就已經有3條資料了。

其中插入資料的各個欄位含義如下:

接下來,我們執行查詢操作:

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.

這樣,我們就可以將之前插入的資料查詢出來了。

排序

有一點需要明確,我們使用Cassandra的時候,資料在寫入的時候就已經排好順序了。

在某一個Key內的所有Column都是按照它的Name來排序的。我們可以在storage-conf.xml檔案中指定排序的類型。

目前Cassandra提供的排序類型有:BytesType, UTF8Type,LexicalUUIDType, TimeUUIDType, AsciiType,和LongType。

現在假設你的未經處理資料如下:

{name: 123, value: "hello there"},

{name: 832416, value: "kjjkbcjkcbbd"},

{name: 3, value: "101010101010"},

{name: 976, value: "kjjkbcjkcbbd"}

當我們storage-conf.xml檔案中指定排序的類型為LongType時:

<!--

      ColumnFamily 在 storage-conf.xml 中定義

-->

<ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/>

排序後的資料就是這樣的:

{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"/>

排序後的資料就是這樣的:

{name: 123, value: "hello there"},   
{name: 3, value: "101010101010"},

{name: 832416, value: "kjjkbcjkcbbd"},

{name: 976, value: "kjjkbcjkcbbd"}

大家可以看到,指定的排序類型不一樣,排序的結果也是完全不同的。

對於SuperColumn,我們有一個額外的排序維度,所以我們可以指定CompareSubcolumnsWith來進行另一個維度排序類型。

假設我們的未經處理資料如下:

{ // 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,那麼排序後的結果為:

{

    // 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的排序功能是允許我們自己實現的,只要你繼承org.apache.cassandra.db.marshal.IType就可以了。

參考文檔

WTF is a SuperColumn? An Intro to the Cassandra Data Model

DataModel

 

更多關於Cassandra的文章:http://www.cnblogs.com/gpcuster/tag/Cassandra/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.