加载中…
个人资料
邓侃
邓侃 新浪个人认证
  • 博客等级:
  • 博客积分:0
  • 博客访问:632,281
  • 关注人气:1,600
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

解剖 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

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有