现在开始深入了解一下cassandra的数据模型。cassandra是一种NoSQL数据库,NoSQL并不是指没有SQL语句,而是指NoRelational。cassandra的数据模型结合了Dynamo的key/value和BigTable
的面向列的特点,主要被设计为存储大规模的分布式数据。
PS:图片在这里显示不全,why?要看图片,可以另存为或复制图片地址,在浏览器里打开。

一、cassandra数据模型的特点

1.它基于key-value模型

cassandra的数据库由ColumnFamilies组成,一个ColumnFamily是一个key-value键值对的集合。若和关系型数据库类比,ColumnFamily相当于表,而里面的key-value键值对相当于表里的一条记录。

2.它的key-value模型有多层嵌套

ColumnFamily里的每条记录都是一个key-value对,value部分存放的是无限制的Columns。每个Column都有一个ColumnName和value,因此Column实际也是一个key-value对。但Column的value部分已经是最基本的数据存储单元,不能再向下嵌套了。在这种嵌套下,ColumnFamily的每条记录都包含一个key和一个由Columns组成的value(至少有一个Column),也就是说ColumnFamily的value只是一个中间人,实际存储数据的是value里的Columns。如下图所示。

上面所说的是双层嵌套,还有一种三层嵌套。在这种情况下,ColumnFamily每条记录的value部分不是Columns,而是一种被称为SuperColumn的结构。SuperColumn的key是SuperColumnname,它的value部分可以存储多个Columns,如下图所示:

这样就有以下三种嵌套:

   ColumnFamily: key - value(SuperColumn)SuperColumn: key(SuperColumn name) - value(Column)Column: key(Column name) - value

SuperColumn里不能再存储SuperColumn,因此cassandra的嵌套最多为三层。

3.Column和SuperColumn的name部分都可以用来存储实际数据

首先,它们的name部分可以用来当做属性名。比如在一个存储用户邮箱的记录里,它是这样的:

Column name=Email,value="fykhlp@163.com";

这是我们在传统关系型数据库里所习惯和使用的。但在cassandra里,name部分也可以直接用来存储实际数据。比如在一个只用来存储用户邮箱的记录里,我们可以这样:

Column name="fykhlp@163.com",value=null;

这得益于(a)cassandra的非结构化数据存储,数据的存储不需要固定的位置(b)name部分也是使用字节流存储(关系型数据库的字段名必须是字符),因此可以存储任何类型的数据。

4.Column和SuperColumn按照name的顺序存储

需要注意的是,cassandra并不是按照value的顺序存储数据,而是按照name。关于这点下文会详细说明。

二、cassandra数据模型的构成

在这一部分,将详细讲解cassandra数据模型的各个组成部分。

1.Column

Column是数据存储的最小单位。它是一个包括name、value和timestamp(时间戳)的元祖。下面是一个Column的示例:

{name:"age",value:24,timestamp:123456789
}

方便书写,后文将省略时间戳,我们将Column看成一个name-value对。name和value都是字节流,长度没有限制。

2.SuperColumn

一个SuperColumn是一个真正的name-value对,它没有时间戳。而且它的value部分可以包含无限个Column,并且用Column的name部分作为关键字。下面是一个SuperColumn的示例:

{name:"homeAddress"//value部分是多个Columnsvalue://这里的key是Column的name部分street:{name:"street",value:"XiTuCheng road"},city:{name:"city",value:"BeiJing"},zip:{name:"zip",value:"410083"},
}

在后面,不再写出name和value,上文将简写为:

homeAddress:{street:"XiTuCheng road",city:"BeiJing",zip:"410083",
}

3.Row

在介绍下文的ColumnFamily前,我们先熟悉一下Row。在cassandra里,每个ColumnFamily都存在一个单独的文件里,这个文件以Row为单位存储并排序。因此,我们应尽量将相关的Column放在同一个ColumnFamily里。

ColumnFamily的组成是一行行的Row,一个Row就是一个key-value对,key决定数据将被存在哪台机器上(笔记二的token部分有解释),value部分就是Columns或SuperColumns。

4.ColumnFamily

ColumnFamily是一个可以包含无数个Row的结构,又因为Row的value部分是Columns或SuperColumns,因此ColumnFamily实际是Columns和SuperColumns的容器。ColumnFamily对应关系型数据库里的“表”。下面给出ColumnFamily和Row的一个简单示例(使用Column):

User={//这是一个ColumnFamily,名字是Userzhangsan:{//这是一个Row,Row的key是zhangsan//下面的value可以有无限制的Columns,这里有两个username:"zhangsan",email:"zhangsan@163.com",},//这个Row结束了lisi:{//这是第二个Row,Row的key是lisi//value部分,依然是Columns,lisi有三个username:"lisi",email:"lisi@163.com",phone:"123456"},//Row结束
}

又如下图所示:

在这个层面没有设计模式的要求,Row没有预先定义它们应该包含的Columns列表,就如上面的示例,李四可以随意的多一个phone的Column。一个Row可能有成千上万个Columns而另一个Row可能只有一个Column。cassandra在这一点上有无法比拟的灵活性。

5.属性为Super的ColumnFamily

上面的示例是一个type为标准的(Standard)ColumnFamily,另外也有Super的ColumnFamily,这取决于我们创建ColumnFamily时的定义。顾名思义,一个类型为Super的ColumnFamily的Row存储的不是Columns,而是SuperColumns。在这种情况下,一个Row的value部分有若干个SuperColumns,一个SuperColumns的value部分又有若干个Columns。如下图所示:

为什么要有SuperColumn呢?SuperColumn提供了比普通Column多一级的一对多关系。Column只能让一个key存储一组相关联的Columns,而这个能让一个key存储多组相关联的Columns。

这里给出一个应用:假设我们提供一种网上地址本的服务,用户可以在这保存他的朋友们的地址,而地址又是由不同的属性如邮编、街道、城市等组成。这时候我们可以采用SuperColumn。对于ColumnFamily,它的key使用的是用户自己的名字,value部分是若干SuperColumns。每个SuperColumns的name部分是用户某个朋友的名字,value部分是若干Columns,存储地址的各个属性。下面是示例:

AddressBook={//这是一个SuperColumnFamily,名字是AddressBookzhangsan:{//这是一个Row,key是zhangsan,张三的地址本//下面是Row的Value部分,可以有任意个SuperColumnslisi:{//这是SuperColumn的name//下面是Columns,表示地址street:"XiTuCheng road",zip:"410083",city:"BeiJing"},wangwu:{//另一个SuperColumnstreet:"XiTuCheng road",zip:"410083",city:"BeiJing"},zhaoliu:{//SuperColumnstreet:"XiTuCheng road",zip:"410083",city:"BeiJing"},.......}//end the row of zhangsanlisi:{//这是另一个Row,key是lisi,李四的地址本wangwu:{//SuperColumnstreet:"XiTuCheng road",zip:"410083",city:"BeiJing"},zhangsan:{//SuperColumnstreet:"XiTuCheng road",zip:"410083",city:"BeiJing"},.......}
}

6.KeySpace

KeySpace是最外层的容器,也是最大的容器,通常一个应用程序对应一个KeySpace。所有的ColumnFamily都位于一个KeySpace里面,它相当于关系数据库里的DB。

三、cassandra的数据排序

前面所介绍的是cassandra里各种数据容器的概念,现在来看看数据模型的另外一个关键地方即数据是如何排序的。cassandra和关系型数据库不同,你无法在取出数据时指定一种排序(orderby)。数据在你存储到集群,被写入数据库时已经按照预定的规则被排好序。当你取出数据时,它们的顺序已经确定了。

如前问所说,cassandra是按照name而不是value进行排序。cassandra在写入数据的时候,每个row中的所有Columns会按照name自动排好序。排序的规则由ColumnFamily的CompareWith选项确定,可选的有:BytesType,UTF8Type,LexicalUUIDType,TimeUUIDType,AsciiType和LongType。这些选项将ColumnName看作不同的数据类型来排序,如LongType将它视为64bitLong类型。如下面给出的例子:

   {name: 123, value: “hello there”},{name: 832416, value: “kjjkbcjkcbbd”},{name: 3, value: “101010101010″},{name: 976, value: “kjjkbcjkcbbd”}

采用LongType排序类型,结果是:

  {name: 3, value: “101010101010″},{name: 123, value: “hello there”},{name: 976, value: “kjjkbcjkcbbd”},{name: 832416, value: “kjjkbcjkcbbd”}

采用UTF8Type排序类型,结果是:

  {name: 123, value: “hello there”},{name: 3, value: “101010101010″},{name: 832416, value: “kjjkbcjkcbbd”},{name: 976, value: “kjjkbcjkcbbd”}

这些排序规则也适用于SuperColumns在Row内的排序,但对于SuperColumn内的Columns,用来定义排序规则的参数不再是Row和SuperColumn里的CompareWith,而是CompareSubcolumnsWith。

我们可以自定义排序规则,实现接口org.apache.cassandra.db.marsha1.IType即可。

cassandra学习笔记四相关推荐

  1. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  2. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  3. RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决)

    RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) 参考文章: (1)RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决) (2)https://www.cnblogs. ...

  4. JSP学习笔记(四十九):抛弃POI,使用iText生成Word文档

    POI操作excel的确很优秀,操作word的功能却不敢令人恭维.我们可以利用iText生成rtf文档,扩展名使用doc即可. 使用iText生成rtf,除了iText的包外,还需要额外的一个支持rt ...

  5. Ethernet/IP 学习笔记四

    Ethernet/IP 学习笔记四 EtherNet/IP Quick Start for Vendors Handbook (PUB213R0): https://www.odva.org/Port ...

  6. OpenCV学习笔记四-image的一些整体操作

    title: OpenCV学习笔记四-image的一些整体操作 categories: 编程 date: 2019-08-08 12:50:47 tags: OpenCV image的一些操作 sP4 ...

  7. 吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码

    吴恩达<机器学习>学习笔记四--单变量线性回归(梯度下降法)代码 一.问题介绍 二.解决过程及代码讲解 三.函数解释 1. pandas.read_csv()函数 2. DataFrame ...

  8. esp8266舵机驱动_arduino开发ESP8266学习笔记四—–舵机

    arduino开发ESP8266学习笔记四-–舵机 使用时发现会有ESP8266掉电的情况,应该是板上的稳压芯片的限流导致的,观测波形,发现当舵机运转时,电源线3.3V不再是稳定的3.3V,大概是在3 ...

  9. mysql新增表字段回滚_MySql学习笔记四

    MySql学习笔记四 5.3.数据类型 数值型 整型 小数 定点数 浮点数 字符型 较短的文本:char, varchar 较长的文本:text, blob(较长的二进制数据) 日期型 原则:所选择类 ...

最新文章

  1. 理财工具——七大标准比率
  2. SQL数据分析概览——Hive、Impala、Spark SQL、Drill、HAWQ 以及Presto+druid
  3. 成功解决cv2.error: OpenCV(4.1.2) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:182: err
  4. 用python绘制图形_python绘制图形
  5. Docker Dockerfile详解
  6. wordpress通过$wpdp更新数据表内容
  7. Android笔记 fragment的Tab样式demo
  8. 《天天数学》连载44:二月十三日
  9. 2022年推出?特斯拉人形机器人被批就是个笑话
  10. 如何在WPF 表格中嵌套按钮
  11. 怎样做到“不说服客户,只拒绝客户”?
  12. windows server上存储提示“由于管理员设置的策略,该磁盘处于脱机状态”
  13. Unity WebPlayer自定义进度条界面
  14. “蓝桥杯”练习系统练习题答案(自己做的)
  15. sap hana安装教程
  16. 移动端h5不支持font-family里面的楷体、微软雅黑等字体
  17. 转录组分析_20个必须知道的转录组知识点!
  18. 安卓开发用什么语言?一次违反常规的安卓大厂面试经历,含BATJM大厂
  19. 2022-2028全球及中国弹性体行业研究及十四五规划分析报告
  20. 软件项目报价术语总结(功能点计数元素ILF、EIF、IE、EO、EQ)

热门文章

  1. 微信开发--开发模式简单配置
  2. 桌面虚拟化之应用程序的整合
  3. C#(asp.net)实现目录(无扩展名)重写
  4. 解决企业人力短缺难题?且看RPA如何大展身手!
  5. Docker的C/S模式
  6. 洛谷——P1657 选书
  7. BaseServlet 继承 httpServlet
  8. Traffic Server中的cache.config的字段理解
  9. MapReduce-深度剖析
  10. Java集合框架之Collection集合