SuperColumn TMD到底是什么?Cassandra数据模型介绍
(二)
Translated by leo zheng
原文地址:WTF is a SuperColumn? An Intro to the Cassandra Data Model
By Arin Sarkissian Digg
排序(Sorting)
OK - 我们已经了解了各种数据容器(data
containers),数据模型另一个重要的组件是:数据是如何排序的。Cassandra并不同于SQL的查询( Cassandra is not
queryable like SQL)-
当你获取数据的时候你不会指定你想要的数据排序方式(还有其它区别)。数据在你将它们放入集群的时候就已经排好序了,并且一直保持排序!这极大的提高了读
取时的性能,然而为了获得这个好处,你必须按照能够满足你的数据访问模式的方式来设计数据模型。
Columns总是按照name在它们所属的行中来排序的。这非常重要,因此我要再强调一遍:Columns总是按照它们的name来排序!name是如
何比较的,这取决于ColumnFamilys的CompareWith选项。(Cassandra)提供了以下一些选项:BytesType,
UTF8Type, LexicalUUIDType, TimeUUIDType, AsciiType, 以及
LongType。每一个选项将Column的name看作是不同的数据类型,你可以灵活选择。例如:使用LongType,Column的name就被
看作是64位的长整型。为了更好的理解,让我们来看一些数据排序前后的情况:
// 这儿展示了一行中所有column随机排序时的情况
// 这仅仅是一个示例,Cassandra存储数据绝对不会随机排序
// 同时,忽略(Column的)值 - 它们和排序无关
{name: 123, value: "hello there"},
{name: 832416, value: "kjjkbcjkcbbd"},
{name: 3, value: "101010101010"},
{name: 976, value: "kjjkbcjkcbbd"}
由于我们使用LongType选项,因此,这些Column的排序会是这样:
<!--
storage-conf.xml中定义的ColumnFamily
-->
<ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/>
// 看到了吗,Column的name被看作是64位长整型了
// 事实上,Column的name按照数值大小排序了
{name: 3, value: "101010101010"},
{name: 123, value: "hello there"},
{name: 976, value: "kjjkbcjkcbbd"},
{name: 832416, value: "kjjkbcjkcbbd"}
你可以看到,Column的name是按照64位长整型(这样可以是非常大的数字)进行比较的。
现在,如果我们用CompareWith的另一个选项,我们将会得到不同的结果。我们把CompareWith设置为UTF8Type,这样Column的name将被看作是UTF8类型,因此,排序的结果将会是这样:
<!--
storage-conf.xml中定义的ColumnFamily
-->
<ColumnFamily CompareWith="UTF8Type" Name="CF_NAME_HERE"/>
// Column的name被看作是UTF8形式的字符串
{name: 123, value: "hello there"},
{name: 3, value: "101010101010"},
{name: 832416, value: "kjjkbcjkcbbd"},
{name: 976, value: "kjjkbcjkcbbd"}
结果完全不同了!
这样的排序原则同样也适用于SuperColums,只是我们额外有个维度需要处理:我们不仅要决定一行中各个SuperColumns如何排序,我们还
要决定每一个SuperColumn中各个Column如何排序。每个SuperColumn中各个Column的排序方式是由
CompareSubcolumnsWith指定的。这儿有个示例:
// 这儿展示了一个拥有2个SuperColumn的行
// 现在它们是随机排序的
{ // 该行中第一个SuperColumn
name: "workAddress",
// 其中的Columns
value: {
street: {name: "street", value: "1234 x street"},
city: {name: "city", value: "san francisco"},
zip: {name: "zip", value: "94107"}
}
},
{ // 同一行中另一个SuperColumn
name: "homeAddress",
// 其中的Columns
value: {
street: {name: "street", value: "1234 x street"},
city: {name: "city", value: "san francisco"},
zip: {name: "zip", value: "94107"}
}
}
现在,如果我们把CompareSubcolumnsWith 和CompareWith 都设为UTF8Type,我们将得到如下的排序结果:
// 现在,已经排好序了
{
// 由于将类型视为UTF8的字符串,所以 "homeAddress" 排在 "workAddress"之前
{
name: "homeAddress",
// SuperColumn中的Columns同样按名称排序了
value: {
// 看,它们也按照Column的名称排序了
city: {name: "city", value: "san francisco"},
street: {name: "street", value: "1234 x street"},
zip: {name: "zip", value: "94107"}
}
},
{ // 同一行中的另一个SuperColumn
name: "workAddress",
value: {
// SuperColumn中的Columns同样按名称排序了
city: {name: "city", value: "san francisco"},
street: {name: "street", value: "1234 x street"},
zip: {name: "zip", value: "94107"}
}
}
}
我想要指出的是:虽然上面的示例中CompareSubcolumnsWith 和 CompareWith 的值都被设置为UTF8Type,但这不是必须的。你可以根据需要为CompareSubcolumnsWith 和 CompareWith 设置不同的值。
关于排序我想要提及的最后一点是:你可以写一个自定义的类来进行排序。排序机制是可插拔的(pluggable)。。。你可以设置CompareSubcolumnsWith 和/或 CompareWith 的值为任意类的全路径名(fully-qualified class name),只要这个类实现了接口:org.apache.cassandra.db.marshal.IType(也就是说你可以自定义比较器(comparators))。
Schema示例(Example Schema)
好的 —— 现在我们已经认识了难题(译注:指Cassandra数据模型)的各块内容,让我们把它们组合在一起,构造一个简单的Blog系统。我们将要构造的系统包含以下规则:
* 支持单篇Blog
* 可以有多个作者(authors)
* Blog包含标题(title)、内容(body)、slug 和(发布日期)publish date
* Blog可以和任意标签(tag)关联
* 人们可以添加评论(comments ),但不能注册:他们每次都输入个人信息(这只是为了简单)
* 评论包含内容(text)、提交时间(time submitted)、评论者的姓名(commenter’s name)
* 必须能按时间倒序显示所有发布的Blog(最新的排在最前面)
* 必须能按时间倒序显示某个tag相关的Blog
下面的各个部分描述了我们系统的Keyspace里定义的ColumnFamily,展示了XML的定义、讨论了我们选择不同排序方式的原因,并且以JSON格式展示了ColumnFamily中的数据。
Authors ColumnFamily
构造Authors ColumnFamily是非常简单的;没有任何花哨的东西。每一个Author就是一行,并且使用Author的全名(full name)作为Key。在每一行中,每一个Column表示的是Author的一个个人信息属性。
这是一个用一行来表示一个对象的例子。。。这个case中是Author对象。这种方式下,每一个Column表示一个属性。超级简单。我要指出的是,由于没有任何的一行中必须包含哪些Column的定义,因此我们拥有了一个无模式(schemaless)的设计。
我们将根据Key来访问各行,并且每一次查询总是获取所有的Column(我们永远不会通过Key —— 'foo',来获取这一行中的前三个Column)。这意味着我们并不关心Column是如何排序的。因此,我们使用BytesType 排序选项,因为它不需要对Column的name做任何验证。
<!--
ColumnFamily: Authors
我们在这存储所有的Author信息
Row Key => Author的姓名(这意味着姓名必须是唯一的)
Column Name: Author的一个属性(标题、内容等)(译注:应该是tiwtter账号、email等)
Column Value: 属性的值
访问: 通过姓名获取一个author(即获取某一行的所有Column)
Authors : { // CF
Arin Sarkissian : { // row key
// Columns对应Author的各个属性
numPosts: 11,
twitter: phatduckk,
email: arin@example.com,
bio: "bla bla bla"
},
// 其他authors
Author 2 {
...
}
}
-->
<ColumnFamily CompareWith="BytesType" Name="Authors"/>
BlogEntries ColumnFamily
再说一遍,这个ColumnFamily只是用来做简单的key/value查询。每一篇blog存为一行。行中的每一个Column表示blog的一个属性:标题、内容等(和前面的例子一样)。一个小优化,我们把tag用逗号分隔的形式存入一个Column。这样,在显示的时候我们只需要分割这个Column的值,就可以得到一个tag列表。
每一行的key是blog的slug。因此当我们想要获得一篇blog的时候,就可以简单的通过这个key(slug)来查询。
<!--
ColumnFamily: BlogEntries
所有的blog存放在这
Row Key +> blog的slug (uri中为了搜索引擎优化的部分)
Column Name: blog的一个属性 (标题、内容等)
Column Value: 属性的值
访问: 通过slug获取一篇blog (通常是获取一行中的所有Column)
fyi: tags是反规范化的。。。它是一个用逗号分隔的列表。
我没有使用json格式是为了不影响我们的表示方法,当然,只要你的程序能够处理,你可以使用任何格式
BlogEntries : { // CF
i-got-a-new-guitar : { // row key - blog的具有唯一性的slug
title: This is a blog entry about my new, awesome guitar,
body: this is a cool entry. etc etc yada yada
author: Arin Sarkissian // Authors CF中一行的key
tags: life,guitar,music // 逗号分隔的tags列表(反规范化的)
pubDate: 1250558004 // 发布时间(unixtime)
slug: i-got-a-new-guitar
},
// 其它的blog
another-cool-guitar : {
...
tags: guitar,
slug: another-cool-guitar
},
scream-is-the-best-movie-ever : {
...
tags: movie,horror,
slug: scream-is-the-best-movie-ever
}
}
-->
<ColumnFamily CompareWith="BytesType" Name="BlogEntries"/>
分享到:
相关推荐
amily 是 Cassandra 数据模型的核心组成部分,用来组织和管理 Column 和 SuperColumn。在 Cassandra 中,一个 ColumnFamily 相当于传统数据库中的表,但它不遵循严格的行与列的关系,而是以键值对的形式存储数据,...
在Cassandra的数据模型中,SuperColumn家族是较旧的数据结构,它类似于传统关系数据库的表。一个SuperColumn家族由多个SuperColumns组成,每个SuperColumn又包含多个子列(或称为Columns)。这种结构允许数据以多维...
### Apache Cassandra 介绍 #### 一、概述 Apache Cassandra 是一套强大的开源分布式 Key-Value 存储系统,它被设计用于处理大规模数据的场景,并且能够实现高度的可伸缩性和容错性。Cassandra 不像传统的数据库...
Cassandra使用手册详细介绍了数据库的安装、配置、数据模型、命令行操作、Java编程接口Thrift的使用,测试以及具体的系统实例实现。手册的目的是为了让用户能够系统地理解和掌握Cassandra的使用方法,从而在实际的...
Cassandra采用了一种基于列族(Column Families)的数据模型,其中包含了Column、SuperColumn、ColumnFamily、Keyspaces、Row等核心概念。每个Keyspace可视为一个独立的命名空间,包含多个ColumnFamily。Row则是在...
Cassandra的数据模型允许模式的灵活性,意味着在存储数据时不必预先定义字段。你可以根据需要动态添加或删除字段,这对于大型部署尤其有用,因为它降低了重构数据模型的成本。 ### 真正的可扩展性 Cassandra支持...
Cassandra 的数据模型是基于列的,与传统的关系型数据库不同,它采用面向列的 ColumnFamily 模型,允许灵活的模式定义。数据存储在 ColumnFamily 中,类似于 BigTable 的表格。ColumnFamily 是由 Row(行)组成的,...
**Cassandra 入门指南** ...随着对Cassandra的理解加深,你可以探索更多高级特性,如分布式数据模型、分区策略、复制策略、索引和触发器等。Cassandra是一个强大且灵活的数据库解决方案,尤其适合处理海量分布式数据。
Apache Cassandra 是一个分布式数据库系统,特别设计用于处理大规模的数据分布于多台服务器上,具有高可用性和可扩展性。在1.2.5版本中,它提供了许多关键特性和改进,使得这个开源数据库更适合处理PB级别的数据。 ...
Cassandra CLI是Apache Cassandra数据库系统的一个命令行工具,它提供了与Cassandra集群交互的能力,包括连接到远程节点、创建或更新模式(schema)、设置和检索记录及列,以及查询节点和集群元数据。这个工具主要...
Cassandra的数据模型可以理解为四维或五维的哈希。它主要包含以下几个概念: 1. Cluster(集群):由多个Keyspace组成。 2. Keyspace(键空间):类似于数据库,包含多个ColumnFamily,每个ColumnFamily对应应用...
1. 数据模型:Cassandra采用键值对存储,支持ColumnFamily、SuperColumn和Column。其数据模型设计灵活,适合大规模数据存储。 2. 分布式架构:Cassandra基于一致性哈希,实现去中心化的数据分布,保证了系统的可扩展...
Cassandra的数据模型基于列族(ColumnFamily)和超级列(SuperColumn)。每个表(Keyspace)由多个列族组成,列族内包含行(Row),行由列(Column)组成。列族可以视为关系数据库中的表,行则是记录,列是记录中的...
4. **数据模型**:理解 Cassandra 的数据模型很重要,因为它基于列族(ColumnFamily)和超级列(SuperColumn)。在 Astyanax 中,你可以创建对应的实体类来映射这些概念。 5. **异步操作**:Astyanax 支持异步操作...
运行游戏只需执行SuperColumn.exe 文件即可,没有SuperColumn.sav与SuperColumn.dat文件也可,它会自动在当前目录分别创建一个,另外,在当前目录下还需要动画鼠标ButterFly.ani,若没有就调用系统缺省的箭头鼠标,...
NoSQL数据库与传统的关系型数据库在数据模型、事务处理、查询能力等方面存在显著差异。NoSQL数据库更注重水平扩展性、高并发处理能力和最终一致性,而传统的关系型数据库则强调事务的一致性和完整性。 #### 结语 ...
- **数据模型**: 支持嵌套结构的数据存储。 ##### 5. Redis - **介绍**: Redis是一个开源的内存数据结构存储,可以用作数据库、缓存和消息中间件。 - **数据结构**: 支持字符串、哈希表、列表、集合、有序集合等...