cassandra数据模型

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: 
    "[email protected]"
    ,   

  4. timestamp: 123456789  

  5. }  


为了简单起见,我们可以忽略timestamp。就把column想象成一个name/value即可。

注意,这里提到的name和value都是byte[]类型的,长度不限。

SuperColumn

我们可以将SuperColumn想象成Column的数组,它包含一个name,以及一系列相应的Column。

将一个SuperColumn用JSON的形式表现如下:

  
  
  
  
  1. {     

  2. // 这是一个SuperColumn   
     

  3. name: 
    "逖靖寒的世界"
    ,  

  4.  
    // 包含一系列的Columns 
     

  5. value: {    

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

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

  8. zip: {name: 
    "zip"
    , value: 
    "94107"
    , timestamp: 123456789},    

  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 = {   

  2. // 这是一个ColumnFamily 
     

  3. phatduckk: {     

  4. // 这是对应ColumnFamily的key  
     

  5. // 这是Key下对应的Column  
     

  6.  username: 
    "gpcuster"
    ,    

  7.  email: 
    "[email protected]"
    ,   

  8. phone: 
    "6666"
         

  9.  }, 
    // 第一个row结束 
     

  10. ieure: {    

  11.  
    // 这是ColumnFamily的另一个key 
     

  12. //这是另一个Key对应的column 
     

  13.  username: 
    "pengguo"
    ,   

  14.  email: 
    "[email protected]"
    ,    

  15.  phone: 
    "888"
       

  16.  age: 
    "66"
        

  17.  },    

  18.  }  


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运行起来以后,启动命令行,执行如下操作:

  
  
  
  
  1. cassandra
    >
     set Keyspace1.Standard1['jsmith']['first'] = 'John'   

  2. Value inserted.   

  3. cassandra
    >
     set Keyspace1.Standard1['jsmith']['last'] = 'Smith'   

  4. Value inserted.   

  5. cassandra
    >
     set Keyspace1.Standard1['jsmith']['age'] = '42'   

  6. Value inserted. 


这个时候,Cassandra中就已经有3条数据了。

其中插入数据的各个字段含义如下:

cassandra数据模型_第1张图片  

接下来,我们执行查询操作:

  
  
  
  
  1. cassandra
    >
     get Keyspace1.Standard1['jsmith']   

  2.   (
    column
    =
    age

    value
    =
    42

    timestamp
    =
    1249930062801
    )   

  3.   (
    column
    =
    first

    value
    =
    John

    timestamp
    =
    1249930053103
    )   

  4.   (
    column
    =
    last

    value
    =
    Smith

    timestamp
    =
    1249930058345
    )   

  5. Returned 3 rows. 


这样,我们就可以将之前插入的数据查询出来了。

 

 

//最后可以做一点说明,cassandra中,可以把Keyspace1看成是一个单独的数据库,standard1看成是一些表的集合,key看成是某个单独表的名称,每个单独表都是由一组column组成的,每个column就是一个<name,value>向量。

排序

有一点需要明确,我们使用Cassandra的时候,数据在写入的时候就已经排好顺序了。

在某一个Key内的所有Column都是按照它的Name来排序的。我们可以在storage-conf.xml文件中指定排序的类型。

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

现在假设你的原始数据如下:

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

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

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

  4. {name: 976, value: "kjjkbcjkcbbd"} 


当我们storage-conf.xml文件中指定排序的类型为LongType时:

<!--
      ColumnFamily 在 storage-conf.xml 中定义
-->
<ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/>

排序后的数据就是这样的:

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

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

  3. {name: 976, value: "kjjkbcjkcbbd"},   

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


如果我们指定排序的类型为UTF8Type

  
  
  
  
  1. <!-- 
     

  2.       ColumnFamily 在 storage-conf.xml 中定义
     

  3. -->
       

  4. <
    ColumnFamily
     
    CompareWith
    =
    "UTF8Type"
     
    Name
    =
    "CF_NAME_HERE"
    />
     


排序后的数据就是这样的:

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

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

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

  4. {name: 976, value: "kjjkbcjkcbbd"} 


大家可以看到,指定的排序类型不一样,排序的结果也是完全不同的。

对于SuperColumn,我们有一个额外的排序维度,所以我们可以指定CompareSubcolumnsWith来进行另一个维度的排序类 型。

假设我们的原始数据如下:

  
  
  
  

  1. // first SuperColumn from a Row 
     

  2.     name: 
    "workAddress"
    ,   

  3.     
    // and the columns within it 
     

  4.     value: {   

  5.         street: {name: 
    "street"
    , value: 
    "1234 x street"
    },   

  6.         city: {name: 
    "city"
    , value: 
    "san francisco"
    },   

  7.         zip: {name: 
    "zip"
    , value: 
    "94107"
    }   

  8.     }   

  9. },   


  10. // another SuperColumn from same Row 
     

  11.     name: 
    "homeAddress"
    ,   

  12.     
    // and the columns within it 
     

  13.     value: {   

  14.         street: {name: 
    "street"
    , value: 
    "1234 x street"
    },   

  15.         city: {name: 
    "city"
    , value: 
    "san francisco"
    },   

  16.         zip: {name: 
    "zip"
    , value: 
    "94107"
    }   

  17.     }   



然后我们定义CompareSubcolumnsWith和CompareWith的排序类型都是UTF8Type,那么排序后的结果为:

  
  
  
  
  1. {   

  2.     
    // this one's first b/c when treated as UTF8 strings 
     

  3.     { 
    // another SuperColumn from same Row 
     

  4.         
    // This Row comes first b/c "homeAddress" is before "workAddress"            
     

  5.         name: 
    "homeAddress"
    ,   

  6.         
    // the columns within this SC are also sorted by their names too 
     

  7.         value: {   

  8.             
    // see, these are sorted by Column name too 
     

  9.             city: {name: 
    "city"
    , value: 
    "san francisco"
    },                  

  10.             street: {name: 
    "street"
    , value: 
    "1234 x street"
    },   

  11.             zip: {name: 
    "zip"
    , value: 
    "94107"
    }   

  12.         }   

  13.     },          

  14.     name: 
    "workAddress"
    ,   

  15.     value: {   

  16.         
    // the columns within this SC are also sorted by their names too 
     

  17.         city: {name: 
    "city"
    , value: 
    "san francisco"
    },              

  18.         street: {name: 
    "street"
    , value: 
    "1234 x street"
    },   

  19.         zip: {name: 
    "zip"
    , value: 
    "94107"
    }   

  20.     }   



再额外提一句,Cassandra的排序功能是允许我们自己实现的,只要你继承 org.apache.cassandra.db.marshal.IType就可以了。

原文标题:大话Cassandra数据模型

链接: http://www.cnblogs.com/gpcuster/archive/2010/03/12/1684072.html

你可能感兴趣的:(数据库,json,schema,扩展,email,cassandra)