NoSQL还是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 横向扩展来满足功能。
- 存储结构化和半结构化的数据。