深入浅出存储引擎
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1.2 关系数据库、NoSQL数据库与NewSQL数据库

关系数据库、NoSQL数据库、NewSQL数据库这三者是现如今讨论很多的一组概念,其实要搞明白它们之间的区别,就不得不回到数据库的发展历程上来审视它们产生的背景和动机。数据库的发展历程如图1-1所示。

图1-1 数据库的发展历程

1.关系数据库

关系数据库也称为SQL数据库(为描述方便,后面简称为SQL数据库)。最早的数据库可以追溯至20世纪70年代IBM研发的第一个SQL数据库System R,这也是最早的SQL数据库。再后来,20世纪80年代至90年代涌现出大量的SQL数据库产品,例如Oracle、DB2、SQL Server、PostgreSQL、MySQL等。

SQL数据库按照以“行”为单位的二维表格存储数据,这种方式最符合现实世界中的实体,同时通过事务的支持为数据的一致性提供了非常好的保证。这既是SQL数据库的优势,也是它的缺陷。在面对海量数据存储、高并发访问的场景下,SQL数据库的扩展性和性能会受到限制。随着互联网的飞速发展,到2000年左右,存储海量数据、高并发处理读/写的需求变得非常强烈,这对SQL数据库提出了巨大的挑战。为了解决这个问题,出现了支持数据可扩展性、最终一致性的NoSQL数据库。因此,NoSQL数据库可以看作基于SQL数据库的缺陷而诞生的一种新产品。

2.NoSQL数据库

NoSQL组件普遍选择牺牲复杂SQL的支持及ACID事务功能,以换取弹性扩展能力和更高的读/写性能。这类系统主要存储半结构化或非结构化数据。根据存储的数据种类,NoSQL数据库主要分为文档数据库(Document-based Database)、键值数据库(Key Value Database)、图数据库(Graph-based Database)、时序数据库(Time Series Database)、列式存储(Column-based Store)及多模数据库(Multi-model Database)。

(1)文档数据库

文档数据库以文档作为基本的单元进行操作。这里的文档并不是传统意义上的“文档”,它所指的是一条数据记录,类似关系数据库中的一行数据。这个记录是可以进行自我描述的,主要的形式有JSON、XML、HTML等,文档数据库中存储的每个文档可以具有完全不同的结构。从广义上来看,文档数据库也是一种KV数据库,只不过它和键值数据库的区别在于它的值是文档。此外,文档数据库还可以通过文档内容构建复杂索引。这类数据库除了MongoDB外,还有CouchDB、OrientDB等。这类数据库通常很容易和关系数据库进行数据转换。文档数据库非常适用于爬虫、物流、游戏、物联网等场景,存储一些数据模型无法确定的数据。

(2)键值数据库

键值数据库也就是一般意义上的KV数据库,它提供的功能和数据结构中的哈希(Hash)表类似。通常添加或更新数据时调用Put(k,v)接口,而在检索和删除时都只需要传入k即可。一般用Get(k)接口来获取数据,用Delete(k)接口来删除数据。这类数据库最为常用的是Redis,此外还有Riak、Amazon DynamoDB等。这类数据库的主要特点是读/写性能超高,系统内部可以支持弹性扩展,主要适用于对性能要求比较高的单点读/写场景,例如推荐系统,用于存储用户或物品特征、用户对内容的互动信息(点赞数、收藏数)等。

(3)图数据库

图数据库是一种使用图数据结构进行语义查询的数据库。图是一组点和边的集合,“点”表示实体,“边”表示实体间的关系,图数据库通过点和边来存储数据。鉴于它采用独特的图数据结构组织数据,类似于现实世界中的人际关系、交通网络,因此这类数据库比较适用于社交网络、数据挖掘等场景。这类数据库的主要代表有Neo4j、Dgraph、TigerGraph等。

(4)时序数据库

时序数据库又称为时间序列数据库,它是用来存储和管理时间序列数据的专业数据库,具备写多读少、海量数据持续高并发写入、数据冷热分离等特点。此外,这类数据库可以基于时间区间进行数据聚合分析和灵活检索。它被广泛应用在物联网、金融、工业制造、软硬件兼容系统等高频度、高密度、动态实时采集场景下。时序数据库的热门产品有InfluxDB、KDB+、Amazon Timestream和TimescaleDB等。

(5)列式存储

列式存储一般也指宽列式数据库,这类数据库一般采用列族数据模型存储数据。和关系数据库类似,列式存储也由多行数据构成,每行数据包含多个列族,每个列族又会对应多列。不同的行可以具有不同数量的列族。同一列族的数据存储在一起。简单来看这类数据库和关系数据库差不多,但实际上在数据存储上存在很大的差别。

传统的关系数据库中数据是按照行来组织的,多个列构成的一行数据在存储时会按照特定的行格式进行扁平化组织,然后写入文件中。当检索一行中的某列数据时需要读取整行数据,再返回该列的数据。这对每次总是使用整行中的多列信息的场景来说非常高效。而在一些统计分析场景中,往往需要对海量数据中的某列或者某几列数据进行频繁的读取和聚合。在这样的模式下,关系数据库的处理方式就变得不太高效了,而列式存储的优势可以得到充分发挥。列式存储中的数据按照列组织后,同一类型的稀疏数据有时候可以采用一些手段(例如位图编码)进行压缩以节约空间。列式存储主要适用于OLAP场景,典型的产品有HBase、ClickHouse、Cassandra、BigTable等。

(6)多模数据库

多模数据库是下一代新型数据库,它与传统的支持单一数据模型的数据库不同。这类数据库是在一套系统内支持多种不同数据模型的数据库。这些数据模型可包括传统的关系模型、NoSQL数据模型(文档模型、键值模型、图模型等)。多模数据库的主要特性之一是通常支持一种或者多种查询语言,可以以灵活的方式访问多种不同的数据模型,甚至跨越模型进行join等操作。这类数据库使得对数据的存储、组织、查询变得比以往的数据库更加灵活和便捷。目前有些关系数据库和NoSQL数据库正在通过扩展对其他数据模型的支持来转变为多模数据库。多模数据库的典型代表有MongoDB(支持文档、图等模型)、Oracle(支持关系表、XML、文档等模型)、OrientDB(支持文档、图、键值等模型)、ArangoDB(支持文档、图、键值等模型)等。

目前,不同的多模数据库通过不同的底层架构来实现多模型数据的管理。多模数据库的总体实现有两种方式:一种方式是在原生存储引擎存储主数据模型,然后扩展实现其他数据模型,例如某些产品用文档来实现主存储,然后使用文档之间的关系实现图模型;另一种方式是在所有数据模型上层增加一个中间层来集成所有操作,这样每种数据模型都需要有对应的处理模块。

结合上述对各种NoSQL数据库的介绍,将它们对应存储的数据结构进行汇总,如图1-2所示。

虽然NoSQL数据库克服了关系数据库存储的缺陷,但它无法完全代替关系数据库。在NoSQL数据库出现后的一段时间内,互联网软件的构建基本上都是结合二者来提供服务的,在不同的场景下选择不同的数据库进行数据存储。虽然这样的合作方式很好,但是在这样的模式下,一个用户可能会因为场景的不同而存储多份相同的数据到不同的数据库中,在用户量级和存储数据量很小的情况下没什么问题,一旦量级发生变化就会引发新的问题。

3.NewSQL数据库

随着存储数据量的不断增加,资源的浪费和成本的上升不容忽视,工业界和学术界都在寻找更好的解决方案。直到2010年左右,诞生了NewSQL数据库(也称为分布式数据库)。它的出发点是结合关系数据库的事务一致性,又具备NoSQL数据库的扩展性及访问性能。这无疑给系统的设计及实现带来了更大的挑战,NewSQL数据库不仅要考虑单机环境下高效存储的问题,还需要考虑多机情况下数据复制、一致性、容灾、分布式事务等问题。目前,NewSQL数据库的典型代表有TiDB、OceanBase、CockroachDB等。

图1-2 NoSQL数据存储类型

从数据库的发展历程可以看到,每种类型数据库的产生都是为了解决特定场景下的问题,这也是计算机软件发展的一个永恒不变的规律。SQL数据库、NoSQL数据库、NewSQL数据库不同维度的对比见表1-2。

表1-2 SQL数据库、NoSQL数据库、NewSQL数据库对比

如果以组件的类型是关系数据库还是非关系数据库,并结合服务的场景是OLTP还是OLAP来对业界的各种存储组件进行划分的话,可以得到图1-3所示的结果。关系数据库中既有为OLTP设计的,也有为OLAP设计的,同时还有新兴发展起来兼容二者的HTAP数据库。这些系统都有各自适用的业务场景,在实际方案选型时需要结合具体场景灵活选择合适的数据库。

图1-3 存储组件的分类