第1周 进入NoSQL世界;NoSQL与SQL的战争

关系数据库的弱点:
很难进行分布式部署,I/O瓶颈显著。依赖于强大的服务器,需要花更大代价才可以突破性能极限
难以处理非结构化数据
all-in-one

nosql数据库家族:
键值(key-value)数据库。如,redis、memcached
面向文档的数据库。如,mongodb
面向列的数据库。如,hbase、cassandra
面向图的数据库。如,neo4j

bigtable 数据模型:

Bigtable不是关系型数据库,但是却沿用了很多关系型数据库的术语,像table(表)、row(行)、column(列)等。这容易让读者误入歧途,将其与关系型数据库的概念对应起来,从而难以理解论文。Understanding HBase and BigTable是篇很优秀的文章,可以帮助读者从关系型数据模型的思维定势中走出来。

本质上说,Bigtable是一个键值(key-value)映射。按作者的说法,Bigtable是一个稀疏的,分布式的,持久化的,多维的排序映射。

先来看看多维、排序、映射。Bigtable的键有三维,分别是行键(row key)、列键(column key)和时间戳(timestamp),行键和列键都是字节串,时间戳是64位整型;而值是一个字节串。可以用 (row:string, column:string, time:int64)→string 来表示一条键值对记录。

行键可以是任意字节串,通常有10-100字节。行的读写都是原子性的。Bigtable按照行键的字典序存储数据。Bigtable的表会根据行键自动划分为片(tablet),片是负载均衡的单元。最初表都只有一个片,但随着表不断增大,片会自动分裂,片的大小控制在100-200MB。行是表的第一级索引,我们可以把该行的列、时间和值看成一个整体,简化为一维键值映射,类似于:

[javascript]  view plain copy print ?
  1. table{  
  2.   "1" : {sth.},//一行  
  3.   "aaaaa" : {sth.},  
  4.   "aaaab" : {sth.},  
  5.   "xyz" : {sth.},  
  6.   "zzzzz" : {sth.}  
  7. }  

列是第二级索引,每行拥有的列是不受限制的,可以随时增加减少。为了方便管理,列被分为多个列族(column family,是访问控制的单元),一个列族里的列一般存储相同类型的数据。一行的列族很少变化,但是列族里的列可以随意添加删除。列键按照family:qualifier格式命名的。这次我们将列拿出来,将时间和值看成一个整体,简化为二维键值映射,类似于:

[javascript]  view plain copy print ?
  1. table{  
  2.   // ...  
  3.   "aaaaa" : { //一行  
  4.     "A:foo" : {sth.},//一列  
  5.     "A:bar" : {sth.},//一列  
  6.     "B:" : {sth.} //一列,列族名为B,但是列名是空字串  
  7.   },  
  8.   "aaaab" : { //一行  
  9.     "A:foo" : {sth.},  
  10.     "B:" : {sth.}  
  11.   },  
  12.   // ...  
  13. }  

或者可以将列族当作一层新的索引,类似于:

[javascript]  view plain copy print ?
  1. table{  
  2.   // ...  
  3.   "aaaaa" : { //一行  
  4.     "A" : { //列族A  
  5.       "foo" : {sth.}, //一列  
  6.       "bar" : {sth.}  
  7.     },  
  8.     "B" : { //列族B  
  9.       "" : {sth.}  
  10.     }  
  11.   },  
  12.   "aaaab" : { //一行  
  13.     "A" : {  
  14.       "foo" : {sth.},  
  15.     },  
  16.     "B" : {  
  17.       "" : "ocean"  
  18.     }  
  19.   },  
  20.   // ...  
  21. }  

时间戳是第三级索引。Bigtable允许保存数据的多个版本,版本区分的依据就是时间戳。时间戳可以由Bigtable赋值,代表数据进入Bigtable的准确时间,也可以由客户端赋值。数据的不同版本按照时间戳降序存储,因此先读到的是最新版本的数据。我们加入时间戳后,就得到了Bigtable的完整数据模型,类似于:

[javascript]  view plain copy print ?
  1. table{  
  2.   // ...  
  3.   "aaaaa" : { //一行  
  4.     "A:foo" : { //一列  
  5.         15 : "y"//一个版本  
  6.         4 : "m"  
  7.       },  
  8.     "A:bar" : { //一列  
  9.         15 : "d",  
  10.       },  
  11.     "B:" : { //一列  
  12.         6 : "w"  
  13.         3 : "o"  
  14.         1 : "w"  
  15.       }  
  16.   },  
  17.   // ...  
  18. }  
查询时,如果只给出行列,那么返回的是最新版本的数据;如果给出了行列时间戳,那么返回的是时间小于或等于时间戳的数据。比如,我们查询"aaaaa"/"A:foo",返回的值是"y";查询"aaaaa"/"A:foo"/10,返回的结果就是"m";查询"aaaaa"/"A:foo"/2,返回的结果是空。


图1是Bigtable论文里给出的例子,Webtable表存储了大量的网页和相关信息。在Webtable,每一行存储一个网页,其反转的url作为行键,比如maps.google.com/index.html的数据存储在键为com.google.maps/index.html的行里,反转的原因是为了让同一个域名下的子域名网页能聚集在一起。图1中的列族"anchor"保存了该网页的引用站点(比如引用了CNN主页的站点),qualifier是引用站点的名称,而数据是链接文本;列族"contents"保存的是网页的内容,这个列族只有一个空列"contents:"。图1中"contents:"列下保存了网页的三个版本,我们可以用("com.cnn.www", "contents:", t5)来找到CNN主页在t5时刻的内容。

再来看看作者说的其它特征:稀疏,分布式,持久化。持久化的意思很简单,Bigtable的数据最终会以文件的形式放到GFS去。Bigtable建立在GFS之上本身就意味着分布式,当然分布式的意义还不仅限于此。稀疏的意思是,一个表里不同的行,列可能完完全全不一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值