您的位置:首页 > 其它

Cassandra数据模型

2010-02-26 16:27 323 查看
提起NoSQL
这个话题,仿佛不应该是DBA
要关注的事,而是架构师应该关心的。但是作为一名DBA
,在使用传统的关系型思想建模时,应该有必要了解NoSQL
的建模方法。

各种NoSQL
数据库有很多,我最关注的还是BigTable

类型,因为它是一个高可用可扩展的分布式计算平台,用来处理海量的结构化数据,而数据库同样也是处理结构化数据,所以除了没有SQL
,在数据模型方面有相似之处。Cassandra

是facebook
开源出来的一个版本,可以认为是BigTable
的一个开源版本,目前twitter
和digg.com
在使用。我们尝试从DBA
的角度出发去理解Cassandra
的数据模型。

NoSQL
并不能简单的理解为No SQL

,其本质应该是No Relational


也就是说它不是基于关系型的理论基础,而我们所有传统的数据库都是基于这套理论而发展起来的,所以SQL
并不是问题的关键所在,比如有些NoSQL
数据库 可以提供SQL
类型的接口,允许你通过类SQL
的语法去访问数据。而Friendfeed
则是反其道而行之,利用关系型数据库MySQL
,采用了去关系化 的设计方法,去实现自己的KeyValue
存储。所以NoSQL
的本质是No Relational.

Cassandra
特点:

1.
灵活的schema
,不需要象数据库一样预先设计schema
,增加或者删除字段非常方便(on the fly
)。

2.
支持range
查询:可以对Key
进行范围查询。

3.
高可用,可扩展:单点故障不影响集群服务,可线性扩展。

Keyspace


Cassandra
中的最大组织单元,里面包含了一系列Column
family
,Keyspace
一般是应用程序的名称。你可以把它理解为Oracle
里面的一个schema
,包含了一系列的对象。

Column
family

(CF



CF
是某个特定Key
的数据集合,每个CF
物理上被存放在单独的文件中。从概念上看,CF
有点象数据库中的Table.

Key


数据必须通过Key
来访问,Cassandra
允许范围查询,例如:
start => '10050', :finish => '10070'


Column


在Cassandra
中字段是最小的数据单元,column
和value
构成一个对,比如:name:“jacky”
,column
是name
,value
是jacky
,每个column:value
后都有一个时间戳:timestamp


和数据库不同的是,Cassandra
的一行中可以有任意多个column
,而且每行的column
可以是不同的。从数据库设计的角度,你可以理解 为表上有两个字段,第一个是Key
,第二个是长文本类型,用来存放很多的column
。这也是为什么说Cassandra
具备非常灵活schema
的原 因。

Super
column


Super column
是一种特殊的column
,里面可以存放任意多个普通的column
。而且一个CF
中同样可以有任意多个Super column
,一个CF
只能定义使用Column
或者Super column
,不能混用。下面是Super column
的一个例子,homeAddress
这个Super column
有三个字段:分别是street
,city
和zip


homeAddress: {street: "binjiang road",city: "hangzhou",zip: "310052",}

Sorting


不同于数据库可以通过Order by
定义排序规则,Cassandra
取出的数据顺序是总是一定的,数据保存时已经按照定义的规则存放,所以取出来的顺序已经确定了,这是一个巨大的性能优势。有意思的是,Cassandra

按照column name
而不是column value
来进行排序,

它 定义了以下几种选项:BytesType, UTF8Type, LexicalUUIDType, TimeUUIDType, AsciiType,

和LongType
,用来定义如何按照column name
来排序。实际上,就是把column name
识别成为不同的类型,以此来达到灵活排序的目的。UTF8Type
是把column name
转换为UTF8
编码来进行排序,LongType
转换成为64
位long
型,TimeUUIDType
是按照基于时间的UUID
来排序。例如:

Column name
按照LongType
排序:

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

{name: 123, value: "hellodba"},

{name: 976, value: "Cassandra"},

{name: 832416, value: "bigtable"}

Column name
按照UTF8Type
排序:

{name: 123, value: "hellodba"},

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

{name: 832416, value: "bigtable"}

{name: 976, value: "Cassandra"}

下面我们看twitter
的Schema


<Keyspace Name="Twitter">

<ColumnFamily CompareWith="UTF8Type" Name="Statuses" />

<ColumnFamily CompareWith="UTF8Type" Name="StatusAudits" />

<ColumnFamily CompareWith="UTF8Type" Name="StatusRelationships"

CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" />

<ColumnFamily CompareWith="UTF8Type" Name="Users" />

<ColumnFamily CompareWith="UTF8Type" Name="UserRelationships"

CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" />

</Keyspace>

我们看到一个叫Twitter
的keyspace
,包含若干个CF
,其中StatusRelationships
和 UserRelationships
被定义为包含Super column
的CF
,CompareWith
定义了column
的排序规则,CompareSubcolumnsWith
定义了subcolumn
的排序 规则,这里使用了两种:TimeUUIDType
和UTF8Type
。我们没有看到任何有关column
的定义,这意味着column
是可以灵活变更的。

为了方便大家理解,我会尝试着用关系型数据库的建模方法去描述Twitter
的Schema
,但千万不要误认为这就是Cassandra
的数据模型

,对于Cassandra
来说,每一行的colunn
都可以是任意的,而不是象数据库一样需要在建表时就创建好。



Users CF
记录用户的信息,Statuses CF
记录tweets
的内容,StatusRelationships CF
记录用户看到的tweets
,UserRelationships CF
记录用户看到的followers
。我们注意到排序方式是TimeUUIDType
,这个类型是按照时间进行排序的UUID
字段,column name
是用UUID
函数产生(这个函数返回了一个UUID
,这个UUID
反映了当前的时间,可以根据这个UUID
来排序,有点类似于timestamp
一样),所以得到结果是按照时间来排序的。使用过twitter
的人都知道,你总是可以看到自己最新的tweets
或者最新的friends.

存储


Cassandra
是基于列存储的(Bigtable
也是一样)
,这个和基于列的数据库是一个道理。



API


下面是数据库,Bigtable
和Cassandra API
的对比:

Relational
SELECT `column` FROM `database`.`table` WHERE `id` = key;

BigTable
table.get(key, "column_family:column")

Cassandra: standard model
keyspace.get("column_family", key, "column")

Cassandra: super column model
keyspace.get("column_family", key, "super_column", "column")

我对Cassandra
数据模型的理解:


1.column name
存放真正的值,而value
是空。因为Cassandra
是按照column name
排序,而且是按列存储的,所以往往利用column name
存放真正的值,而value
部分则是空。例如:“jacky”:“null”
,“fenng”:”null”

2.Super column
可以看作是一个索引,有点象关系型数据库中的外键,利用super column
可以实现快速定位,因为它可以返回一堆column
,而且是排好序的。

3.
排序在定义时就确定了,取出的数据肯定是按照确定的顺序排列的,这是一个巨大的性能优势。

4.
非常灵活的schema
,column
可以灵活定义。实际上,colume name
在很多情况下,就是value
(是不是有点绕)。

5.
每个column
后面的timestamp
,我并没有找到明确的说明,我猜测可能是数据多版本,或者是底层清理数据时需要的信息。

最后说说架构,我认为架构的核心就是有所取舍

,不管是CAP

还是BASE

,讲的都是这个原则。架构之美在于没有任何一种架构可以完美的解决各种问题,数据库和NoSQL
都有其应用场景,我们要做的就是为自己找到合适的架构。

–EOF–

这篇文章,我参考了up
and running with cassandra

,除此以外,我还参考了twitter
提供的API
,它帮助我理解twitter
的schema
设计。这篇文章,肯定有很多理解不正确的地方,希望朋友们指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: