前言
在互联网和大数据的背景下,越来越多的网站、应用系统需要支撑
本文将分析 传统数据库 的存在的问题,以及几类 NoSQL 如何解决这些问题。在不同的 业务场景 下,作出正确的 数据存储 技术选型。
正文
1. 传统数据库缺点
2. NoSQL简介
NoSQL,泛指 非关系型
NoSQL 在许多方面性能大大优于 非关系型 数据库的同时,往往也伴随一些特性的缺失。比较常见的是 事务功能 的缺失。 数据库事务正确执行的四个基本要素 ACID 如下:
针对传统 关系型数据库
3. 列式数据库
列式数据库 是以 列相关存储架构 进行数据存储的数据库,主要适合于 批量数据处理 和 即时查询。相对应的是 行式数据库,数据以 行相关的存储架构 进行空间分配,主要适合于 小批量 的 数据处理,常用于 联机事务型数据处理。
基于列式数据库的 列存储特性,可以解决某些特定场景下 关系型数据库 高 I/O 的问题。
3.1. 基本原理
传统关系型数据库是 按照行 来存储数据库,称为 行式数据库,而 列式数据库 是 按照列 来存储数据。
将表放入存储系统中有两种方法,而我们绝大部分是采用 行存储 的。行存储法是将 各行 放入 连续的物理位置,这很像传统的记录和文件系统。
列存储法 是将数据 按照列 存储到数据库中,与 行存储 类似,下图是两种存储方法的图形化解释:
3.2. 常见列式数据库
3.2.1. HBase
HBase 是一个开源的 非关系型分布式数据库(NoSQL),它参考了 谷歌 的 BigTable 建模,实现的编程语言为 Java。它是 Apache 软件基金会的 Hadoop 项目的一部分,运行于 HDFS 文件系统之上,为 Hadoop 提供类似于 BigTable 规模的服务。因此,它可以 容错地 存储 海量稀疏 的数据。
3.2.2. BigTable
BigTable 是一种 压缩的、高性能的、高可扩展性的,基于 Google 文件系统(Google File System,GFS)的数据存储系统,用于存储 大规模结构化数据,适用于云计算。
3.3. 相关特性
3.3.1. 优点
高效的储存空间利用率列式数据库 针对不同列的 数据特征 而发明了 不同算法,使其比 行式数据库 高的多的 压缩率。普通的 行式数据库 一般压缩率在 3:1 到 5:1 左右,而 列式数据库 的压缩率一般在 8:1 到 30:1 左右。
比较常见的,通过 字典表 压缩数据:
下面才是那张表本来的样子。经过 字典表 进行 数据压缩 后,表中的 字符串 才都变成 数字。正因为每个字符串在 字典表 里只 出现了一次,所以达到了 压缩 的目的。
查询效率高读取多条数据的 同一列效率高,因为这些列都是 存储在一起的,一次磁盘操作可以数据的 指定列 全部读取到 内存 中。 下图通过 一条查询 的执行过程说明 列式存储 (以及 数据压缩)的优点。
执行步骤如下:
去 字典表 里找到 字符串对应数字(只进行一次字符串比较)。用 数字 去列表里匹配,匹配上的位置设为 1。把 不同列 的 匹配结果 进行 位运算 得到符合所有条件的3.3.2. 缺点
不适合扫描 小量数据不适合 随机的更新不适合做含有删除和更新的 实时操作单行数据 支持 ACID 的 事务操作,多行数据 的 事务操作,不支持事务的 正常回滚,支持 (Isolation)隔离性、(Durability)持久性,不能保证 (Atomicity)原子性、(Consistency)一致性。3.4. 应用场景
列数据库的适用场景,以 HBase 为例说明:
适合 大数据量 (100TB 级数据),有4. K-V数据库
4.1. 基本概念
指的是使用 键值(key-value)存储的数据库,其数据按照 键值对 的形式进行 组织、索引 和 存储。
KV 存储非常适合不涉及过多 数据关系 业务的数据。它能够有效减少
4.2. 常见K-V数据库
4.2.1. Redis
Redis 是一个使用 ANSI C 编写的 开源、支持网络、基于内存、可选持久性 的 键值对存储 数据库。Redis 是目前最流行的 键值对存储 数据库之一。
4.2.2. Cassandra
Apache Cassandra(社区内一般简称为 C*)是一套 开源的分布式 NoSQL 数据库系统。它最初由 Facebook 开发,用于储存 收件箱 等简单格式数据,集 Google BigTable 的 数据模型 与 Amazon Dynamo 的 完全分布式 架构于一身。Cassandra 是一种流行的 分布式结构化 数据存储方案。
4.2.3. Memcached
Memcached 是一个 开放源代码、高性能、分配的 内存对象缓存系统。用于加速动态 web 应用程序,减轻关系型数据库负载。它可以应对 任意多个连接,使用 非阻塞的网络 IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个 Hash 表,Memcached 自管理这些 Hash 表。
Memcached 简单而强大。它简单的设计促进 迅速部署,易于发现所面临的问题,解决了很多 大型数据缓存。
4.2.4. LevelDB
LevelDB 是一个由 Google 所研发的 键/值对(Key/Value Pair)嵌入式 数据库管理系统 编程库,以开源的 BSD 许可证发布。
4.3. 相关特性
K-V 数据库的相关特性,以 Redis 为例说明:
4.3.1. 优点
性能极高Redis 单机最高能支持超过 10W 的 TPS。
丰富的数据类型Redis 支持包括 String,Hash,List,Set,Sorted Set,Bitmap 和 Hyperloglog 等数据结构。
丰富的特性Redis 还支持 publish/subscribe,通知,key 过期 等特性。
4.3.2. 缺点
Redis 事务 不能支持 原子性 和 持久性(A 和 D),只支持 隔离性 和 一致性(I 和 C)。这里所说的 无法保证原子性,是针对 Redis 的 事务操作,因为事务是 不支持回滚(roll back),而因为 Redis 的 单线程模型4.4 应用场景
4.4.1. 适用场景
适合存储 用户信息(比如 会话)、配置文件、参数、购物车 等等。这些信息一般都和 ID 挂钩。4.4.2. 不适用场景
不适合需要通过 值 来查询,而不是 键 来查询。Key-Value 数据库中根本没有通过 值查询 的途径。不适合需要储存 数据之间的关系。在 Key-Value 数据库中不能通过 两个或以上 的键来 关联数据。不适合需要支持 事务 的场景。在 Key-Value 数据库中 故障产生5. 文档型数据库
5.1. 基本概念
文档数据库 用于将 半结构化数据 存储为 文档 的一种数据库。文档数据库通常以 JSON 或 XML 格式存储数据。
由于文档数据库的 no-schema 特性,可以 存储 和 读取 任意数据。由于使用的 数据格式 是 JSON 或者 BSON,因为 JSON 数据是 自描述的,无需在使用前定义字段,读取一个 JSON 中 不存在的字段 也不会导致 SQL 那样的语法错误,可以解决关系型数据库 表结构 schema 扩展不方便 的问题。5.2. 常见文档数据库
5.2.1. MongoDB
MongoDB 是一个基于 分布式文件存储 的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的 高性能 数据存储解决方案。
MongoDB 是一个介于 关系数据库 和 非关系数据库 之间的产品,是非关系数据库当中功能 最丰富,最像关系数据库的 NoSQL。
5.2.2. CouchDB
CouchDB 是用 Erlang 开发的 面向文档 的 分布式 数据库,用于存储 半结构化 的数据,比较类似 lucene 的 index 结构。
CouchDB 支持 RESTful API,它使用 JSON 作为 存储格式,JavaScript 作为 查询语言,MapReduce 和 HTTP 作为 API 的 NoSQL 数据库。其中一个显著的功能就是 多主复制 功能。除此之外,CouchDB 构建在强大的 B- 树储存引擎 之上。
[图片上传失败...(image-fe7dcf-1536933787428)]
5.3. 相关特性
文档型数据库 的相关特性,以 MongoDB 为例进行说明:
5.3.1. 优点
新增字段简单不需要像关系型数据库一样,先执行 DDL 语句 修改表结构,程序代码5.3.2. 缺点
相比 传统关系型数据库,文档数据库的缺点,主要是对 多条数据记录 的 事务支持较弱,具体体现如下:
Atomicity(原子性):仅支持 单行/文档级原子性,不支持 多行、多文档、多语句原子性。Isolation(隔离性):隔离级别仅支持 已提交读5.4. 应用场景
5.4.1. 适用场景
数据量 很大或者未来会变得很大。表结构不明确,且 字段 在 不断增加,例如内容管理系统,信息管理系统。5.4.2. 不适用场景
在不同的文档上需要添加 事务。Document-Oriented 数据库并不支持 文档间的事务。多个文档之间需要 复杂的查询,例如 join 操作。6. 全文搜索引擎
6.1. 基本概念
全文搜索引擎的出现,正是解决关系型数据库 全文搜索较弱 的问题。
6.2. 基本原理
全文搜索引擎 的技术原理称为
[图片上传失败...(image-695617-1536933787428)]
正排索引 得到索引如下:[图片上传失败...(image-35c3a2-1536933787428)]
可见,正排索引 适用于根据 文档名称 查询 文档内容。
简单的 倒排索引 如下:可见,倒排索引 适用于根据 关键词 来查询 文档内容。
6.3. 常见全文搜索引擎
6.3.1. ElasticSearch
ElasticSearch 是一个基于 Apache Lucene 的 搜索引擎。它提供了一个 分布式,多租户 对全文搜索引擎。ElasticSearch 是用 Java 开发的,对外提供 RESTful Web 接口。根据 DB-Engines 排名,ElasticSearch 是最受欢迎的 企业搜索引擎。
6.3.2. Solr
Solr 是 Apache Lucene 项目的 开源企业搜索平台
6.4. 相关特性
全文搜索引擎,以 ElasticSearch 为例说明:
6.4.1. 优点
查询效率高,适用于对 海量数据 进行 近实时 的处理。可扩展性基于 集群 环境可以方便 横向扩展,可以承载 PB 级的数据。支持 高可用,ElasticSearch 集群弹性灵活,可以发现新的或失败的节点,重组 和 重新平衡 数据,确保数据是 安全 和 可访问的。6.4.2. 缺点
事务的 ACID 支持不足,单一文档 的数据是支持 ACID 的。对于 多个文档 的6.5. 应用场景
6.5.1. 适用场景
分布式的 搜索引擎 和 数据分析引擎6.5.2. 不适用场景
数据需要 频繁更新。需要 复杂关联查询。7. 图形数据库
7.1. 基本概念
图形数据库 应用 图形理论 存储 实体 之间的 关系信息。最常见例子就是 社会网络中人与人之间的关系。关系型数据库
图形数据库 的独特设计弥补了这个缺陷,解决 关系型 数据库 存储 和 处理复杂关系型数据 功能较弱的问题。
7.2. 常见图形数据库
7.2.1. Neo4j
Neo4j 是一个 高性能的,NOSQL 图形数据库,它将 结构化数据 存储在 “图形网络上” 而不是 “表中”。它是一个 嵌入式的、
Neo4j 也可以被看作是一个 高性能的图引擎。程序员工作在一个 面向对象的、灵活的网络结构 下而不是 严格、静态 的 表中。
7.2.2. ArangoDB
ArangoDB 是一个 原生多模型 数据库系统。数据库系统支持 三个 重要的 数据模型(键/值,文档,图形)。
ArangoDB 包含一个 数据库核心 和 统一查询语言 AQL(ArangoDB 查询语言)。查询语言是 声明性的,允许在 单个查询 中 组合 不同的 数据访问模式。ArangoDB 是一个 NoSQL 数据库系统,但 AQL 在很多方面与 SQL 都类似。
7.3. 基本原理
图形数据库,以 Neo4j 为例说明:
Neo4j 使用 数据结构 中图(graph)的概念来进行 建模。Neo4j 中两个最基本的概念是 节点 和 边。节点 表示 实体,边 则表示 实体之间的关系。节点 和 边 都可以有自己的 属性。不同 实体 通过各种不同的 关系 关联起来,形成复杂的 对象图。针对关系数据,两种数据库的 存储结构 分别如下:
在 Neo4j 中,存储节点 时使用了 index-free adjacency,即 每个节点 都有指向其 邻居节点 的 指针。这样就可以在 O(1) 的 复杂度 内找到 邻居节点。另外,按照官方的说法,在 Neo4j 中 边
7.4. 相关特性
7.4.1. 优点
高性能表现图的遍历 是 图数据结构 所具有的独特算法,即从 一个节点 开始,根据其连接的 关系,可以快速和方便地找出它的 邻近节点。这种查找数据的方法不受 数据量大小 的影响,因为 邻近查询 始终查找的是 有限的局部数据,不会对 整个数据库 进行搜索。
设计的灵活性数据结构 的自然伸展特性,以及其 非结构化 的 数据格式,让图数据库设计可以具有很大的 伸缩性 和 灵活性。因为随着需求的变化而增加的
数据模型 直接明了,从需求的讨论开始,到程序开发和实现,基本上不会有大的变化。
完全支持ACID不像别的 NoSQL 数据库,Neo4j 还完全具有 事务管理特性,完全支持 ACID 事务管理。
7.4.2. 缺点
节点,关系 和它们的 属性 的数量被 限制。不支持 拆分。7.5. 应用场景
7.5.1. 适用场景
在一些7.5.2. 不适用场景
记录大量 基于事件 的数据,如日志记录、传感器数据。对大规模 分布式数据 进行处理,类似于 Hadoop。不适用于应该保存在 关系型数据库 中的 结构化数据。二进制数据存储。小结
关于 关系型数据库 和 NoSQL 数据库 的选型,往往需要考虑几个指标:
数据量并发量实时性一致性要求读写分布数据类型安全性运维成本常见的系统数据库选型参考如下:
系统类型 数据库选型 企业内部管理系统 例如运营系统,数据量少,并发量小,首选考虑