NoSQL还是SQL?这一篇讲清楚

作者 : 开心源码 本文共7696个字,预计阅读时间需要20分钟 发布时间: 2022-05-12 共128人阅读

传统的关系型数据库在应付这些已经显得力不从心,并暴露了许多难以克服的问题。

由此,各种各样的 NoSQL(Not Only SQL)数据库作为传统关系型数据的一个有力补充得到迅猛发展。

本文将分析传统数据库存在的少量问题,以及几大类 NoSQL 如何处理这些问题,希望给大家提供少量在不同业务场景下存储技术选型方面的参考。

传统数据库的缺点

传统的数据库有如下几个缺点:

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

存储的是行记录,无法存储数据结构。

表结构 Schema 扩展不方便,如要修改表结构,需要执行 DDL(data definition language),语句修改,修改期间会导致锁表,部分服务不可使用。

全文搜索功能较弱,关系型数据库下只能够进行子字符串的匹配查询,当表的数据逐步变大的时候,like 查询的匹配会非常慢,即便在有索引的情况下。况且关系型数据库也不应该对文本字段进行索引。

存储和解决复杂关系型数据功能较弱,许多应使用程序需要理解和导航高度连接数据之间的关系,才能启使用社交应使用程序、推荐引擎、欺诈检测、知识图谱、生命科学和 IT/网络等使用例。

然而传统的关系数据库并不善于解决数据点之间的关系。它们的表格数据模型和严格的模式使它们很难增加新的或者不同种类的关联信息。

NoSQL 处理方案

NoSQL,泛指非关系型的数据库,可以了解为 SQL 的一个有力补充。

在 NoSQL 许多方面性能大大优于非关系型数据库的同时,往往也伴随少量特性的缺失,比较常见的是事务库事务功能的缺失。

数据库事务正确执行的四个基本要素 ACID 如下:

下面详情 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)。

查询效率高:读取多条数据的同一列效率高,由于这些列都是存储在一起的,一次磁盘操作可以把数据的指定列一律读取到内存中。

下图通过一条查询的执行过程说明列式存储(以及数据压缩)的优点。

执行步骤如下:

去字典表里找到字符串对应数字(只进行一次字符串比较)。

使用数字去列表里匹配,匹配上的位置设为 1。?

把不同列的匹配结果进行位运算得到符合所有条件的记录下标。

用这个下标组装出最终的结果集。

列式数据库还适合做聚合操作,适合大量的数据而不是小数据。

缺点如下:

不适合扫描小量数据。

不适合随机的升级。

不适合做含有删除和升级的实时操作。

单行的数据是 ACID 的,多行的事务时,不支持事务的正常回滚,支持 I(Isolation)隔离性(事务串行提交),D(Durability)持久性,不能保证 A(Atomicity)原子性, C(Consistency)一致性。

用场景

以 HBase 为例说明:

大数据量(100s TB级数据),且有快速随机访问的需求。

写密集型应使用,每天写入量巨大,而相对读数量较小的应使用,比方 IM 的历史消息,游戏的日志等等。

不需要复杂查询条件来查询数据的应使用,HBase 只支持基于 rowkey 的查询,对于 HBase 来说,单条记录或者者小范围的查询是可以接受的。

大范围的查询因为分布式的起因,可能在性能上有点影响,HBase 不适使用于有 join,多级索引,表关系复杂的数据模型。

对性能和可靠性要求非常高的应使用,因为 HBase 本身没有单点故障,可使用性非常高。

数据量较大,而且增长量无法预估的应使用,需要进行优雅的数据扩展的 HBase 支持在线扩展,即便在一段时间内数据量呈井喷式增长,也可以通过 HBase 横向扩展来满足功能。

存储结构化和半结构化的数据。

K-V 数据库

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

K-V 存储非常适合不涉及过多数据关系业务关系的数据,同时能有效减少读写磁盘的次数,比 SQL 数据库存储拥有更好的读写性能,能够处理关系型数据库无法存储数据结构的问题。

常见 K-V 数据库

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,Comcas,Instagram,Spotify,eBay,Rackspace,Netflix 等知名网站所采使用,成为了一种流行的分布式结构化数据存储方案。

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

相关特性

以 Redis 为例,K-V 数据库优点如下:

性能极高: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 准则,例如游戏实时排行榜,粉丝关注等场景,即便部分数据持久化失败,其实业务影响也非常小。因而在设计方案时,需要根据业务特征和要求来做选择。

用场景

适使用场景:

储存使用户信息(比方会话)、配置文件、参数、购物车等等。这些信息一般都和 ID(键)挂钩。

不适使用场景:

需要通过值来查询,而不是键来查询。Key-Value 数据库中根本没有通过值查询的途径。

需要储存数据之间的关系。在 Key-Value 数据库中不能通过两个或者以上的键来关联数据。

需要事务的支持。在 Key-Value 数据库中故障产生时不可以进行回滚。

文档数据库

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

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

因为用的数据格式是 JSON 或者者 BSON,由于 JSON 数据是自形容的,无需在用前定义字段,读取一个 JSON 中不存在的字段也不会导致 SQL 那样的语法错误,可以处理关系型数据库表结构 Schema 扩展不方便的问题。

常见文档数据库

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

CouchDB:Apache CouchDB 是一个开源数据库,专注于易使用性和成为”完全拥抱 Web 的数据库”。

它是一个用 JSON 作为存储格式,JavaScript 作为查询语言,MapReduce 和 HTTP 作为 API 的 NoSQL 数据库。

其中一个明显的功能就是多主复制。CouchDB 的第一个版本发布在 2005 年,在 2008 年成为了 Apache 的项目。

相关特性

以 MongoDB 为例进行说明,文档数据库优点如下:

新添加字段简单,无需像关系型数据库一样先执行 DDL 语句修改表结构,程序代码直接读写就可。

容易兼容历史数据,对于历史数据,即便没有新添加的字段,也不会导致错误,只会返回空值,此时代码兼容解决就可。

容易存储复杂数据,JSON 是一种强大的形容语言,能够形容复杂的数据结构。

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

Atomicity(原子性),仅支持单行/文档级原子性,不支持多行、多文档、多语句原子性。

Solation(隔离性),隔离级别仅支持已提交读(Read committed)级别,可能导致不可重复读,幻读的问题。

不支持复杂查询,例如 join 查询,假如需要 join 查询,需要屡次操作数据库。

MongonDB 还支持多文档事务的 Consistency(一致性)和 Durability(持久性),尽管官方宣布 MongoDB 将在 4.0 版本中正式推出多文档 ACID 事务支持,最后落地情况还有待见证。

用场景

适使用场景:

数据量很大或者者未来会变得很大。

表结构不明确,且字段在不断添加,例如内容管理系统,信息管理系统。

不适使用场景:

在不同的文档上需要增加事务。Document-Oriented 数据库并不支持文档间的事务。

多个文档之间需要复杂查询,例如 join。

全文搜索引擎

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

全文搜索的条件可以随便排列组合,假如通过索引来满足,则索引的数量非常多。

全文搜索的模糊匹配方式,索引无法满足,只能使用 like 查询,而 like 查询是整表扫描,效率非常低。

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

基本原理

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

现在有如下文档集合:

正排索引得到索引如下:

由上可见,正排索引适使用于根据文档名称查询文档内容。简单的倒排索引如下:

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

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

常见全文搜索引擎

Elasticsearch:是一个基于 Lucene 的搜索引擎。它提供了一个分布式,多租户,能够全文搜索与发动机 HTTP Web 界面和无架构 JSON 文件。

Elasticsearch 是使用 Java 开发的,并根据 Apache License 的条款作为开源发布。

根据 DB-Engines 排名,Elasticsearch 是最受欢迎的企业搜索引擎,后面是基于 Lucene 的 Apache Solr。

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

相关特性

以 Elasticsearch 为例,全文搜索引擎优点如下:

查询效率高,对海量数据进行近实时的解决。

可扩展性,基于集群环境可以方便横向扩展,可以承载 PB 级数据。

高可使用,Elasticsearch 集群弹性,他们将发现新的或者失败的节点,重组和重新平衡数据,确保数据是安全的和可访问的。

缺点如下:

ACID 支持不足,单一文档的数据是 ACID 的,包含多个文档的事务时不支持事务的正常回滚,支持 I(Isolation)隔离性(基于乐观锁机制的),D(Durability)持久性,不支持 A(Atomicity)原子性,C(Consistency)一致性。

对相似数据库中通过外键的复杂的多表关联操作支持较弱。

读写有肯定延时,写入的数据,最快 1s 中能被检索到。

升级性能较低,底层实现是先删数据,再插入新数据。

内存占使用大,由于 Lucene 将索引部分加载到内存中。

用场景

适使用场景如下:

分布式的搜索引擎和数据分析引擎。

全文检索,结构化检索,数据分析。

对海量数据进行近实时的解决,可以将海量数据分散到多台服务器上去存储和检索。

不适使用场景如下:

数据需要频繁升级。

需要复杂关联查询。

图形数据库

图形数据库应使用图形理论存储实体之间的关系信息。最常见例子就是社会网络中人与人之间的关系。

关系型数据库使用于存储“关系型”数据的效果并不好,其查询复杂、缓慢、超出预期。

而图形数据库的独特设计恰恰弥补了这个缺陷,处理关系型数据库存储和解决复杂关系型数据功能较弱的问题。

常见图形数据库

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

ArangoDB:是由 triAGENS GmbH 开发的原生多模型数据库系统。数据库系统支持三个重要的数据模型(键/值,文档,图形),其中包含一个数据库核心和统一查询语言 AQL(ArangoDB 查询语言)。

查询语言是公告性的,允许在单个查询中组合不同的数据访问模式。ArangoDB 是一个 NoSQL 数据库系统,但 AQL 在很多方面与 SQL 相似。

Titan:是一个可扩展的图形数据库,针对存储和查询包含分布在多机群集中的数百亿个顶点和边缘的图形进行了优化。

Titan 是一个事务性数据库,可以支持数千个并发使用户实时执行复杂的图形遍历。

相关特性

以 Neo4j 为例,Neo4j 用数据结构中图(graph)的概念来进行建模。Neo4j 中两个最基本的概念是节点和边。

节点表示实体,边则表示实体之间的关系。节点和边都可以有自己的属性。不同实体通过各种不同的关系关联起来,形成复杂的对象图。

针对关系数据,两种数据库的存储结构不同:

Neo4j 中,存储节点时用了“index-free adjacency”,即每个节点都有指向其邻居节点的指针,可以让我们在 O(1) 的时间内找到邻居节点。

另外,按照官方的说法,在 Neo4j 中边是最重要的,即“first-class entities”,所以单独存储,这有利于在图遍历的时候提高速度,也可以很方便地以任何方向进行遍历。

优点如下:

高性能体现,图的遍历是图数据结构所具备的独特算法,即从一个节点开始,根据其连接的关系,可以快速和方便地找出它的邻近节点。

这种查找数据的方法并不受数据量的大小所影响,由于邻近查询始终查找的是有限的局部数据,不会对整个数据库进行搜索。

设计的灵活性,数据结构的自然伸展特性及其非结构化的数据格式,让图数据库设计可以具备很大的伸缩性和灵活性。

由于随着需求的变化而添加的节点、关系及其属性并不会影响到原来数据的正常用。

开发的敏捷性,直观明了的数据模型,从需求的探讨开始,到程序开发和实现,以及最终保存在数据库中的样子,它的模样似乎没有什么变化,甚至可以说原本就是一模一样的。

完全支持 ACID,不像别的 NoSQL 数据库,Neo4j 还具备完全事务管理特性,完全支持 ACID 事务管理。

缺点如下:

具备支持节点,关系和属性的数量的限制。

不支持拆分。

用场景

适使用场景如下:

在少量关系性强的数据中,例如社交网络。

推荐引擎。假如我们将数据以图的形式体现,那么将会非常有益于推荐的制定。

不适使用场景如下:

记录大量基于事件的数据(例如日志条目或者传感器数据)。

对大规模分布式数据进行解决,相似于 Hadoop。

适合于保存在关系型数据库中的结构化数据。

二进制数据存储。

总结

关系型数据库和 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

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

假如大家喜欢这篇文章的话,希望大家能够收藏,转发 谢谢!更多相关资讯可以关注西安华美校区,免费取得java零基础教程!额外附送excel教程!

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » NoSQL还是SQL?这一篇讲清楚

发表回复