0%

NoSql数据库

为什么选择NoSql数据库

传统数据库缺点

  • 大数据场景下I/O较高 因为数据是按行存储,即使只针对其中某一列进行运算,关系型数据库也会将整行数据从存储设备中读入内存,导致I/O较高
  • 存储的是行记录,无法存储数据结构
  • 表结构schema扩展不方便 如要需要修改表结构,需要执行执行DDL(data definition language),语句修改,修改期间会导致锁表,部分服务不可用
  • 全文搜索功能较弱 关系型数据库下只能够进行子字符串的匹配查询,当表的数据逐渐变大的时候,like查询的匹配会非常慢,即使在有索引的情况下。况且关系型数据库也不应该对文本字段进行索引
  • 存储和处理复杂关系型数据功能较弱 许多应用程序需要了解和导航高度连接数据之间的关系,才能启用社交应用程序、推荐引擎、欺诈检测、知识图谱、生命科学和 IT/网络等用例。然而传统的关系数据库并不善于处理数据点之间的关系。它们的表格数据模型和严格的模式使它们很难添加新的或不同种类的关联信息。

NoSQL的常见类型

键值(K-V)数据库

其数据按照键值对的形式进行组织、索引和存储。

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

键值:键值数据库是高度可分区的,并且允许以其他类型的数据库无法实现的规模进行水平扩展。诸如游戏、广告技术和 IoT 等使用案例本身特别适合键值数据模型。

键值数据库是一种非关系数据库,它使用简单的键值方法来存储数据。键值数据库将数据存储为键值对集合,其中键作为唯一标识符。键和值都可以是从简单对象到复杂复合对象的任何内容。键值数据库是高度可分区的,并且允许以其他类型的数据库无法实现的规模进行水平扩展。

使用场景

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

  • 不适用场景

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

列式数据库

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

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

基本原理

相关特性

优点如下:

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

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

通过字典表压缩数据

  • 查询效率高

读取多条数据的同一列效率高,因为这些列都是存储在一起的,一次磁盘操作可以数据的指定列全部读取到内存中。 下图通过一条查询的执行过程说明列式存储(以及数据压缩)的优点

  • 适合做聚合操作
  • 适合大量的数据而不是小数据

缺点如下:

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

使用场景

以HBase为例说明:

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

文档数据库

文档数据库(也称为文档型数据库)是旨在将半结构化数据存储为文档的一种数据库。

文档数据库通常以 JSON 或 XML 格式存储数据。

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

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

文档数据库是一种非关系数据库,旨在将数据作为类 JSON 文档存储和查询。文档数据库让开发人员可以使用他们在其应用程序代码中使用的相同文档模型格式,更轻松地在数据库中存储和查询数据。文档和文档数据库的灵活、半结构化和层级性质允许它们随应用程序的需求而变化。文档模型可以很好地与目录、用户配置文件和内容管理系统等使用案例配合使用,其中每个文档都是唯一的,并会随时间而变化。文档数据库支持灵活的索引、强大的临时查询和文档集合分析。

常见文档数据库

  1. MongoDB

    优点如下:

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

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

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

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

使用场景

适用场景

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

不适用场景

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

图形数据库

图形数据库应用图形理论存储实体之间的关系信息

图形:图形数据库旨在轻松构建和运行与高度连接的数据集一起使用的应用程序。图形数据库的典型使用案例包括社交网络、推荐引擎、欺诈检测和知识图形。热门图形数据库包括 Neo4j 和 Giraph。图形数据库专门用于存储和导航关系。关系是图形数据库中的一等公民,图形数据库的大部分价值都源自于这些关系。图形数据库使用节点来存储数据实体,并使用边缘来存储实体之间的关系。边缘始终有一个开始节点、结束节点、类型和方向,并且边缘可以描述父子关系、操作、所有权等。一个节点可以拥有的关系的数量和类型没有限制。

图形数据库中的图形可依据具体的边缘类型进行遍历,或者也可对整个图形进行遍历。在图形数据库中,遍历联结或关系非常快,因为节点之间的关系不是在查询时计算的,而是留存在数据库中。在社交网络、推荐引擎和欺诈检测等使用案例中,需要在数据之间创建关系并快速查询这些关系,此时,图形数据库更具优势。

使用场景

适用场景如下:

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

不适用场景如下:

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

搜索数据库

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

  • 全文搜索的条件可以随意排列组合,如果通过索引来满足,则索引的数量非常多
  • 全文搜索的模糊匹配方式,索引无法满足,只能用like查询,而like查询是整表扫描,效率非常低

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

基本原理

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

关特性相

以Elasticsearch为例: 优点如下:

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

缺点如下:

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

使用场景

适用场景如下:

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

不适用场景如下:

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

参考文章

NoSQL 还是 SQL ?这一篇讲清楚 - 掘金 (juejin.cn)