NoSQL那些事:51CTO带您走进列数据库

摘要:列数据库算不算NoSQL,目前来看还是存在争议的。51CTO数据库频道认为还是要一分为二的看待,按列存储也含有一定的关系,因此严格意义上说列数据库有一些还是属于关系型数据库的。

标签:列数据库  NoSQL

【51CTO外电头条】列数据库出名可能是因为Google BigTable的出现,它表面上和关系数据库类似,但实际上却有着本质的不同,一个是按行存储数据(关系数据库),一个是按列存储数据(列数据库)的,你不能将适用于关系数据库的解决方案强加给列数据库,因为列数据库是没有关系的。51CTO数据库频道向您推荐《NoSQL:关系型数据库的终结者?》专题,以便于您更好的理解NoSQL。

搞清楚下面几个概念才能理解列数据库是如何工作的:

◆Column Family

◆Super Column

◆Column

列数据库中的Column和Super Column是不占位的,意味着如果它们里面没有值,它们只占用0字节,Column Family与传统数据库中的表类似,但和表又不一样,在Column Family中的唯一定义是名称和键(Key)排序选项(没有任何模式)。

我个人认为Column Family数据库(CFDB)可能是消除抽象设计的最佳方法,因为CFDB中的一切都是围绕真实的物理模型的。

◆Column Family – Column Family指定数据如何存储在磁盘上的,一个Column Family中的所有数据都将保存在相同的文件中,一个Column Family可以容纳多个Super Column或Column。

◆Super Column - Super Column是一个字典,它是一个包含其它列的列,但一个Super Column不能包含另一个Super Column。

◆Column -  Column是一个由名称,值和时间戳组成的三元组(我将忽略时间戳,把它当作一个Key/Value对看待)。

最重要的是要明白CFDB架构设计的外围重要性,如果架构都不正确,那基本上就无法获取数据,CFDB通常按照键或键范围提供一两种形式的查询,这是很有意义的,因为CDFB通常是分布式的,键决定了数据的真实物理位置,这是因为数据是基于Column Family的排序顺序存储的,你是没有办法改变排序方式的(除了选择升序和降序外)。

和关系数据库中的排序顺序不一样,列数据库的排序顺序不受列的值影响,只受列名的影响。

假设在Users Column Family,@ayende行中,我们将列“name”设为“Ayende Rahine”,列“location”设为“Israel”,CFDB将会象Users Column Family文件一样对它们进行排序:

@ayende/location = “Israel”

@ayende/name = “Ayende Rahien”

这是因为排序时“location”小于“name”的缘故,如果在Friends Column Family中有一个Super Column,用户“@ayende”有两个朋友,它们将会象Friends Column Family文件那样进行存储:

@ayende/friends/arava= 945

@ayende/friends/rose = 14

记住,这个属性对理解CFDB是如何工作的相当重要,我们以Twitter模型为例,我们需要存储:用户和推(tweet),我们定义了三个Column Family:

◆Users – 按UTF-8排序

◆Tweets – 按连续GUID排序

◆UsersTweets - Super Column Family,按连续GUID排序

我们创建一个用户(我使用name参数标志列名和值,key参数表示行的键,Column Family是Users):

cfdb.Users.Insert(key: “@ayende”, name: “Ayende Rahine”, location: “Israel”, profession: “Wizard”);

下图是一个可视化的表示,注意与关系数据库的区别。

图 1 保存用户信息的存储样式

现在我们创建一个推:

var firstTweetKey = “Tweets/” + SequentialGuid.Create();

cfdb.Tweets.Insert(key: firstTweetKey, application: “TweekDeck”, text: “Err, is this on?”, private: true);

var secondTweetKey = “Tweets/” + SequentialGuid.Create();

cfdb.Tweets.Insert(key: secondTweetKey, app: “Twhirl”, version: “1.2”,

text: “Well, I guess this is my mandatory hello world”, public: true);

下面是它真实的存储格式:

图 2 保存推信息的存储样式

这里有几件事需要注意:

◆在这里,Key不重要,重要的是它是连续的,因为后面会根据它进行排序;

◆两个行上面有不同的数据列;

◆我们实际上没有任何方法将用户和推关联起来。

在关系数据库中,我们通常会定义一个名叫UserId的列,这样我们可以通过它将推链接回用户,此外,关系允许我们按用户ID查询推,但CFDB没有这样的功能,无法根据列的值进行查询,也没有办法按照列进行查询,CFDB只能根据键查询,我们以UsersTweets Column Family为例进行说明:

cfdb.UsersTweets.Insert(key: “@ayende”,

timeline: { SequentialGuid.Create(): firstTweetKey } );

cfdb.UsersTweets.Insert(key: “@ayende”,

timeline: { SequentialGuid.Create(): secondTweetKey } );

在CFDB上,它看起来象:

图 3 用户和推关联

这里我们向UsersTweets Column Family插入数据,行的Key是“@ayende”,Super Column timeline有两列,每个列的名字是一个连续的GUID,这意味着我们可以根据它进行排序,实际上我们是用一个Super Column创建了一个行,它又包含两列,列名是一个GUID,每一列的值是Tweets表中一个行的键。

问题:我们可以在Users Column Family中创建一个Super Column存储关系吗?是的,可以这么做,但一个Column Family要么容纳Super Column,要么容纳Column,不能二者兼得。

为了获得某个用户发的推,我们需要执行:

var tweetIds =

cfdb.UsersTweets.Get(“@ayende”)

.Fetch(“timeline”)

.Take(25)

.OrderByDescending()

.Select(x=>x.Value);

var tweets = cfdb.Tweets.Get(tweetIds);

从本质上来讲,我们执行了两个查询,一个是在UsersTweets Column Family执行的,用行键“@ayende”请求timeline Super Column中的列和值,然后在Tweets Column Family上执行另一个查询,获得真正的推。

因为数据是按照列名排序的,同时我们选择的是降序排序,我们获得了该用户的最后25个推。

如果我想展示最后25个推该怎么办?很简单,只需要查询Tweets Column Family中的推,然后按键倒序排序即可。

为什么CFDB有如此多的限制?

你可能已经注意到我多次提及RDBMS和CFDB的差异,我认为CFDB理解起来确实有点难,即使它表面上和关系数据库很接近,但它的限制却很多,没有连接,没有真正的查询功能(除了主键外),越是熟悉关系数据库,对理解CFDB越是有影响。

之所以有这么多的限制,主要原因是CFDB设计目标就是运行在多台机器上,存储大量信息的,在关系数据库中几乎是不可能存储这么多数据的,即使是象Oracle RAC这样的集群数据库也存储不了那么多数据。

CFDB不提供连接的原因是,连接需要你能扫描整个数据集,这个时候要么使用一个视图,否则就只有扫描整个数据库了,这会造成性能急剧下降,因此CFDB必须避免出现这种情况。

CFDB不提供按列或按值查询的原因是,因为这样要么需要一个索引,要么扫描整个数据集,CFDB将查询限制到只能按键进行查询,确保它能准确地知道查询应在哪个节点上运行,这意味着每个查询只会扫描一小段数据集,性能自然会好很多。

理解列数据库需要一种截然不同的思维方式,虽然我没有CFDB实战经验,我可以想像得到,使用它们迁移是个麻烦事,但它确实是获得高可扩展数据存储的最好方式。

到最后,51CTO数据库的编辑了解到,有些专业人士还是认为列数据库也不全是NoSQL。尽管有Sybase IQ这样的产品,但是列数据库当中还是有关系存在的。

作者简介

Ayende Rahien只是网名,作者的真实名字叫做Oren Eini,他是一名经验丰富的开发人员/架构师,主要精力放在CLR,构建商业应用和开发生产力框架和工具上,他也是多个著名开源项目的积极成员,包括NHibernate,Castle等,另外,Oren Eini还创建了多个开源项目,如Rhino Mocks,NHibernate Query Analyzer,Rhino Commons等。

原文出处:ayende.com/Blog/archive/2010/05/14/that-no-sql-thing-Column-family-databases.aspx

摘要:列数据库算不算NoSQL,目前来看还是存在争议的。51CTO数据库频道认为还是要一分为二的看待,按列存储也含有一定的关系,因此严格意义上说列数据库有一些还是属于关系型数据库的。

标签:列数据库  NoSQL

【51CTO外电头条】列数据库出名可能是因为Google BigTable的出现,它表面上和关系数据库类似,但实际上却有着本质的不同,一个是按行存储数据(关系数据库),一个是按列存储数据(列数据库)的,你不能将适用于关系数据库的解决方案强加给列数据库,因为列数据库是没有关系的。51CTO数据库频道向您推荐《NoSQL:关系型数据库的终结者?》专题,以便于您更好的理解NoSQL。

搞清楚下面几个概念才能理解列数据库是如何工作的:

◆Column Family

◆Super Column

◆Column

列数据库中的Column和Super Column是不占位的,意味着如果它们里面没有值,它们只占用0字节,Column Family与传统数据库中的表类似,但和表又不一样,在Column Family中的唯一定义是名称和键(Key)排序选项(没有任何模式)。

我个人认为Column Family数据库(CFDB)可能是消除抽象设计的最佳方法,因为CFDB中的一切都是围绕真实的物理模型的。

◆Column Family – Column Family指定数据如何存储在磁盘上的,一个Column Family中的所有数据都将保存在相同的文件中,一个Column Family可以容纳多个Super Column或Column。

◆Super Column - Super Column是一个字典,它是一个包含其它列的列,但一个Super Column不能包含另一个Super Column。

◆Column -  Column是一个由名称,值和时间戳组成的三元组(我将忽略时间戳,把它当作一个Key/Value对看待)。

最重要的是要明白CFDB架构设计的外围重要性,如果架构都不正确,那基本上就无法获取数据,CFDB通常按照键或键范围提供一两种形式的查询,这是很有意义的,因为CDFB通常是分布式的,键决定了数据的真实物理位置,这是因为数据是基于Column Family的排序顺序存储的,你是没有办法改变排序方式的(除了选择升序和降序外)。

和关系数据库中的排序顺序不一样,列数据库的排序顺序不受列的值影响,只受列名的影响。

假设在Users Column Family,@ayende行中,我们将列“name”设为“Ayende Rahine”,列“location”设为“Israel”,CFDB将会象Users Column Family文件一样对它们进行排序:

@ayende/location = “Israel”

@ayende/name = “Ayende Rahien”

这是因为排序时“location”小于“name”的缘故,如果在Friends Column Family中有一个Super Column,用户“@ayende”有两个朋友,它们将会象Friends Column Family文件那样进行存储:

@ayende/friends/arava= 945

@ayende/friends/rose = 14

记住,这个属性对理解CFDB是如何工作的相当重要,我们以Twitter模型为例,我们需要存储:用户和推(tweet),我们定义了三个Column Family:

◆Users – 按UTF-8排序

◆Tweets – 按连续GUID排序

◆UsersTweets - Super Column Family,按连续GUID排序

我们创建一个用户(我使用name参数标志列名和值,key参数表示行的键,Column Family是Users):

cfdb.Users.Insert(key: “@ayende”, name: “Ayende Rahine”, location: “Israel”, profession: “Wizard”);

下图是一个可视化的表示,注意与关系数据库的区别。

图 1 保存用户信息的存储样式

现在我们创建一个推:

var firstTweetKey = “Tweets/” + SequentialGuid.Create();

cfdb.Tweets.Insert(key: firstTweetKey, application: “TweekDeck”, text: “Err, is this on?”, private: true);

var secondTweetKey = “Tweets/” + SequentialGuid.Create();

cfdb.Tweets.Insert(key: secondTweetKey, app: “Twhirl”, version: “1.2”,

text: “Well, I guess this is my mandatory hello world”, public: true);

下面是它真实的存储格式:

图 2 保存推信息的存储样式

这里有几件事需要注意:

◆在这里,Key不重要,重要的是它是连续的,因为后面会根据它进行排序;

◆两个行上面有不同的数据列;

◆我们实际上没有任何方法将用户和推关联起来。

在关系数据库中,我们通常会定义一个名叫UserId的列,这样我们可以通过它将推链接回用户,此外,关系允许我们按用户ID查询推,但CFDB没有这样的功能,无法根据列的值进行查询,也没有办法按照列进行查询,CFDB只能根据键查询,我们以UsersTweets Column Family为例进行说明:

cfdb.UsersTweets.Insert(key: “@ayende”,

timeline: { SequentialGuid.Create(): firstTweetKey } );

cfdb.UsersTweets.Insert(key: “@ayende”,

timeline: { SequentialGuid.Create(): secondTweetKey } );

在CFDB上,它看起来象:

图 3 用户和推关联

这里我们向UsersTweets Column Family插入数据,行的Key是“@ayende”,Super Column timeline有两列,每个列的名字是一个连续的GUID,这意味着我们可以根据它进行排序,实际上我们是用一个Super Column创建了一个行,它又包含两列,列名是一个GUID,每一列的值是Tweets表中一个行的键。

问题:我们可以在Users Column Family中创建一个Super Column存储关系吗?是的,可以这么做,但一个Column Family要么容纳Super Column,要么容纳Column,不能二者兼得。

为了获得某个用户发的推,我们需要执行:

var tweetIds =

cfdb.UsersTweets.Get(“@ayende”)

.Fetch(“timeline”)

.Take(25)

.OrderByDescending()

.Select(x=>x.Value);

var tweets = cfdb.Tweets.Get(tweetIds);

从本质上来讲,我们执行了两个查询,一个是在UsersTweets Column Family执行的,用行键“@ayende”请求timeline Super Column中的列和值,然后在Tweets Column Family上执行另一个查询,获得真正的推。

因为数据是按照列名排序的,同时我们选择的是降序排序,我们获得了该用户的最后25个推。

如果我想展示最后25个推该怎么办?很简单,只需要查询Tweets Column Family中的推,然后按键倒序排序即可。

为什么CFDB有如此多的限制?

你可能已经注意到我多次提及RDBMS和CFDB的差异,我认为CFDB理解起来确实有点难,即使它表面上和关系数据库很接近,但它的限制却很多,没有连接,没有真正的查询功能(除了主键外),越是熟悉关系数据库,对理解CFDB越是有影响。

之所以有这么多的限制,主要原因是CFDB设计目标就是运行在多台机器上,存储大量信息的,在关系数据库中几乎是不可能存储这么多数据的,即使是象Oracle RAC这样的集群数据库也存储不了那么多数据。

CFDB不提供连接的原因是,连接需要你能扫描整个数据集,这个时候要么使用一个视图,否则就只有扫描整个数据库了,这会造成性能急剧下降,因此CFDB必须避免出现这种情况。

CFDB不提供按列或按值查询的原因是,因为这样要么需要一个索引,要么扫描整个数据集,CFDB将查询限制到只能按键进行查询,确保它能准确地知道查询应在哪个节点上运行,这意味着每个查询只会扫描一小段数据集,性能自然会好很多。

理解列数据库需要一种截然不同的思维方式,虽然我没有CFDB实战经验,我可以想像得到,使用它们迁移是个麻烦事,但它确实是获得高可扩展数据存储的最好方式。

到最后,51CTO数据库的编辑了解到,有些专业人士还是认为列数据库也不全是NoSQL。尽管有Sybase IQ这样的产品,但是列数据库当中还是有关系存在的。

作者简介

Ayende Rahien只是网名,作者的真实名字叫做Oren Eini,他是一名经验丰富的开发人员/架构师,主要精力放在CLR,构建商业应用和开发生产力框架和工具上,他也是多个著名开源项目的积极成员,包括NHibernate,Castle等,另外,Oren Eini还创建了多个开源项目,如Rhino Mocks,NHibernate Query Analyzer,Rhino Commons等。

原文出处:ayende.com/Blog/archive/2010/05/14/that-no-sql-thing-Column-family-databases.aspx


相关文章

  • 解读NoSQL技术代表之作Dynamo
  • NoSQL在过去的一年里,逐渐已经成为了家喻户晓的东西,我(54chen)自从去年开始人人网的NoSQL系统Nuclear的研发以来,一直看 NoSQL越来越热,越来越引来大家的围观.受InfoQ中文站编辑之托,特作此文,一来作为过去一年的 ...查看


  • 社交网络数据库技术分析
  • 社交网络数据库技术分析 传统互联网正在迈向一个全新的时代--社交服务网(Social Networking Service)时代,从"人与机器"的时代迈向"人与人"的时代.互联网社交服务网站的发展验证 ...查看


  • iOSAPP开发工具大盘点
  • iOS APP开发工具大盘点 随着iphone5的持续走俏,其操作平台iOS 和开发语言Objective-C都跟着沾了光.iOS 6 还未推出就广受瞩目,Objective-C更是成为市场占有率第3的开发语言.目前基于iOS的APP应用有 ...查看


  • [架构]NoSQL架构实践(一)以NoSQL为辅
  • 摘要:很多朋友看到NoSQL时总会有困惑,觉得很好,但是却不知道如何正式用到自己的项目中.下文中笔者带我们看下怎么样在我们的系统中使用NoSQL. 标签:NoSQL 经常有朋友遇到困惑,看到NoSQL的介绍,觉得很好,但是却不知道如何正式用 ...查看


  • [廉环话]漫谈信息安全设计与治理之资源治理
  • 推广 | 令人窒息的奖品等你-2016最权威的全球开发者调研 [51CTO.com原创稿件]上周末,廉哥突然江郎才尽了,不知和大家漫谈些什么好.于是干脆从自己待腻了的地方去了一趟僧人待腻了的地方.对,我去修禅了.这次我可没带什么书,不去装什 ...查看


  • 由浅入深 NoSQL的五种主流数据模型
  • 2012年03月05日10:37 来源:nosqlfan 作者:NoSQLfan 编辑:王玉圆 评论:0条 [IT168 技术]本文内容是对<NoSQL Data Modeling Techniques>一文的简单概述,原文对N ...查看


  • REDIS内存容量的预估和优化
  • Redis相关知识 Redis订阅/发布机制实现分析 NoSQL数据库Redis系统性介绍 NoSQL数据库Redis的短期发展规划 Redis 2.6 新功能一览 深入剖析Redis RDB持久化机制 Redis常见的性能问题和解决方法 ...查看


  • 专业机房的网络设备的布局 - 网络管理 - 51CTO技术论坛
  • 专业机房的网络设备的布局 网络的建设离不开机房,一方面机房提供了网络的汇聚,通过核心层的交换路由设备将千百个离散的信息点连接到一起;另一方面机房中的服务器为企业内部提供了各种必要的服务,WWW服务器,MAIL服务器,数据库服务器等等均放置在 ...查看


  • NoSQL时代已经到来?
  • 诸多厂商都宣称自己的产品可以应对大数据带来的挑战.大数据时代已经到来,但应对大数据的NoSQL是否已经成熟? ―― 本报记者许继楠 "大数据"无疑是继"云计算"之后业界最热的词.市场研究机构Gartn ...查看


热门内容