转自:http://www.infoq.com/cn/articles/best-practice-of-cassandra-data-model-design

不要把Cassandra model想象成关系型数据库table

取而代之,应该把它想象成事一个有序的map结构。

对于一个新手来说,下面关系型数据库术语常常被对应到Cassandra模型

这种对比可以帮助我们从关系型数据库转换到非关系型数据库。但是当设计Cassandra column famiy的时候请不要这样去类比。取而代之,考虑它是一个map中嵌入另一个map:外部map的key为row key,内部map的key为column key,两个map的key都是有序的。如下:

SortedMap<RowKey, SortedMap<ColumnKey, ColumnValue>>

why?

将column family想象成嵌套的并排序的map比关系型数据库table描述的更为准确,它将帮助你正确的进行Cassandra模型设计。

How?

  • Map可以进行高效查询,同时排序的特性可以进行高效column扫描。在Cassandra中,我们可以使用row key和column key做高效查找和范围扫描
  • Column key的数量是很庞大的(译者注:目前译者所使用的Cassandra1.2.5版本,每个row支持最多20亿个columns)。换句话说你,你可以拥有一个wide rows。
  • Column key自身可以存储值,即你可以拥有一个没有值的column。

如果集群使用Order Preserving Partitioner (OOP)策略进行数据存储,就可以对row key进行范围查询。但是OOP大多数情况都不推荐使用(译者注:将rowkey按照顺序存储到节点上,如果分区不均匀,将导致数据读写不均衡),所以你可以认为外部的map是不排序的,如下:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

上面提到的”Super Column”,认为它们是一组column,这样的话,两级嵌套map就会像下面展示的一样变为三级嵌套map:

Map<RowKey, SortedMap<SuperColumnKey,
           SortedMap<ColumnKey, ColumnValue>>>

注意:

  • 你需要传递timestamp给每个column value,因为Cassandra使用它做内部的冲突处理机制。但在建模过程中你可以忽略它(译者注:在操作column的时候timestamp信息 会自动添加到column)。同时,不要考虑在你的程序中使用column的timestamp,因为它不是为你设计的,与Hbase不同,它们不会生成 新的version数据(译者注:在Hbase中相同rowkey和column key的数据会保存多个version,而Cassandra会将相同数据覆盖,timestamp只保存最后一次更新的时间)。
  • 因为Super Column的性能问题和缺乏二级索引支持问题,Cassandra社区对它的使用曾有过强烈争议。所以,推荐使用Composite Columns代替Super Column实现功能。(译者注:使用Super Column,如果你要获取其中一个columnvalue,则要扫描整个Super Column,这会导致查询性能很糟糕)

围绕着查询模式进行Column Family建模

建模尽量从实体和它们的关系开始

  • 与关系型数据库不同,在Cassandra中通过创建二级索引或者编写复杂SQL(使用joins, order by, group by)来新建或修改查询不是件容易的事情。因为Cassandra具有很高的分布式特性,所以要先考虑查询模式,然后再设计column family。
  • 牢记前面提到的嵌入排序map数据结构,在考虑如何组织你的数据到map,以满足快速查询/排序/分组/过滤/聚合的要求。

在大部分情况下,实体和它们的关系是很重要的(特殊用例除外,如日志存储或者其它时间序列数据)。如果我给你一个查询模式,用于为一个电子商务网站 创建Cassandra模型,但不告诉你任何实体和它们的关系。你会有意或者无意的从查询模式或者从你之前领域对象的理解找出实体和它们之间的关系(因为 我们是通过实体和关系来描述真实世界)。在设计数据模型时最好从实体和关系开始,然后使用反范式化和冗余的方式继续围绕查询模式建模。如果这听起来有些让 人困惑,通过后面的详细例子就可以理解。

注意:在建模的时候考虑以下几点会很有帮助。区分频次大的查询和频次小的查询,有些查询可能只被查询几千次,其它可能被查询数十亿次;还要考虑哪些查询对数据延迟是敏感的。确保你的模型优先满足查询频次大的查询和重要查询。

Cassandra 数据模型设计,根据你的查询来制定设计——反范式设计本质:空间换时间的更多相关文章

  1. Redis学习笔记~关于空间换时间的查询案例

    回到目录 空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于re ...

  2. Redis基础知识之————空间换时间的查询案例

    空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于redis这个 ...

  3. Merkle 树——空间换时间,分而治之的hash表,通过根节点是由它的两个子节点内容的哈希值组成来校验数据完整性,定位篡改的数据位置

    Merkle 树 图 1.5.6.1 - Merkle 树示例 默克尔树(又叫哈希树)是一种二叉树,由一个根节点.一组中间节点和一组叶节点组成.最下面的叶节点包含存储数据或其哈希值,每个中间节点是它的 ...

  4. 图解Skip List——本质是空间换时间的数据结构,在lucene的倒排列表,bigtable,hbase,cassandra的memtable,redis中sorted set中均用到

    Skip List的提出已有二十多年[Pugh, W. (1990)],却依旧应用广泛(Redis.LevelDB等).作为平衡树(AVL.红黑树.伸展树.树堆)的替代方案,虽然它性能不如平衡树稳定, ...

  5. 译 - Cassandra 数据建模的基本规则

    Basic Rules of Cassandra Data Modeling 原文地址:http://www.datastax.com/dev/blog/basic-rules-of-cassandr ...

  6. 【mysql的设计与优化专题(2)】数据中设计中的范式与反范式

    设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小.但是有些时候一昧的追求范式减少冗余,反而会降低数据读写 ...

  7. MySQL中数据中设计中的范式与反范式

    设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小.但是有些时候一昧的追求范式减少冗余,反而会降低数据读写 ...

  8. Redis | 第10章 二进制数组、慢查询日志和监视器《Redis设计与实现》

    目录 前言 1. 二进制位数组 1.1 位数组的表示 1.2 GETBIT 命令的实现 1.3 SETBIT 命令的实现 1.4 BITECOUNT 命令的实现 1.5 BITOP 命令的实现 2. ...

  9. MongoDB 存储引擎和数据模型设计

    标签: MongoDB NoSQL MongoDB 存储引擎和数据模型设计 1. 存储引擎 1.1 存储引擎是什么 1.2 MongoDB中的默认存储引擎 2. 数据模型设计 2.1 内嵌和引用 2. ...

随机推荐

  1. C++ 常见字符处理 收录

    1.string字符串删除 字符串中 指定字符 std::string& HTTPRequestHandlerImpl::replace_all_distinct(std::string&am ...

  2. Vue(1)- es6的语法、vue的基本语法、vue应用示例,vue基础语法

    一.es6的语法 1.let与var的区别 ES6 新增了let命令,用来声明变量.它的用法类似于var(ES5),但是所声明的变量,只在let命令所在的代码块内有效.如下代码: { let a = ...

  3. sql server等待类型

    sql server 各种等待类型-转 sql server各个等待类型及解决办法:https://www.sqlskills.com/help/waits/writelog/其他等待类型的描述和解决 ...

  4. 让你的代码量减少3倍!使用kotlin开发Android

    (一) 创建Kotlin工程 (二) –秘笈!扩展函数 (三) 缩短五倍的Java Bean 本项目使用的代码地址

  5. PAT 1081 Rational Sum[分子求和][比较]

    1081 Rational Sum (20 分) Given N rational numbers in the form numerator/denominator, you are suppose ...

  6. django(python manage.py migrate)同步数据库出错后的解决办法

    执行python manage.py migrate同步数据库前一次执行 python manage.py makemigrations 时生成的文件及之后所有的文件删除即可,然后修改models.p ...

  7. vue生命周期以及vue的计算属性

    一.Vue生命周期(vue实例从创建到销毁的过程,称为生命周期,共有八个阶段) 1.beforeCreate :在实例初始化之后,数据观测 (data observer) 和 event/watche ...

  8. 第一课Linux系统安装知识(2)

    接着上节课单击Finish按钮之后,虚拟机将会启动进入安装界面. 根据提示按回车选择图形界面安装. 这里选择Skip跳过媒介检查. 选择安装语言为简体中文,键盘鼠标默认项即可. 这里安装类型选择是定制 ...

  9. LeetCode:棒球比赛【682】

    LeetCode:棒球比赛[682] 题目描述 你现在是棒球比赛记录员.给定一个字符串列表,每个字符串可以是以下四种类型之一:1.整数(一轮的得分):直接表示您在本轮中获得的积分数.2. " ...

  10. ExtJS + fileuploadfield实现文件上传

    后台服务端接收文件的代码: /** * 后台上传文件处理Action */ @RequestMapping(value = "/uploadFile", method=Reques ...