文章首发于51CTO技术栈公众号
做者 陈彩华
文章转载交流请联系 caison@aliyun.com
复制代码
随着大数据时代的到来,愈来愈多的网站、应用系统须要支撑海量数据存储,高并发请求、高可用、高可扩展性等特性要求,传统的关系型数据库在应付这些调整已经显得力不从心,暴露了许多能以克服的问题。由此,各类各样的NoSQL(Not Only SQL)数据库做为传统关系型数据的一个有力补充获得迅猛发展。html
本文将分析传统数据库的存在的相关问题,以及几大类NoSQL如何解决这些问题,但愿给你们提供在不一样业务场景下,关于存储方面技术选型提供参考。java
大数据场景下I/O较高 由于数据是按行存储,即便只针对其中某一列进行运算,关系型数据库也会将整行数据从存储设备中读入内存,致使I/O较高web
存储的是行记录,没法存储数据结构redis
表结构schema扩展不方便 如要须要修改表结构,须要执行执行DDL(data definition language),语句修改,修改期间会致使锁表,部分服务不可用算法
全文搜索功能较弱 关系型数据库下只可以进行子字符串的匹配查询,当表的数据逐渐变大的时候,like查询的匹配会很是慢,即便在有索引的状况下。何况关系型数据库也不该该对文本字段进行索引sql
存储和处理复杂关系型数据功能较弱 许多应用程序须要了解和导航高度链接数据之间的关系,才能启用社交应用程序、推荐引擎、欺诈检测、知识图谱、生命科学和 IT/网络等用例。然而传统的关系数据库并不善于处理数据点之间的关系。它们的表格数据模型和严格的模式使它们很难添加新的或不一样种类的关联信息。数据库
NoSQL,泛指非关系型的数据库,能够理解为SQL的一个有力补充。编程
在NoSQL许多方面性能大大优于非关系型数据库的同时,每每也伴随一些特性的缺失,比较常见的,是事务库事务功能的缺失。 数据库事务正确执行的四个基本要素:ACID以下:缓存
名称 | 描述 | |
---|---|---|
A | Atomicity (原子性) |
一个事务中的全部操做,要么所有完成,要么所有不完成,不会在中间某个环节结束。 事务在执行过程当中发生错误,会被回滚到事务开始前的状态,就像这个事务历来没有执行过同样。 |
C | Consistency 一致性 |
在事务开始以前和事务结束之后,数据库的完整性没有被破坏。 |
I | Isolation 隔离性 |
数据库容许多个并发事务同时对数据进行读写和修改的能力。隔离性能够防止多个事务并发执行时因为交叉执行而致使数据的不一致。 |
D | Durability 持久性 |
事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失。 |
下面介绍5大类NoSQL数据针对传统关系型数据库的缺点提供的解决方案:安全
列式数据库是以列相关存储架构进行数据存储的数据库,主要适合于批量数据处理和即时查询。相对应的是行式数据库,数据以行相关的存储体系架构进行空间分配,主要适合于小批量的数据处理,经常使用于联机事务型数据处理。
基于列式数据库的列列存储特性,能够解决某些特定场景下关系型数据库I/O较高的问题
传统关系型数据库是按照行来存储数据库,称为“行式数据库”,而列式数据库是按照列来存储数据。
将表放入存储系统中有两种方法,而咱们绝大部分是采用行存储的。 行存储法是将各行放入连续的物理位置,这很像传统的记录和文件系统。 列存储法是将数据按照列存储到数据库中,与行存储相似,下图是两种存储方法的图形化解释:
HBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现的编程语言为 Java。它是Apache软件基金会的Hadoop项目的一部分,运行于HDFS文件系统之上,为 Hadoop 提供相似于BigTable 规模的服务。所以,它能够容错地存储海量稀疏的数据。
BigTable是一种压缩的、高性能的、高可扩展性的,基于Google文件系统(Google File System,GFS)的数据存储系统,用于存储大规模结构化数据,适用于云端计算。
优势以下:
列式数据库因为其针对不一样列的数据特征而发明的不一样算法使其每每有比行式数据库高的多的压缩率,普通的行式数据库通常压缩率在3:1 到5:1 左右,而列式数据库的压缩率通常在8:1到30:1 左右。 比较常见的,经过字典表压缩数据: 下面中才是那张表原本的样子。通过字典表进行数据压缩后,表中的字符串才都变成数字了。正由于每一个字符串在字典表里只出现一次了,因此达到了压缩的目的(有点像规范化和非规范化Normalize和Denomalize)
读取多条数据的同一列效率高,由于这些列都是存储在一块儿的,一次磁盘操做能够数据的指定列所有读取到内存中。 下图经过一条查询的执行过程说明列式存储(以及数据压缩)的优势
执行步骤以下:
i. 去字典表里找到字符串对应数字(只进行一次字符串比较)。
ii. 用数字去列表里匹配,匹配上的位置设为1。
iii. 把不一样列的匹配结果进行位运算获得符合全部条件的记录下标。
iv. 使用这个下标组装出最终的结果集。
复制代码
适合作聚合操做
适合大量的数据而不是小数据
缺点以下:
以HBase为例说明:
指的是使用键值(key-value)存储的数据库,其数据按照键值对的形式进行组织、索引和存储。
KV 存储很是适合不涉及过多数据关系业务关系的数据,同时能有效减小读写磁盘的次数,比 SQL 数据库存储拥有更好的读写性能,可以解决关系型数据库没法存储数据结构的问题。
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。从2015年6月开始,Redis的开发由Redis Labs赞助,而2013年5月至2015年6月期间,其开发由Pivotal赞助。在2013年5月以前,其开发由VMware赞助。根据月度排行网站DB-Engines.com的数据显示,Redis是最流行的键值对存储数据库。
Apache Cassandra(社区内通常简称为C*)是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的彻底分布式架构于一身。Facebook于2008将 Cassandra 开源,此后,因为Cassandra良好的可扩展性和性能,被 Apple, Comcast,Instagram, Spotify, eBay, Rackspace, Netflix等知名网站所采用,成为了一种流行的分布式结构化数据存储方案。
以Redis为例: 优势以下:
缺点以下: 针对ACID,Redis事务不能支持原子性和持久性(A和D),只支持隔离性和一致性(I和C) 特别说明一下,这里所说的没法保证原子性,是针对Redis的事务操做,由于事务是不支持回滚(roll back),而由于Redis的单线程模型,Redis的普通操做是原子性的
大部分业务不须要严格遵循ACID原则,例如游戏实时排行榜,粉丝关注等场景,即便部分数据持久化失败,其实业务影响也很是小。所以在设计方案时,须要根据业务特征和要求来作选择
文档数据库(也称为文档型数据库)是旨在将半结构化数据存储为文档的一种数据库。文档数据库一般以 JSON 或 XML 格式存储数据。
因为文档数据库的no-schema特性,能够存储和读取任意数据。
因为使用的数据格式是JSON或者BSON,由于JSON数据是自描述的,无需在使用前定义字段,读取一个JSON中不存在的字段也不会致使SQL那样的语法错误,能够解决关系型数据库表结构schema扩展不方便的问题
MongoDB是一种面向文档的数据库管理系统,由C++撰写而成,以此来解决应用程序开发社区中的大量现实问题。2007年10月,MongoDB由10gen团队所发展。2009年2月首度推出。
Apache CouchDB是一个开源数据库,专一于易用性和成为"彻底拥抱web的数据库"。它是一个使用JSON做为存储格式,JavaScript做为查询语言,MapReduce和HTTP做为API的NoSQL数据库。其中一个显著的功能就是多主复制。CouchDB的第一个版本发布在2005年,在2008年成为了Apache的项目。
以MongoDB为例进行说明
优势以下:
相比传统关系型数据库,文档数据库的缺点主要是对多条数据记录的事务支持较弱,具体体现以下:
MongonDB仍是支持多文档事务的Consistency(一致性)和Durability(持久性)
虽然官方宣布MongoDB将在4.0版本中正式推出多文档ACID事务支持,最后落地状况还有待见证。
适用场景:
不适用场景:
传统关系型数据库主要经过索引来达到快速查询的目的,在全文搜索的业务下,索引也无能为力,主要体如今:
而全文搜索引擎的出现,正是解决关系型数据库全文搜索功能较弱的问题
全文搜索引擎的技术原理称为“倒排索引”(inverted index),是一种索引方法,其基本原理是创建单词到文档的索引。与之相对是,是“正排索引”,其基本原理是创建文档到单词的索引。
如今有以下文档集合:
正排索引获得索引以下:
可见,正排索引适用于根据文档名称查询文档内容
简单的倒排索引以下:
带有单词频率信息的倒排索引以下:
可见,倒排索引适用于根据关键词来查询文档内容
Elasticsearch
Solr
以Elasticsearch为例: 优势以下:
缺点以下:
适用场景以下:
不适用场景以下:
图形数据库应用图形理论存储实体之间的关系信息。最多见例子就是社会网络中人与人之间的关系。关系型数据库用于存储“关系型”数据的效果并很差,其查询复杂、缓慢、超出预期,而图形数据库的独特设计偏偏弥补了这个缺陷,解决关系型数据库存储和处理复杂关系型数据功能较弱的问题。
Neo4j是由Neo4j,Inc。开发的图形数据库管理系统。由其开发人员描述为具备原生图存储和处理的符合ACID的事务数据库,根据DB-Engines排名, Neo4j是最流行的图形数据库。
ArangoDB是由triAGENS GmbH开发的原生多模型数据库系统。数据库系统支持三个重要的数据模型(键/值,文档,图形),其中包含一个数据库核心和统一查询语言AQL(ArangoDB查询语言)。查询语言是声明性的,容许在单个查询中组合不一样的数据访问模式。ArangoDB是一个NoSQL数据库系统,但AQL在不少方面与SQL相似。
Titan是一个可扩展的图形数据库,针对存储和查询包含分布在多机群集中的数百亿个顶点和边缘的图形进行了优化。Titan是一个事务性数据库,能够支持数千个并发用户实时执行复杂的图形遍历。
以Neo4j为例:
Neo4j 使用数据结构中图(graph)的概念来进行建模。 Neo4j 中两个最基本的概念是节点和边。节点表示实体,边则表示实体之间的关系。节点和边均可以有本身的属性。不一样实体经过各类不一样的关系关联起来,造成复杂的对象图。
针对关系数据,2种2数据库的存储结构不一样:
Neo4j中,存储节点时使用了”index-free adjacency”,即每一个节点都有指向其邻居节点的指针,可让咱们在O(1)的时间内找到邻居节点。另外,按照官方的说法,在Neo4j中边是最重要的,是”first-class entities”,因此单独存储,这有利于在图遍历的时候提升速度,也能够很方便地以任何方向进行遍历
以下优势:
高性能表现 图的遍历是图数据结构所具备的独特算法,即从一个节点开始,根据其链接的关系,能够快速和方便地找出它的邻近节点。这种查找数据的方法并不受数据量的大小所影响,由于邻近查询始终查找的是有限的局部数据,不会对整个数据库进行搜索
设计的灵活性 数据结构的天然伸展特性及其非结构化的数据格式,让图数据库设计能够具备很大的伸缩性和灵活性。由于随着需求的变化而增长的节点、关系及其属性并不会影响到原来数据的正常使用
开发的敏捷性 直观明了的数据模型,从需求的讨论开始,到程序开发和实现,以及最终保存在数据库中的样子,它的模样彷佛没有什么变化,甚至能够说原本就是如出一辙的
彻底支持ACID 不像别的NoSQL数据库Neo4j还具备彻底事务管理特性,彻底支持ACID事务管理
缺点以下:
适用场景以下:
不适用场景以下:
关系型数据库和NoSQL数据库的选型,每每须要考虑几个指标:
常见软件系统数据库选型参考以下:
设计实践中,要基于需求、业务驱动架构,不管选用RDB/NoSQL/DRDB,必定是以需求为导向,最终数据存储方案必然是各类权衡的综合性设计
NoSQL Databases, why we should use, and which one we should choose