NoSQL简介

  随着大数据时代的到来,我们每天都需要面对海量的数据。为了满足高并发,高可用,高可拓展性的需求,传统的关系型数据库已经越来越力不从心了。

关系型数据库特点

  传统的关系型数据库的事务(transaction)需要满足ACID的设计原则:

  Actomic,即原子性,也就是说事务需要作为一个整体来执行,要么操作成功,要么操作失败回滚到事务发生前的状态。
  Consistency,即一致性,事务执行前后,数据库中的数据需要保持一致。
  Isolation,隔离性,即不同的事务执行互不干扰。
  Durability,持久性,事务执行成功后对数据库的改变是永久的。

  通用的SQL语言和ACID特性让关系型数据库易于理解和操作,而一致性和持久性也使得关系型数据库在存储方面具有良好地表现。因此,在很长一段时间,关系型数据库都是人们的首选。
  然而,在数据爆炸的今天,关系型数据库在许多方面已经显得力不从心。

关系型数据库的缺点

  • 高并发下压力大

      关系型数据库数据按行存储,即使只针对其中某一列进行操作,也需要将整行数据一起读入内存中,造成较大的IO。
  • 维护索引开销大

      为了提高查询的性能,关系型数据库一般对常用的字段建立索引,因而数据的更新必然会引起索引的更新,因而降低了数据库的读写能力。
  • 维护数据一致性代价大

      数据一致性是关系型数据库的核心。关系型数据库为事务定义了不同的隔离级别,从低到高依次是读未提交,读已提交,可重复读,串行化。一般而言,较低的隔离级别能提高较强的并发能力,但也会带来较高的并发错误。
  • 拓展带来的问题

      随着企业的规模做大,对表的需求更高,需要对原有的数据库和表进行拓展。对数据库进行分库需要考虑数据的迁移,分布式事务处理,跨表操作等等问题。对表的拓展,如添加字段等等,需要通过DDL语句来进行修改,并且需要锁表,这个期间会造成服务不可用的问题。
  • 全文搜索能力差

      关系型数据库的模糊匹配如like "%中国真伟大%"不具备分词能力,即匹配不了"中国真是太伟大了"这样的语句,因此在查询方面有一定的限制。

      这些问题反映出一个问题,那就是关系型数据库在当今高并发,高数据量要求的情况下遇到了一定的瓶颈,带来的结果就是CPU开销大,SQL语句执行慢等等问题。而通过增加CPU,服务器的做法虽然能够在一定程度上缓解这个问题,但是性价比却比较低。

什么是NoSQL

  NoSQL,泛指非关系型数据库,也叫Not only SQL,是对不同于传统关系型数据库的数据管理系统的总称。NoSQL适用于超大规模数据的存储,这些数据的存储不需要特定的格式,适合横向拓展。

不同类型的NoSQL

列式存储型

  传统关系型数据库是按照行来存储数据的,而列式存储,顾名思义,则是按照列来存储数据的。随便举一个查询的例子,SELECT name, id FROM students_table,当我们使用行存储的时候,要查询name和id字段,需要将整张表一起读入内存;而使用列存储,则可以直接查询name字段和id字段所在的列,不需要读入所有的数据。在处理海量数据的时候,我们通常需要筛选出指定的字段,而不是所有的字段,因此全表查询在很多情况下都是不必须的,使用列式存储,能够极大的减少IO开销。
在这里插入图片描述
  列式存储查询过程如上,每一列数据按照字典序储存在一张表中,叫做字典表。

  1. 首先在字典表中查找到对应字符串所在的位置
  2. 然后用该数字去列表中进行匹配,匹配正确的位置设置为1,于是得到了一个n位位串
  3. 匹配的条件数对应位串的个数,将这些位串进行与操作,得到一个最终的位串
  4. 利用得到的位串去结果集(即自己想要的字段表,1个或者多个)中查找,即可得到所有满足查询条件的结果

  其次,行式存储是将每一行的数据存储到硬盘上一块连续的地方,同理列式存储将每一列的数据存储到硬盘上一块连续的地方。通常一行数据各个字段的类型不同,值也是千差万别,而一列数据则是同一字段,必然是同种类型,因此列式存储相比行式存储还有一个更加优秀的性能,那就是数据压缩。
列式存储压缩
  如上图的表格所示,材料和名称这一栏被压缩了,而原始表中的材料和名称数值则替换成了列式表中的位置。通常对于一些高重复的字段,比如年龄,性别等等,都可以通过列式存储来进行压缩。

键值对型

  KV型数据库,顾名思义,那就是数据通过键值对进行存储。以redis为例,它将所有数据读入内存中,通过异步方式将数据写回磁盘。因为数据是基于内存的,所以读写速度非常快,并且时间复杂度为O(1)。
  也正是因为这种方式,KV型数据库只能通过Key值来查找,不支持条件查询。并且由于所有的数据都被读入内存中,因此数据的规模受限于内存配置,即无法处理海量的数据。同时,数据在内存中可能会因为某些故障而导致数据丢失。
  因此KV型数据库比较适合存储缓存,即读多于写,对数据持久化要求不高的情况。

文档型

  文档型数据库中的数据是按照文档类型来存储的,文档格式一般采用XML,JSON,BSON等等。与关系型数据库中的存储格式不同,关系型数据库是将一列数据按照一个整体来进行存储,并且有着严格的表结构限制,而文档型数据库则将这一列数据一起存入一个文档中,例如JSON文件。
在这里插入图片描述
  以如上的表为例,将name和quantity字段一起保存进入一个JSON文档,其内容为

{"name": "notebook", "quantity": 50}

  对于size这个字段,它可以细分成3个字段,用JSON格式表示则是

{"w": 8.5, "h": 11, "uom": "in"}

  tags字段不同于上面的size,它不是表示3个不同字段的值,而是表示一个tags字段含有多个值,因此用如下JSON格式表示

["college-ruled", "perforated"]

  最终,上述一行数据可以表示成如下的JSON格式

{
	"name": "notebook", 
	"quantity": 50, 
	"size": {"w": 8.5, "h": 11, "uom": "in"}, 
	"status": "A", 
	"tags": ["college-ruled", "perforated"], 
	"rating": 8, 
}

  文档型数据库很好的解决了关系型数据库schema拓展很困难的问题,当我们需要对一个字段进行拓展的时候,不需要对表进行修改,而是直接在JSON文件中增加一个字段。而这种增加字段的情况对原始的格式也有着良好地兼容性,对于没有新字段的旧文档,它对新字段的返回值为空,而不会报错。

搜索型

  传统关系型数据库通过建立索引来加快查询速度,但是在全文搜索的情况下,索引是无能为力的,另一方面,like模糊查询功能并不能满足所有的模糊匹配查询,并且它的使用限制太大,在使用不当的情况下容易造成慢查询。
  搜索型数据库的原理是倒排索引,什么叫倒排索引呢?顾名思义,与之相对应的就是正向索引。在搜索引擎中,所有的文档都对应一个文档ID,而文档的内容经过分词,得到一系列的关键词,正向索引则是记录了这些关键词所在的地方和出现的次数。当我们通过正向索引来查找一个关键词对应的文档时,需要通过遍历所有的文档来找出包含这个关键词的文档,并通过关键词出现的次数来对文档进行推荐排序,也就是将关键词出现最多的文档最先输出。在数据量较小的情况下,这种搜索并没有暴露出太大的问题,而在处理海量数据的时候,正向索引的遍历时间则就是一个巨大的数字了,根本无法满足实时搜索的需求,因而反向索引(也就是倒排索引)被提出来。搜索引擎将正排索引反向重构成倒排索引,以关键词为Key,出现的文档ID和对应出现次数为value值,通过关键词来定位符合条件的文档,也就避免了大量的检索时间。

四种常见NoSQL比较图

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值