转自: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. 携程greenlet模块使用

    import greenlet def f1(): print(11) gr2.switch() print(22) gr2.switch() def f2(): print(33) gr1.swit ...

  2. Android Studio "佛祖保佑 永无bug" 注释模板设置详解(仅供娱乐)

    1.注释模板效果图 今天在网上看到一段有趣的注释,佛祖保佑 永无bug, 效果如下图所示: 代码如下所示: /** * _ooOoo_ * o8888888o * 88" . "8 ...

  3. PAGELATCH_x和PAGEIOLATCH_x介绍

    Microsoft SQL Server企业级平台管理实践 第11章 Buffer Latch Timeout的解析 什么是PAGELATCH和PAGEIOLATCH 1.PAGELATCH_x和PA ...

  4. 从0开始用python实现神经网络 IMPLEMENTING A NEURAL NETWORK FROM SCRATCH IN PYTHON – AN INTRODUCTION

    code地址:https://github.com/dennybritz/nn-from-scratch 文章地址:http://www.wildml.com/2015/09/implementing ...

  5. 【网络编程基础】Linux下进程通信方式(共享内存,管道,消息队列,Socket)

    在网络课程中,有讲到Socket编程,对于tcp讲解的环节,为了加深理解,自己写了Linux下进程Socket通信,在学习的过程中,又接触到了其它的几种方式.记录一下. 管道通信(匿名,有名) 管道通 ...

  6. Rare But Powerful Vim Commands.

    @1: We all know about :wq, but we usually ignore :x. :x和:wq都是保存当前文件并退出. 这两个命令实际上并不完全等价,当文件被修改时两个命令时相 ...

  7. Python之字符编码(Day10)

    1. python解释器执行py文件的原理 ,例如python test.py    第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器 第二阶段:python解释器相当于文本编辑器, ...

  8. appcmd应用

    appcmd资料: http://www.jb51.net/article/36024.htm 官方文档:https://docs.microsoft.com/zh-cn/iis/get-starte ...

  9. Educational Codeforces Round 11A. Co-prime Array 数学

    地址:http://codeforces.com/contest/660/problem/A 题目: A. Co-prime Array time limit per test 1 second me ...

  10. Kotlin学习记录3

    参考我的博客:http://www.isedwardtang.com/2017/09/04/kotlin-primer-3/