一网打尽 NoSQL:当下 NoSQL 类型、适用场景及使用公司

前言

在互联网和大数据的背景下,越来越多的网站、应用系统需要支撑海量数据存储、高并发请求、高可用、高可扩展性等特性要求。传统的关系型数据库 RDBMS 已经难以应对类似的需求,各种各样的 NoSQL(Not Only SQL)数据库凭借易扩展、大数据量和高性能以及灵活的数据模型成功的在数据库领域站稳了脚跟。本文将分析传统数据库的存在的问题,以及几类 NoSQL 如何解决这些问题。在不同的业务场景下,作出正确的数据存储技术选型。

传统数据库缺点

缺点 解释说明
大数据场景下 I/O 较高 因为数据是按行存储,即使只针对其中某一列进行运算,关系型数据库也会对整行数据进行扫描,从存储设备中读入内存,导致 I/O 较高
结构化存储不够灵活 存储的是行记录,无法存储灵活的数据结构
表结构 schema 扩展不方便 如要需要修改表结构,需要执行执行 DDL(data definition language)语句修改,修改期间会导致锁表,部分服务不可用。
全文搜索功能较弱 关系型数据库只能够进行子字符串的匹配查询,当表的数据逐渐变大的时候,即使在有索引的情况下,like 扫表查询的匹配会非常慢
难以存储和处理复杂关系型数据 传统的关系数据库,并不擅长处理数据点之间的关系

NoSQL 简介

NoSQL,指的是非关系型的数据库,可以理解为关系型数据库的一个有力补充。NoSQL 有时也称作 Not Only SQL 的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称,它具有非关系型、分布式、不提供 ACID 的数据库设计模式等特征。

NoSQL 用于超大规模数据的存储(例如谷歌或 Facebook 每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

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

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

目前大家基本认同将 NoSQL 数据库分为四大类: 键值(Key-Value)数据库、列存储(Wide Column Store/Column-Family)数据库、 图(Graph-Oriented)数据库以及面向文档(Document-Oriented)数据库,其中每一种类型的数据库都能够解决关系型数据不能解决的问题。在实际应用中,NoSQL 数据库的分类界限其实没有那么明显,往往会是多种类型的组合体。

键值(Key-Value)数据库

使用键值(key-value)存储的数据库,其数据按照键值对的形式进行组织、索引和存储。KV 存储非常适合不涉及过多数据关系业务的数据。它能够有效减少读写磁盘的次数,比关系型数据库存储拥有更好的读写性能,能够解决关系型数据库无法存储的数据结构的问题。

常见 K-V 数据库 :Redis、Memcached、LevelDB、Cassandra

Redis

Redis 是一个使用 ANSI C 编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。Redis 是目前最流行的键值对存储数据库之一。

最佳应用场景:适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。

例如:股票价格、数据分析、实时数据搜集、实时通讯。

Memcached

Memcached 是一个开放源代码、高性能、分配的内存对象缓存系统。用于加速动态 web 应用程序,减轻关系型数据库负载。它可以应对任意多个连接,使用非阻塞的网络 IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个 Hash 表,Memcached 自管理这些 Hash 表。
Memcached 简单而强大。它简单的设计促进迅速部署,易于发现所面临的问题,解决了很多大型数据缓存。

Cassandra

Apache Cassandra(社区内一般简称为 C*)是一套开源的分布式 NoSQL 数据库系统。它最初由 Facebook 开发,用于储存收件箱等简单格式数据,集 Google BigTable 的数据模型与 Amazon Dynamo 的完全分布式架构于一身。Cassandra 是一种流行的分布式结构化数据存储方案。

最佳应用场景:当使用写操作多过读操作(记录日志)

例如:银行业,金融业(虽然对于金融交易不是必须的,但这些产业对数据库的要求会比它们更大)写比读更快,所以一个自然的特性就是实时数据分析

LevelDB

LevelDB 是一个由 Google 所研发的键/值对(Key/Value Pair)嵌入式数据库管理系统编程库,以开源的 BSD 许可证发布。LevelDB 是一个基于本地文件的存储引擎,非分布式存储引擎,原理基于 BigTable(LSM 文件树),无索引机制,存储条目为 Key-value。适用于保存数据缓存、日志存储、高速缓存等应用,主要是避免 RPC 请求带来的延迟问题。

相关特性

K-V 数据库的相关特性,以 Redis 为例说明::

优点

  • 性能极高:Redis 单机最高能支持超过 10W 的 TPS。
  • 丰富的数据类型:Redis 支持包括 String,Hash,List,Set,SortedSet,Bitmap 和 Hyperloglog 等数据结构。
  • 丰富的特性:Redis 还支持 publish/subscribe,通知,key 过期等特性。

缺点

  • Redis 事务不能支持原子性和持久性(A 和 D),只支持隔离性和一致性(I 和 C)。

应用场景

适用场景

内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。适合存储用户信息(比如会话)、配置文件、参数、购物车等等。这些信息一般都和 ID 挂钩。

不适用场景

  • 不适合需要通过值来查询,而不是键来查询。Key-Value 数据库中根本没有通过值查询的途径。
  • 不适合需要储存数据之间的关系。在 Key-Value 数据库中不能通过两个或以上的键来关联数据。
  • 不适合需要支持事务的场景。在 Key-Value 数据库中故障产生时不可以进行回滚。

列存储(Wide Column Store/Column-Family)数据库

列式数据库是以列相关存储架构进行数据存储的数据库,主要适合于批量数据处理和即时查询。相对应的是行式数据库,数据以行相关的存储架构进行空间分配,主要适合于小批量的数据处理,常用于联机事务型数据处理。基于列式数据库的列存储特性,可以解决某些特定场景下关系型数据库高 I/O 的问题。

常见列式数据库 :HBase、BigTable

HBase

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

最佳应用场景:适用于偏好 BigTable;对数据有版本查询需求,并且需要对大数据进行随机、实时访问的场合。

例如:Facebook 消息数据库

BigTable

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

相关特性

优点

  • 高效的储存空间利用率:列式数据库针对不同列的数据特征而发明了不同算法,使其比行式数据库高的多的压缩率。普通的行式数据库一般压缩率在 3:1 到 5:1 左右,而列式数据库的压缩率一般在 8:1 到 30:1 左右。
  • 查询效率高:读取多条数据的同一列效率高,因为这些列都是存储在一起的,一次磁盘操作可以把数据的指定列全部读取到内存中。
  • 适合做聚合操作
  • 适合大量的数据而不是小数据

缺点

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

应用场景

列数据库的适用场景,以 HBase 为例说明:

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

图(Graph-Oriented)数据库

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

常见图形数据库 :Neo4j、ArangoDB

Neo4j

Neo4j 是一个高性能的,NOSQL 图形数据库,它将结构化数据存储在 “图形网络上” 而不是“表中”。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的 Java 持久化引擎。Neo4j 也可以被看作是一个高性能的图引擎。

最佳应用场景:适用于图形一类数据。这是 Neo4j 与其他 nosql 数据库的最显著区别

例如:社会关系,公共交通网络,地图及网络拓谱

ArangoDB

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

相关特性

优点

  • 高性能表现:图的遍历是图数据结构所具有的独特算法,即从一个节点开始,根据其连接的关系,可以快速和方便地找出它的邻近节点。这种查找数据的方法不受数据量大小的影响,因为邻近查询始终查找的是有限的局部数据,不会对整个数据库进行搜索。利用图结构相关算法。比如最短路径寻址,N 度关系查找等。
  • 设计的灵活性:数据结构的自然伸展特性,以及其非结构化的数据格式,让图数据库设计可以具有很大的伸缩性和灵活性。因为随着需求的变化而增加的节点、关系及其属性,并不会影响到原来数据的正常使用。
  • 开发的敏捷性:数据模型直接明了,从需求的讨论开始,到程序开发和实现,基本上不会有大的变化。
  • 完全支持 ACID:不像别的 NoSQL 数据库,Neo4j 还完全具有事务管理特性,完全支持 ACID 事务管理。

缺点

  • 节点,关系和它们的属性的数量被限制。
  • 不支持拆分,图数据库结构不太好做分布式的集群方案。

应用场景

适用场景

专注于构建关系图谱,善于处理大量复杂、互连接、低结构化的数据,数据往往变化迅速,且查询频繁。(1)在一些关系性强的数据应用,例如社交网络。(2)推荐引擎,将数据以图的形式表现,非常有益于推荐的制定。

不适用场景

  • 记录大量基于事件的数据,如日志记录、传感器数据。
  • 对大规模分布式数据进行处理,类似于 Hadoop。
  • 不适用于应该保存在关系型数据库中的结构化数据。
  • 二进制数据存储。

面向文档(Document-Oriented)数据库

文档数据库用于将半结构化数据存储为文档的一种数据库。文档数据库通常以 JSON 或 XML 格式存储数据。(1)由于文档数据库的 no-schema 特性,可以存储和读取任意数据。(2)由于使用的数据格式是 JSON 或者 BSON,因为 JSON 数据是自描述的,无需在使用前定义字段,读取一个 JSON 中不存在的字段也不会导致 SQL 那样的语法错误,可以解决关系型数据库表结构 schema 扩展不方便的问题。

常见文档数据库 :MongoDB、ArangoDB

MongoDB

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的 NoSQL。

最佳应用场景:适用于需要动态查询支持;需要使用索引而不是 map/reduce 功能;需要对大数据库有性能要求;需要使用 CouchDB 但因为数据改变太频繁而占满内存的应用程序。

例如:你本打算采用 MySQL 或 PostgreSQL,但因为它们本身自带的预定义栏让你望而却步。

CouchDB

CouchDB 是用 Erlang 开发的面向文档的分布式数据库,用于存储半结构化的数据,比较类似 lucene 的 index 结构。CouchDB 支持 RESTful API,它使用 JSON 作为存储格式,JavaScript 作为查询语言,MapReduce 和 HTTP 作为 API 的 NoSQL 数据库。其中一个显著的功能就是多主复制功能。除此之外,CouchDB 构建在强大的 B - 树储存引擎之上。

最佳应用场景:适用于数据变化较少,执行预定义查询,进行数据统计的应用程序。适用于需要提供数据版本支持的应用程序。

例如: CRM、CMS 系统。 master-master 复制对于多站点部署是非常有用的。

相关特性

文档型数据库的相关特性,以 MongoDB 为例进行说明:

优点

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

缺点

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

应用场景

适用场景

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

不适用场景

  • 在不同的文档上需要添加事务。Document-Oriented 数据库并不支持文档间的事务。
  • 多个文档之间需要复杂的查询,例如 join 操作。

参考博文

[1]. 浅谈常见的 NoSQL 技术方案和选型


谢谢你长得那么好看,还打赏我!😘
0%