Cassandra 数据模型 (基于CQL,解决胖列数量限制及灵活性问题)(1.1及以上版本)
2013-09-16 15:22
344 查看
文中主要交代Cassandra的编程模型及数据结构。
由于Cassandra版本数次更新,网上中文的资料已经有点过时,比较有代表性的比如ebuy那篇文章都已经过时了,于是自己找资料,结合官方博客写一篇Cassandra模型的文章。
一些名词的介绍:由于技术名词冲突,BigTable里的表对应的是Cassandra里的列族,而BigTable里面列族的概念更类似Cassandra早期实现里的超级列(该功能在Cassandra里已被关闭)。
Cassandra是Apache的开源项目,是NoSQL的一种,广泛意义上的列族数据库,分布式,无中心机。其早期实现主要参考了Google的Big Table论文及亚马逊的Dynamo论文中的介绍,可以参考两篇论文来获得Cassandra的设计思想,关于更详细的资料,可以参见wiki及官方文档。
Cassandra的早期实现里,使用的完全是BigTable的数据模型,即列及列族及主键等概念。在ebuy的最佳实践的文中,对该模型的使用做了详细解释,我无意在此引用他人文章,只是简单说一下概念。
最佳实践文章总共分两部分,上部分主要说的是列族数据库中该如何设计数据模型,其中主要讨论的是对关系及部分相关数据的重复储存来减少对数据库的分布式读取,其中对列族数据库数据结构的有个挺有意思的式子,如下:
Map<RowKey, SortedMap<ColumnKey, ColumnValue>>
下部分交代的则是Cassandra中的具体实现方式,比如当时Cassandra实现了一个与BigTable列族类似的东西,或者说只是名字不同的东西,就是超级列,把类似的列聚
合在一起提取。
再比如说推荐使用胖列(使用列键查询)而不是瘦列(使用主键查询)。胖列指的是以大量的列储存关系,比如用户表users有三列user_k,p1,p2,第一列user_k是主键,第二列p1是用户购买的产品1,第三列p2是用户购买的产品2,pn可以扩展到极大的数量.
注:上文只是简单解释,实际全文中对各种应用场景的讨论不仅限于该范围。
CREATE TABLE timeline (
user_id varchar,
tweet_id uuid,
author varchar,
body varchar,
PRIMARY KEY (user_id, tweet_id)
);
上图是传统数据库的储存方式。
上图是Cassandra的储存方式,注意{1787,author}是列键名而不只是数据。
CQL中有主键及二级主键的概念,主键就是原先的主键,这个概念没有变化,而对于原先的超级列聚合,CQL通过把二级主键的值加上列名作为列键名解决了这个问题。
也就是说,把原先由数据字典(请允许我使用这个关系数据库词汇)储存的数据储存到了数据表中,减轻了对数据字典的访问及数据字典数据结构的维持开销,把压力下发到数据表。
参考:
Schema in Cassandra 1.1
Cassandra Wiki
Cassandra Data Modeling Best Practices, Part 1
Cassandra Data Modeling Best Practices, Part 2
由于Cassandra版本数次更新,网上中文的资料已经有点过时,比较有代表性的比如ebuy那篇文章都已经过时了,于是自己找资料,结合官方博客写一篇Cassandra模型的文章。
一些名词的介绍:由于技术名词冲突,BigTable里的表对应的是Cassandra里的列族,而BigTable里面列族的概念更类似Cassandra早期实现里的超级列(该功能在Cassandra里已被关闭)。
Cassandra介绍
首先介绍一下Cassandra。Cassandra是Apache的开源项目,是NoSQL的一种,广泛意义上的列族数据库,分布式,无中心机。其早期实现主要参考了Google的Big Table论文及亚马逊的Dynamo论文中的介绍,可以参考两篇论文来获得Cassandra的设计思想,关于更详细的资料,可以参见wiki及官方文档。
早期实现及最佳实践
前文提到早期实现,那么现在当然与早期区别已经极大了,从数据模型设计到实际使用,基本上已经自成体系了。其中之一最大的改变,就是1.1版本里对数据库操作的改变。Cassandra的早期实现里,使用的完全是BigTable的数据模型,即列及列族及主键等概念。在ebuy的最佳实践的文中,对该模型的使用做了详细解释,我无意在此引用他人文章,只是简单说一下概念。
最佳实践文章总共分两部分,上部分主要说的是列族数据库中该如何设计数据模型,其中主要讨论的是对关系及部分相关数据的重复储存来减少对数据库的分布式读取,其中对列族数据库数据结构的有个挺有意思的式子,如下:
Map<RowKey, SortedMap<ColumnKey, ColumnValue>>
下部分交代的则是Cassandra中的具体实现方式,比如当时Cassandra实现了一个与BigTable列族类似的东西,或者说只是名字不同的东西,就是超级列,把类似的列聚
合在一起提取。
再比如说推荐使用胖列(使用列键查询)而不是瘦列(使用主键查询)。胖列指的是以大量的列储存关系,比如用户表users有三列user_k,p1,p2,第一列user_k是主键,第二列p1是用户购买的产品1,第三列p2是用户购买的产品2,pn可以扩展到极大的数量.
注:上文只是简单解释,实际全文中对各种应用场景的讨论不仅限于该范围。
磁盘储存方式
Cassandra使用的方式是:把一级主键当做分区主键,列名作为列键储存。光说不清楚,上图:(图片来自Cassandra 1.1)CREATE TABLE timeline (
user_id varchar,
tweet_id uuid,
author varchar,
body varchar,
PRIMARY KEY (user_id, tweet_id)
);
上图是传统数据库的储存方式。
上图是Cassandra的储存方式,注意{1787,author}是列键名而不只是数据。
现在的实现
随着Cassandra的成长,原先完全按照BigTable实现的数据模型开始产生一些问题,其中之一就是无法无限扩大的列的数量,虽然已经设计了一个足够大的列数量,但对于大数据分布式数据库,仍然是不够用的,而且超级列的方式灵活性受限制,于是开发者开始走自己的道路,于是随着CQL(Cassandra自己的类似SQL的操作语言)的发布及发展,首先清除了超级列(BigTable里的列族)的概念:在CQL中,没有超级列的概念,在列上一级就是表,也就是原先概念上的超级列是不存在的,那针对原先的胖列的应用场景,该如何处理呢?CQL中有主键及二级主键的概念,主键就是原先的主键,这个概念没有变化,而对于原先的超级列聚合,CQL通过把二级主键的值加上列名作为列键名解决了这个问题。
也就是说,把原先由数据字典(请允许我使用这个关系数据库词汇)储存的数据储存到了数据表中,减轻了对数据字典的访问及数据字典数据结构的维持开销,把压力下发到数据表。
参考:
Schema in Cassandra 1.1
Cassandra Wiki
Cassandra Data Modeling Best Practices, Part 1
Cassandra Data Modeling Best Practices, Part 2
相关文章推荐
- 解决phpMyAdmin2.6以上版本数据乱码问题
- 基于jQuery解决ios10以上版本缩放问题
- 解决phpMyAdmin2.6以上版本数据乱码问题
- 解决phpMyAdmin2.6以上版本数据乱码问题
- 解决SpeedTree模型导入Unity5.0及以上版本问题~
- 解决VMware6.5 以上版本安装RHEL 5的自动安装的问题
- WCF+Restfull服务 提交或获取数据时数据大小限制问题解决方案
- 解决Nginx+php(php 5.3.0及其以上版本)防止目录跨站问题
- Mongo 3.X以上版本使用Robomongo无法查看Collections内容的问题解决
- plsql在安装有10g数据库及以上版本的环境上运行时database项为空的问题解决
- 解决Skyline 6.5版本中3DML模型单体化后外部网页挂接问题
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 大型软件系统客户端数据同步的问题解决
- 第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密 java.lang.ClassNotFoundException 踩坑解决问题详细内幕版本
- Django groundwork在Django1.4以上的版本的问题解决
- Chrome58以上版本Goagent访问google显示不安全使用问题解决
- 【Android】图片剪裁类库,解决com.android.camera.action.CROP在4.4版本以上遇到的intent类型问题
- WCF+Restfull服务 提交或获取数据时数据大小限制问题解决方案
- 解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法
- Mysql5.6以上版本Order by出现意料之外的数据原因与解决