解剖 Cassandra 【2】 Sorting
(2012-06-27 13:45:32)
标签:
云计算
nosql
it
|
分类:
技术评论
|
by 盛楠、邓侃、朱小杰
关于Cassandra 的 Data Model,除了前边介绍的几个基本概念,另外一个重要的部分,就是数据的排序。
ColumnFamily 的数据,在写入的时候,就按照指定的规则,进行了排序。
在用户更新某个 ColumnFamily 中的原有数据,或者插入新数据时,这个 ColumnFamily
中的数据,一直保持着有序的状态,而且排序的规则一直遵循着创建时制定的规则。
1. 排序选项
Cassandra 有以下预制的 Sorting 规则: BytesType, UTF8Type, LexicalUUIDType,
TimeUUIDType, AsciiType, and LongType。
我们来看一个例子,假如有以下几个字符串:“123”、“832416”、“3”、“976”,
1. 用 LongType 排序的结果是:“3”、“123”、“976”、“832416”。
2. 用 UTF8Type 排序的结果是:“123”、“3”、“832416”、“976”。
当然 Cassandra
允许使用者,自行定义其它的排序的办法,只要实现org.apache.cassandra.db.marshal.AbstractType方法,并且指定自己的类名即可。
2. Row 的排序
一个 ColumnFamily中往往包含多行。行与行之间的先后顺序,是按照每行的 Row-key来进行排序的。
Row-key的比较规则,取决于创建ColumnFamily 时,设置的CompareWith选项。
假如有个 ColumnFamily,存放着四条微博:
TweetCF =
{
123:{name: "Content",
value:"hello there", timestamp: null},
832416:{name: "Content",
value:"kjjkbcjkcbbd", timestamp: null},
3:{name: "Content,
value:"101010101010", timestamp: null},
976: {name: "Content", value:"kjjkbcjkcbbd", timestamp:
null}
}
这个 Column Family 中,有四行。每行除了 Row-key,只有一个 column。这个 column 的
Name,永远是 “Content”,而在不同的行中,每行的 “Content”Column 的 Value,却各不一样,有一个是
“hello there”,另一个是 “kjjkbcjkcbbd”,等等。
如果用户在创建 TweetCF ColumnFamily 时,把storage-conf.xml 文件中的 CompareWith
的规则,制定为 “LongType”,即,
<ColumnFamily
CompareWith="LongType" Name="TweetCF"/>
那么就规定了 TweetCF 这个 ColumnFamily的排序规则是 LongType。那么 TweetCF
的内容,按以下顺序,写在硬盘上,
TweetCF =
{
3:{name: "Content, value: …, timestamp: …},
123:{name: "Content", value: …, timestamp: …},
976: {name: "Content", value: …, timestamp: …},
832416:{name: "Content", value: …, timestamp: …}
}
又例如,如果用户在 storage-conf.xml 文件中,规定 TweetCF 的排序规则是 UTF8,即
<ColumnFamily
CompareWith="UTF8Type" Name="TweetCF"/>
那么 TweetCF 的内容,将按以下顺序,写在硬盘上,
TweetCF =
{
123:{name: "Content", value: …, timestamp:
…},
3:{name: "Content, value: …, timestamp: …},
832416:{name: "Content", value: …, timestamp: …},
976: {name: "Content", value: …, timestamp: …}
}
3. Column 的排序
在上述例子中,每个Row中,都只有一个 column。
但是如果一行中有多个columns,那么就要涉及到多个columns的排序问题了。
在 ColumnFamily 中,先对 rows 进行排序,然后在每一个 row 中,对 columns 进行排序。
如前所述,Rows 的排序是按照 row-key 来进行,而 row-key 的比较方法,有 UTF8Type、LongType
等等。
在一个 row 中,如果有多个 columns,这些 columns 的排序,是按照 column name 来进行,而与
column value 无关。至于 column name 的比较方法,与 row-key
的比较方法一样,也有UTF8Type、LongType 等等。
举例说明,假如有一个未经排序的 ColumnFamily 如下。
TweetCF =
{
123: {
{name: "Content", value: "hello there", timestamp:
null},
{name: "Tag", value: "talk", timestamp: null}
},
832416: {
{name: "Content", value: "cooking pork..", timestamp:
null},
{name: "Tag", value: "life, cuisine", timestamp:
null},
{name: "Type", value: "POI", timestamp: null}
},
3: {
{name: "Content", value: "101010101010", timestamp:
null},
{name:"Type", value: "JPG", timestamp: null},
{name: "Size", value: "230K", timestamp: null},
{name: "Tag", value: "travel", timestamp: null}
},
976: {
{name: "Content", value: "kjjkbcjkcbbd", timestamp:
null},
{name: "Category", value: "Note", timestamp: null}
}
}
如果用户在创建 TweetCF ColumnFamily 时,把storage-conf.xml 文件中的 CompareWith
的规则,制定为 “UTF8Type”,即,
<ColumnFamily CompareWith="UTF8Type"
Name="TweetCF"/>
那么 TweetCF 的内容,先按 row 排序,然后再按 column Name 排序的顺序,写在硬盘上,如下所示,
TweetCF =
{
123: {
{name: "Content", value: …, timestamp: …},
{name: "Tag", value: …, timestamp: …}
},
3: {
{name: "Content", value: …, timestamp: …},
{name: "Size", value: …, timestamp: …},
{name: "Tag", value: …, timestamp: …},
{name:"Type", value: …, timestamp: …}
},
832416: {
{name: "Content", value: …, timestamp: …},
{name: "Tag", value: …, timestamp: …},
{name: "Type", value: …, timestamp: …}
},
976: {
{name: "Category", value: …,
timestamp: …},
{name: "Content", value: …, timestamp: …}
}
}
4. SuperColumn 的排序
如果 TweetCF 中有多行,每行的列数不同,而且其中包含
SuperColumns,那么就涉及到SuperColumns中的columns的排序了,例如有一个未经排序的
ColumnFamily 如下,
TweetCF =
{
976:{ // 第一行
{ name:
"6547" // 第一行第一个
SuperColumn
value:{
// 第一行第一个 SuperColumn 的 第一个 Column
{name: "street", value: …, timestamp: …},
// 第一行第一个 SuperColumn 的 第二个 Column
{name: "zip", value: …, timestamp: …},
// 第一行第一个 SuperColumn 的 第三个 Column
{name: "city", value: …, timestamp: …},
// 第一行第一个 SuperColumn 的 第四个 Column
state: {name: "state", value: …, timestamp: …}
}
},
{ name:
"2413" //
第一行第二个 SuperColumn
value:{
{name: "street", value: …, timestamp: …},
{name: "zip", value: …, timestamp: …},
{name: "city", value: …, timestamp: …},
{name: "state", value: …, timestamp: …}
}
}
},
253:{ // 第二行
{ name:
"4215" // 第二行第一个 SuperColumn
value:{
{name:
"street", value: …, timestamp: …},
{name: "zip", value: …, timestamp: …},
{name: "city", value: …, timestamp: …},
{name: "state", value: …, timestamp: …}
}
}
}
}
如同前面几个章节中介绍的,用户可以通过配置storage-conf.xml 中的CompareWith选项,来确定 row
的排序方法,以及每一个 row 中的多个superColumns的排序方法。
除此之外,用户还可以设置CompareSubcolumnsWith
选项,对每一行的每一个SuperColumn中的多个columns来进行排序。
例如,用户在创建 TweetCF ColumnFamily 时,把storage-conf.xml 文件中的 CompareWith
的规则,制定为 “LongType”,
SuperColumn内部的columns的排序规则,制定为“UTF8Type”,即,
<ColumnFamily CompareWith="LongType"
CompareSubcolumnsWith="UTF8Type"
Name="TweetCF"/>
那么 TweetCF 的内容,先按 Row 排序,然后再按 SuperColumn Name 排序的顺序,Row
和SuperColumn 的排序规则,都是 LongType。
而每个SuperColumns内部的 Columns,则按照 Column Name,以 UTF8Type
排序。结果如下,
TweetCF =
{
253:{ //row-key
{ name: "4215"
value:{
{name: "city", value: …, timestamp: …},
{name: "state", value: …, timestamp: …},
{name: "street", value: …, timestamp: …},
{name: "zip", value: …, timestamp: …},
}
}
},
976:{ //row-key
{ name: "2413"
value:{
{name: "city", value: …, timestamp: …},
{name: "state", value: …, timestamp: …},
{name: "street", value: …, timestamp: …},
{name: "zip", value: …, timestamp: …}
}
},
{ name: "6547"
value:{
{name: "city", value: …, timestamp: …},
{name: "state", value: …, timestamp: …},
{name: "street", value: …, timestamp: …},
{name: "zip", value: …, timestamp: …}
}
},
}
}
Reference,
[1] What is a SuperColumn? An introduction to the Cassandra Data
Model.
http://arin.me/blog/wtf-is-a-supercolumn-cassandra-data-model
喜欢
0
赠金笔
加载中,请稍候......