NoSQL 仍是 SQL ?这一篇讲清楚

文章首发于51CTO技术栈公众号
做者 陈彩华
文章转载交流请联系 caison@aliyun.com
复制代码

NoSQL历史

随着大数据时代的到来,愈来愈多的网站、应用系统须要支撑海量数据存储,高并发请求、高可用、高可扩展性等特性要求,传统的关系型数据库在应付这些调整已经显得力不从心,暴露了许多能以克服的问题。由此,各类各样的NoSQL(Not Only SQL)数据库做为传统关系型数据的一个有力补充获得迅猛发展。html

本文将分析传统数据库的存在的相关问题,以及几大类NoSQL如何解决这些问题,但愿给你们提供在不一样业务场景下,关于存储方面技术选型提供参考。java

1 传统数据库缺点

  • 大数据场景下I/O较高 由于数据是按行存储,即便只针对其中某一列进行运算,关系型数据库也会将整行数据从存储设备中读入内存,致使I/O较高web

  • 存储的是行记录,没法存储数据结构redis

  • 表结构schema扩展不方便 如要须要修改表结构,须要执行执行DDL(data definition language),语句修改,修改期间会致使锁表,部分服务不可用算法

  • 全文搜索功能较弱 关系型数据库下只可以进行子字符串的匹配查询,当表的数据逐渐变大的时候,like查询的匹配会很是慢,即便在有索引的状况下。何况关系型数据库也不该该对文本字段进行索引sql

  • 存储和处理复杂关系型数据功能较弱 许多应用程序须要了解和导航高度链接数据之间的关系,才能启用社交应用程序、推荐引擎、欺诈检测、知识图谱、生命科学和 IT/网络等用例。然而传统的关系数据库并不善于处理数据点之间的关系。它们的表格数据模型和严格的模式使它们很难添加新的或不一样种类的关联信息。数据库

2 NoSQL解决方案

NoSQL,泛指非关系型的数据库,能够理解为SQL的一个有力补充。编程

在NoSQL许多方面性能大大优于非关系型数据库的同时,每每也伴随一些特性的缺失,比较常见的,是事务库事务功能的缺失。 数据库事务正确执行的四个基本要素:ACID以下:缓存

名称 描述
A Atomicity
(原子性)
一个事务中的全部操做,要么所有完成,要么所有不完成,不会在中间某个环节结束。
事务在执行过程当中发生错误,会被回滚到事务开始前的状态,就像这个事务历来没有执行过同样。
C Consistency
一致性
在事务开始以前和事务结束之后,数据库的完整性没有被破坏。
I Isolation
隔离性
数据库容许多个并发事务同时对数据进行读写和修改的能力。隔离性能够防止多个事务并发执行时因为交叉执行而致使数据的不一致。
D Durability
持久性
事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失。

下面介绍5大类NoSQL数据针对传统关系型数据库的缺点提供的解决方案:安全

2.1 列式数据库

列式数据库是以列相关存储架构进行数据存储的数据库,主要适合于批量数据处理和即时查询。相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合于小批量的数据处理,经常使用于联机事务型数据处理。

基于列式数据库的列列存储特性,能够解决某些特定场景下关系型数据库I/O较高的问题

2.1.1 基本原理

传统关系型数据库是按照行来存储数据库,称为“行式数据库”,而列式数据库是按照列来存储数据。

将表放入存储系统中有两种方法,而咱们绝大部分是采用行存储的。 行存储法是将各行放入连续的物理位置,这很像传统的记录和文件系统。 列存储法是将数据按照列存储到数据库中,与行存储相似,下图是两种存储方法的图形化解释:

按行存储和按列存储模式

2.1.2 常见列式数据库

  • HBase
    HBase

HBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现的编程语言为 Java。它是Apache软件基金会的Hadoop项目的一部分,运行于HDFS文件系统之上,为 Hadoop 提供相似于BigTable 规模的服务。所以,它能够容错地存储海量稀疏的数据。

  • BigTable

BigTable是一种压缩的、高性能的、高可扩展性的,基于Google文件系统(Google File System,GFS)的数据存储系统,用于存储大规模结构化数据,适用于云端计算。

2.1.3 相关特性

优势以下:

  • 高效的储存空间利用率**

列式数据库因为其针对不一样列的数据特征而发明的不一样算法使其每每有比行式数据库高的多的压缩率,普通的行式数据库通常压缩率在3:1 到5:1 左右,而列式数据库的压缩率通常在8:1到30:1 左右。 比较常见的,经过字典表压缩数据: 下面中才是那张表原本的样子。通过字典表进行数据压缩后,表中的字符串才都变成数字了。正由于每一个字符串在字典表里只出现一次了,因此达到了压缩的目的(有点像规范化和非规范化Normalize和Denomalize)

经过字典表压缩数据

  • 查询效率高

读取多条数据的同一列效率高,由于这些列都是存储在一块儿的,一次磁盘操做能够数据的指定列所有读取到内存中。 下图经过一条查询的执行过程说明列式存储(以及数据压缩)的优势

执行步骤以下:
i. 去字典表里找到字符串对应数字(只进行一次字符串比较)。
ii. 用数字去列表里匹配,匹配上的位置设为1。
iii. 把不一样列的匹配结果进行位运算获得符合全部条件的记录下标。
iv. 使用这个下标组装出最终的结果集。
复制代码
  • 适合作聚合操做

  • 适合大量的数据而不是小数据

缺点以下:

  • 不适合扫描小量数据
  • 不适合随机的更新
  • 不适合作含有删除和更新的实时操做
  • 单行的数据是ACID的,多行的事务时,不支持事务的正常回滚,支持 I(Isolation)隔离性(事务串行提交),D(Durability)持久性,不能保证 A(Atomicity)原子性, C(Consistency)一致性

2.1.4 使用场景

以HBase为例说明:

  • 大数据量 (100s TB级数据) 且有快速随机访问的需求
  • 写密集型应用,天天写入量巨大,而相对读数量较小的应用 好比IM的历史消息,游戏的日志等等
  • 不须要复杂查询条件来查询数据的应用 HBase只支持基于rowkey的查询,对于HBase来讲,单条记录或者小范围的查询是能够接受的,大范围的查询因为分布式的缘由,可能在性能上有点影响,HBase不适用与有join,多级索引,表关系复杂的数据模型
  • 对性能和可靠性要求很是高的应用 因为HBase自己没有单点故障,可用性很是高。
  • 数据量较大,并且增加量没法预估的应用,须要进行优雅的数据扩展的 HBase支持在线扩展,即便在一段时间内数据量呈井喷式增加,也能够经过HBase横向扩展来知足功能。
  • 存储结构化和半结构化的数据

2.2 K-V数据库

指的是使用键值(key-value)存储的数据库,其数据按照键值对的形式进行组织、索引和存储。

KV 存储很是适合不涉及过多数据关系业务关系的数据,同时能有效减小读写磁盘的次数,比 SQL 数据库存储拥有更好的读写性能,可以解决关系型数据库没法存储数据结构的问题

2.2.1 常见 K-V数据库

  • Redis

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。从2015年6月开始,Redis的开发由Redis Labs赞助,而2013年5月至2015年6月期间,其开发由Pivotal赞助。在2013年5月以前,其开发由VMware赞助。根据月度排行网站DB-Engines.com的数据显示,Redis是最流行的键值对存储数据库。

  • Cassandra

Apache Cassandra(社区内通常简称为C*)是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的彻底分布式架构于一身。Facebook于2008将 Cassandra 开源,此后,因为Cassandra良好的可扩展性和性能,被 Apple, Comcast,Instagram, Spotify, eBay, Rackspace, Netflix等知名网站所采用,成为了一种流行的分布式结构化数据存储方案。

  • LevelDB
    image
    LevelDB是一个由Google公司所研发的键/值对(Key/Value Pair)嵌入式数据库管理系统编程库, 以开源的BSD许可证发布。

2.2.2 相关特性

以Redis为例: 优势以下:

  • 性能极高:Redis能支持超过10W的TPS
  • 丰富的数据类型: Redis支持包括String,Hash,List,Set,Sorted Set,Bitmap和hyperloglog
  • 丰富的特性:Redis还支持 publish/subscribe, 通知, key 过时等等特性

缺点以下: 针对ACID,Redis事务不能支持原子性和持久性(A和D),只支持隔离性和一致性(I和C) 特别说明一下,这里所说的没法保证原子性,是针对Redis的事务操做,由于事务是不支持回滚(roll back),而由于Redis的单线程模型,Redis的普通操做是原子性的

大部分业务不须要严格遵循ACID原则,例如游戏实时排行榜,粉丝关注等场景,即便部分数据持久化失败,其实业务影响也很是小。所以在设计方案时,须要根据业务特征和要求来作选择

2.2.3 使用场景

  • 适用场景 储存用户信息(好比会话)、配置文件、参数、购物车等等。这些信息通常都和ID(键)挂钩
  • 不适用场景
    • 须要经过值来查询,而不是键来查询。Key-Value数据库中根本没有经过值查询的途径。
    • 须要储存数据之间的关系。在Key-Value数据库中不能经过两个或以上的键来关联数据
    • 须要事务的支持。在Key-Value数据库中故障产生时不能够进行回滚。

2.3 文档数据库

文档数据库(也称为文档型数据库)是旨在将半结构化数据存储为文档的一种数据库。文档数据库一般以 JSON 或 XML 格式存储数据。

因为文档数据库的no-schema特性,能够存储和读取任意数据。

因为使用的数据格式是JSON或者BSON,由于JSON数据是自描述的,无需在使用前定义字段,读取一个JSON中不存在的字段也不会致使SQL那样的语法错误,能够解决关系型数据库表结构schema扩展不方便的问题

2.3.1 常见文档数据库

  • MongoDB

MongoDB是一种面向文档的数据库管理系统,由C++撰写而成,以此来解决应用程序开发社区中的大量现实问题。2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。

  • CouchDB

Apache CouchDB是一个开源数据库,专一于易用性和成为"彻底拥抱web的数据库"。它是一个使用JSON做为存储格式,JavaScript做为查询语言,MapReduce和HTTP做为API的NoSQL数据库。其中一个显著的功能就是多主复制。CouchDB的第一个版本发布在2005年,在2008年成为了Apache的项目。

2.3.2 相关特性

以MongoDB为例进行说明

优势以下:

  • 新增字段简单 无需像关系型数据库同样先执行DDL语句修改表结构,程序代码直接读写便可
  • 容易兼容历史数据 对于历史数据,即便没有新增的字段,也不会致使错误,只会返回空值,此时代码兼容处理便可
  • 容易存储复杂数据 JSON是一种强大的描述语言,可以描述复杂的数据结构

相比传统关系型数据库,文档数据库的缺点主要是对多条数据记录的事务支持较弱,具体体现以下:

  • Atomicity(原子性) 仅支持单行/文档级原子性,不支持多行、多文档、多语句原子性
  • Isolation(隔离性) 隔离级别仅支持已提交读(Read committed)级别,可能致使不可重复读,幻读的问题
  • 不支持复杂查询 例如join查询,若是须要join查询,须要屡次操做数据库

MongonDB仍是支持多文档事务的Consistency(一致性)和Durability(持久性)

虽然官方宣布MongoDB将在4.0版本中正式推出多文档ACID事务支持,最后落地状况还有待见证。

2.3.3 使用场景

适用场景

  • 数据量很大或者将来会变得很大
  • 表结构不明确,且字段在不断增长,例如内容管理系统,信息管理系统

不适用场景

  • 在不一样的文档上须要添加事务。Document-Oriented数据库并不支持文档间的事务
  • 多个文档直接须要复杂查询,例如join

2.4 全文搜索引擎

传统关系型数据库主要经过索引来达到快速查询的目的,在全文搜索的业务下,索引也无能为力,主要体如今:

  • 全文搜索的条件能够随意排列组合,若是经过索引来知足,则索引的数量很是多
  • 全文搜索的模糊匹配方式,索引没法知足,只能用like查询,而like查询是整表扫描,效率很是低

而全文搜索引擎的出现,正是解决关系型数据库全文搜索功能较弱的问题

2.4.1 基本原理

全文搜索引擎的技术原理称为“倒排索引”(inverted index),是一种索引方法,其基本原理是创建单词到文档的索引。与之相对是,是“正排索引”,其基本原理是创建文档到单词的索引。

如今有以下文档集合:

正排索引获得索引以下:

可见,正排索引适用于根据文档名称查询文档内容

简单的倒排索引以下:

简单的倒排索引

带有单词频率信息的倒排索引以下:

带有单词频率信息的倒排索

可见,倒排索引适用于根据关键词来查询文档内容

2.4.2 常见全文搜索引擎

  • Elasticsearch

    Elasticsearch是一个基于Lucene的搜索引擎。它提供了一个分布式,多租户 -可以全文搜索与发动机HTTP Web界面和无架构JSON文件。Elasticsearch是用Java开发的,并根据Apache License的条款做为开源发布。根据DB-Engines排名,Elasticsearch是最受欢迎的企业搜索引擎,后面是基于Lucene的Apache Solr。

  • Solr

    Solr是Apache Lucene项目的开源企业搜索平台。其主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本(如Word、PDF)的处理。Solr是高度可扩展的,并提供了分布式搜索和索引复制

2.4.3 相关特性

以Elasticsearch为例: 优势以下:

  • 查询效率高 对海量数据进行近实时的处理
  • 可扩展性 基于集群环境能够方便横向扩展,能够承载PB级数据
  • 高可用 Elasticsearch集群弹性-他们将发现新的或失败的节点,重组和从新平衡数据,确保数据是安全的和可访问的

缺点以下:

  • ACID支持不足 单一文档的数据是ACID的,包含多个文档的事务时不支持事务的正常回滚,支持 I(Isolation)隔离性(基于乐观锁机制的),D(Durability)持久性,不支持 A(Atomicity)原子性,C(Consistency)一致性
  • 对相似数据库中经过外键的复杂的多表关联操做支持较弱
  • 读写有必定延时,写入的数据,最快1s中能被检索到
  • 更新性能较低,底层实现是先删数据,再插入新数据
  • 内存占用大,由于Lucene 将索引部分加载到内存中

2.4.4 使用场景

适用场景以下:

  • 分布式的搜索引擎和数据分析引擎
  • 全文检索,结构化检索,数据分析
  • 对海量数据进行近实时的处理 能够将海量数据分散到多台服务器上去存储和检索

不适用场景以下:

  • 数据须要频繁更新
  • 须要复杂关联查询

2.5 图形数据库

图形数据库应用图形理论存储实体之间的关系信息。最多见例子就是社会网络中人与人之间的关系。关系型数据库用于存储“关系型”数据的效果并很差,其查询复杂、缓慢、超出预期,而图形数据库的独特设计偏偏弥补了这个缺陷,解决关系型数据库存储和处理复杂关系型数据功能较弱的问题。

2.5.1 常见图形数据库

  • Neo4j

Neo4j是由Neo4j,Inc。开发的图形数据库管理系统。由其开发人员描述为具备原生图存储和处理的符合ACID的事务数据库,根据DB-Engines排名, Neo4j是最流行的图形数据库。

  • ArangoDB

ArangoDB是由triAGENS GmbH开发的原生多模型数据库系统。数据库系统支持三个重要的数据模型(键/值,文档,图形),其中包含一个数据库核心和统一查询语言AQL(ArangoDB查询语言)。查询语言是声明性的,容许在单个查询中组合不一样的数据访问模式。ArangoDB是一个NoSQL数据库系统,但AQL在不少方面与SQL相似。

  • Titan

Titan是一个可扩展的图形数据库,针对存储和查询包含分布在多机群集中的数百亿个顶点和边缘的图形进行了优化。Titan是一个事务性数据库,能够支持数千个并发用户实时执行复杂的图形遍历。

2.5.2 相关特性

以Neo4j为例:

Neo4j 使用数据结构中图(graph)的概念来进行建模。 Neo4j 中两个最基本的概念是节点和边。节点表示实体,边则表示实体之间的关系。节点和边均可以有本身的属性。不一样实体经过各类不一样的关系关联起来,造成复杂的对象图。

针对关系数据,2种2数据库的存储结构不一样:

2种存储结构

Neo4j中,存储节点时使用了”index-free adjacency”,即每一个节点都有指向其邻居节点的指针,可让咱们在O(1)的时间内找到邻居节点。另外,按照官方的说法,在Neo4j中边是最重要的,是”first-class entities”,因此单独存储,这有利于在图遍历的时候提升速度,也能够很方便地以任何方向进行遍历

以下优势:

  • 高性能表现 图的遍历是图数据结构所具备的独特算法,即从一个节点开始,根据其链接的关系,能够快速和方便地找出它的邻近节点。这种查找数据的方法并不受数据量的大小所影响,由于邻近查询始终查找的是有限的局部数据,不会对整个数据库进行搜索

  • 设计的灵活性 数据结构的天然伸展特性及其非结构化的数据格式,让图数据库设计能够具备很大的伸缩性和灵活性。由于随着需求的变化而增长的节点、关系及其属性并不会影响到原来数据的正常使用

  • 开发的敏捷性 直观明了的数据模型,从需求的讨论开始,到程序开发和实现,以及最终保存在数据库中的样子,它的模样彷佛没有什么变化,甚至能够说原本就是如出一辙的

  • 彻底支持ACID 不像别的NoSQL数据库Neo4j还具备彻底事务管理特性,彻底支持ACID事务管理

缺点以下:

  • 具备支持节点,关系和属性的数量的限制
  • 不支持拆分

2.5.3 使用场景

适用场景以下:

  • 在一些关系性强的数据中,例如社交网络
  • 推荐引擎。若是咱们将数据以图的形式表现,那么将会很是有益于推荐的制定

不适用场景以下:

  • 记录大量基于事件的数据(例如日志条目或传感器数据)
  • 对大规模分布式数据进行处理,相似于Hadoop
  • 适合于保存在关系型数据库中的结构化数据
  • 二进制数据存储

3 总结

关系型数据库和NoSQL数据库的选型,每每须要考虑几个指标:

  • 数据量
  • 并发量
  • 实时性
  • 一致性要求
  • 读写分布和类型
  • 安全性
  • 运维成本

常见软件系统数据库选型参考以下:

  • 内部使用的管理型系统 如运营系统,数据量少,并发量小,首选考虑关系型
  • 大流量系统 如电商单品页,后台考虑选关系型,前台考虑选内存型
  • 日志型系统 原始数据考虑选列式,日志搜索考虑选倒排索引
  • 搜索型系统 例如站内搜索,非通用搜索,如商品搜索,后台考虑选关系型,前台考虑选倒排索引
  • 事务型系统 如库存,交易,记帐,考虑选关系型型+缓存+一致性型协议
  • 离线计算 如大量数据分析,考虑选列式或者关系型也能够
  • 实时计算 如实时监控,能够考虑选内存型或者列式数据库

设计实践中,要基于需求、业务驱动架构,不管选用RDB/NoSQL/DRDB,必定是以需求为导向,最终数据存储方案必然是各类权衡的综合性设计

参考

从0开始学架构 —— Alibaba 李运华

NoSQL漫谈

图形数据库 Neo4j 开发实战

大数据时代的 9 大Key-Value存储数据库

事务—— Redis官方文档

MongoDB是如何实现事务的ACID?

MySQL脏读、虚读、幻读

全面梳理关系型数据库和 NoSQL 的使用情景

浅析列式数据库的特色

一分钟搞懂列式与行式数据库

HBase 基本概念

NoSQL Databases, why we should use, and which one we should choose

传统关系数据库与分布式数据库知识点

相关文章
相关标签/搜索