第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格式命名的。这次我们将列拿出来,将时间和值看成一个整体,简化为二维键值映射,类似于:

  • table{
  • //...
  • "aaaaa":{//一行
  • "A:foo":{sth.},//一列
  • "A:bar":{sth.},//一列
  • "B:":{sth.}//一列,列族名为B,但是列名是空字串
  • },
  • "aaaab":{//一行
  • "A:foo":{sth.},
  • "B:":{sth.}
  • },
  • //...
  • }
  • 或者可以将列族当作一层新的索引,类似于:

  • table{
  • //...
  • "aaaaa":{//一行
  • "A":{//列族A
  • "foo":{sth.},//一列
  • "bar":{sth.}
  • },
  • "B":{//列族B
  • "":{sth.}
  • }
  • },
  • "aaaab":{//一行
  • "A":{
  • "foo":{sth.},
  • },
  • "B":{
  • "":"ocean"
  • }
  • },51); font-family:Arial"> 时间戳是第三级索引。Bigtable允许保存数据的多个版本,版本区分的依据就是时间戳。时间戳可以由Bigtable赋值,代表数据进入Bigtable的准确时间,也可以由客户端赋值。数据的不同版本按照时间戳降序存储,因此先读到的是最新版本的数据。我们加入时间戳后,就得到了Bigtable的完整数据模型,类似于:

  • table{
  • //...
  • "aaaaa":{//一行
  • "A:foo":{//一列
  • 15:"y",//一个版本
  • 4:"m"
  • },
  • "A:bar":{//一列
  • 15:"d",
  • },
  • "B:":{//一列
  • 6:"w"
  • 3:"o"
  • 1:"w"
  • }
  • },
  • //...
  • }
  • 查询时,如果只给出行列,那么返回的是最新版本的数据;如果给出了行列时间戳,那么返回的是时间小于或等于时间戳的数据。比如,我们查询"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之上本身就意味着分布式,当然分布式的意义还不仅限于此。稀疏的意思是,一个表里不同的行,列可能完完全全不一样。

    相关文章

    文章浏览阅读752次。关系型数据库关系型数据库是一个结构化的...
    文章浏览阅读687次,点赞2次,收藏5次。商城系统中,抢购和秒...
    文章浏览阅读1.4k次。MongoTemplate开发spring-data-mongodb...
    文章浏览阅读887次,点赞10次,收藏19次。1.背景介绍1. 背景...
    文章浏览阅读819次。MongoDB连接失败记录_edentialmechanisn...
    文章浏览阅读470次。mongodb抽取数据到ES,使用ELK内部插件无...