跳过正文
  1. 面试题库/

09|数据库选型

·3650 字·8 分钟
目录
MySQL面试题库 - 这篇文章属于一个选集。
§ 9: 本文

1. SQL 和 NoSQL 数据库有什么区别?
#

分析

区别维度SQL 数据库NoSQL 数据库
数据模型关系型,有固定行和列的表格文档型、键值对型、JSON 文档型、列不固定的列式存储、图类型
发展历史开发于 20 世纪 70 年代产生于 2000 年左右
典型代表Oracle、MySQL、Microsoft SQL Server、PostgreSQL文档型:MongoDB、CouchDB;键值对:Redis、DynamoDB;列式:Cassandra、HBase;图数据库:Neo4j
Schemas(模式)数据表格灵活结构
扩展性垂直扩展,需要升级机器硬件配置水平扩展
事务支持ACID不支持 ACID
应用访问模式数据中间层、ORM直接映射为应用语言数据结构

SQL
#

SQL(Structured Query Language)是关系型数据库中的语言标准。对于 SQL 和关系型数据库来说,最重要的是结构化(Structured)和关系(Relationship)。

关系型数据库要求存储的数据都要符合格式标准(Table Schema),所有数据都必须按照已定义好的标准来存放。这是它严谨的一面,也直接体现了结构化特征。另一方面,它又鼓励各个数据之间可以随意建立连接,互相认识朋友,建立起庞大的关系网络,这是关系属性的体现。

假设我们想要在关系型数据库中存储一个员工的基本信息。

alt text

在员工信息的存储中,我们构建了两个表,分别用来存储员工信息和部门信息。

可以发现,两张表中都包含了主键和数据类型,这意味着员工信息和部门信息必须指定存储内容。一旦指定了数据类型,这就意味着你想要存储的数据必须符合所规定的类型。

如果你想新加入一个员工的信息,但是这个员工的性别却是一个数字,比如 3,这种操作是绝对不允许的,因为 SQL 已经规定了性别必须是 varchar 类型。

在关系型数据库中,我们还可以用外键把两个表联系起来,用来表示两个数据之间的联系,这也是关系型数据库中独有的特点。关系型数据库中的表关系包括一对一、一对多、多对一、多对多,这些关系构建了不同数据之间的复杂关系网络。

NoSQL
#

NoSQL(Not Only Structured Query Language)代表非关系型数据库的机制。对于 NoSQL 来说,它像是一个自由的艺术家,自由体现在它对数据存储格式没有约束,可以在 NoSQL 中存储各种各样的数据,比如文档、图等。

假设我们同样想在 NoSQL 中存储员工信息,并且选择文档数据库来进行存储,那么它会是另一种形式:

alt text

员工信息由两个集合组成,分别是个人集合和部门信息集合。集合(Collection)相当于 SQL 中的 Table 概念,但是我们可以发现,集合内存储的东西是类似 JSON 格式的文本,并且第一个员工李峰存储了性别信息,但是第二个员工却没有存储性别信息。

这就是 NoSQL 的自由性,它不会对数据的格式和存储内容做出严格约束。

这里使用了文档数据库来存储 JSON 信息,不同于 SQL,NoSQL 不仅可以存储文档,还可以存储各种各样的数据。大体上 NoSQL 可以分为四类:

  • 文档数据库,代表数据库是 MongoDB 和 CouchDB。
  • Key-Value 数据库,代表数据库是 Redis 和 DynamoDB。
  • Graph 图数据库,代表数据库是 Neo4j。
  • Column 列数据库,代表数据库是 Cassandra 和 HBase。

alt text

SQL 和 NoSQL 的对比
#

  • 查询对比:
    • SQL 支持 Table 之间建立多种关系和固定的 Table 结构,因此 SQL 可以支持各种复杂多样的嵌套查询。比如在之前的员工信息表中,由于外键的存在,我们可以快速查找到所有属于研发部门的员工。
    • NoSQL 由于数据格式不统一,并且没有统一的查询语言,因此很难实现复杂多样的嵌套查询。
  • 扩展性对比:
    • SQL 数据库在增加 capacity 时,一般会选择垂直扩展,也就是增加单台服务器的性能。不过,现在的 SQL 数据库也早已通过分 shard 来支持水平扩展,通过对 Table 进行分区并部署在不同的 server 上来增加 SQL 数据库的 capacity。但是,由于 SQL 中的 Table 之间包含复杂的关系,因此对 Table 进行分区时通常需要考虑很多因素,比如需要解决跨服务器 JOIN、分布式事务等问题。
    • NoSQL 数据库在增加 capacity 时,通常会选择水平扩展,也就是通过增加服务器数量来提升数据库的 capacity。由于 NoSQL 中的数据相当于都是独立的个体,数据之间的联系很少,因此在进行水平扩展时更加方便,不用考虑复杂的数据关联问题,比如 Redis 自带主从复制模式、哨兵模式、切片集群模式。
  • 事务对比:
    • SQL 数据库具有 ACID 的特性,强调事务和数据的安全可靠性。
    • NoSQL 则不考虑 ACID 特性,它更注重处理任务的性能和吞吐量,不会保证数据的可靠性。
  • 适用场景对比:
    • SQL 数据库更适用于 OLTP 类的基于事务的处理分析任务,这类任务往往需要对数据进行大量的 Update、Insert 和 Delete 等操作,并且经常需要对多个数据进行联合查询。SQL 数据库的 ACID 特性提供了对事务执行的强大支持,因此 SQL 最适合处理基于事务的在线分析任务。
    • NoSQL 数据库则没有 ACID 特性的保证,同时也没有固定的数据格式。这种近乎自由的数据存储给 NoSQL 带来了更高的性能。因此 NoSQL 更适合对访问性能有要求同时又不要数据可靠性的场景,比如搜索、缓存等。

回答

SQL 和 NoSQL 数据库区别主要有:

  • 数据存储的区别:SQL 数据库是关系型数据库,主要代表数据库是 MySQL,数据是严格按照二维表格的形式存储的,表与表之间可以建立连接来查询数据。NoSQL 是非关系型数据库,主要代表数据库是 Redis、MongoDB 等,数据是灵活存储的,对数据存储格式没有约束,可以存储 JSON 文档、图、键值对等各种数据。
  • 事务的区别:SQL 数据库具备 ACID 四大特性的事务,而 NoSQL 数据库不具备满足 ACID 特性的事务,因为 NoSQL 数据库都是通过牺牲 ACID 特性来获取更高性能的。
  • 扩展性的区别:SQL 数据库的数据之间存在关联性,一般会选择垂直扩展,也就是增加服务器性能,虽然也可以通过分库分表实现水平扩展,但是水平扩展后,会带来很多新问题,比如跨库跨表查询、分布式事务、全局唯一 ID 等。NoSQL 数据库的数据相当于独立个体,数据之间关系很少,因此进行水平扩展时更加方便,不用考虑复杂的数据关联问题。

我觉得 NoSQL 并不是为了取代 SQL,相反它们需要相互结合。SQL 数据库提供 ACID 事务,NoSQL 数据库提供更好的扩展性和性能,所以 NoSQL 一般作为传统关系型数据库的补充而存在,弥补关系型数据库在性能、扩展性和某些场景下的不足。

2. MySQL 和 MongoDB 之间怎么选型?
#

分析

MySQL 是关系型数据库。

优势:

  • 由二维表结构来逻辑表达,相对网状、层次等其他模型更加容易被理解。严格遵循数据格式与长度规范,数据以行为单位,一行数据表示一个实体信息,每一行数据的属性都是相同的。
  • 操作方便,通用的 SQL 语言使得操作关系型数据库非常方便,支持 JOIN 等复杂查询。SQL 加二维关系是关系型数据库最无可比拟的优点,这和易用性非常贴近开发者。
  • 支持 ACID 特性,可以维护数据之间的一致性,这是使用关系数据库非常重要的一个理由。例如银行转账,张三转给李四 100 块钱,张三扣 100 元,李四加 100 元,而且必须同时成功或者同时失败,否则就会造成用户的资损。

劣势:

  • 为维护数据一致性付出的代价大。数据一致性是关系型数据库的核心,但是同样为了维护数据一致性的代价也非常大。我们都知道 SQL 标准为事务定义了不同的隔离级别,从低到高依次是读未提交、读已提交、可重复读、串行化,事务隔离级别越低,可能出现的并发异常越多,但是通常而言能提供的并发能力越强。为了保证事务一致性,数据库就需要提供并发控制与故障恢复两种技术,前者用于减少并发异常,后者可以在系统异常时保证事务与数据库状态不会被破坏。对于并发控制,其核心思想是加锁,无论是乐观锁还是悲观锁,只要提供隔离级别越高,那么读写性能必然越差。
  • 表结构扩展不方便。由于数据库存储的是结构化数据,因此表结构 Schema 是固定的,扩展不方便。如果需要修改表结构,需要执行 DDL(Data Definition Language)语句修改,修改期间会导致锁表,部分服务不可用。
  • 水平扩展后带来的种种问题难处理。随着业务规模扩大,一种方式是对数据库做分库,做了分库之后,数据迁移、跨库 JOIN、分布式事务等问题都需要考虑,尤其是分布式事务处理,业界当前都没有特别好的解决方案。

MongoDB 是文档型 NoSQL 数据库,以 JSON 或 XML 格式存储数据,因此文档型 NoSQL 没有 Schema。由于没有 Schema 的特性,可以随意地存储与读取数据,因此文档型 NoSQL 的出现是为了解决关系型数据库表结构扩展不方便的问题。

优点:

  • 没有预定义的字段,扩展字段容易。
  • 相较于关系型数据库,读写性能优越,命中二级索引的查询不会比关系型数据库慢,对于非索引字段的查询则是全表扫描。

缺点:

  • 不适合依赖复杂事务的场景。
  • 多表之间的关联查询不支持。虽然有嵌入文档的方式,但 JOIN 查询通常还是需要多次操作。

回答

MySQL 是关系型数据库,支持 ACID 特性的事务,而 MongoDB 是 NoSQL 类型的数据库。如果业务需要通过事务保证数据一致性,就需要选择 MySQL。

如果业务上没有强一致性的要求,可以根据下面这两种场景来考虑:

  • MongoDB 是灵活的文档模型。也就是说,如果预计数据可以被一个稳定的模型来描述,那么我会倾向于使用 MySQL 等关系型数据库;一旦认为数据模型会经常变动,比如很难预料用户会输入什么数据,这种情况下就更加倾向于使用 MongoDB。
  • MongoDB 属于 NoSQL,更容易进行横向扩展。虽然关系型数据库也可以通过分库分表达到横向扩展的目标,但是比 MongoDB 更困难,后期运维也更复杂,而这一切在 MongoDB 里面都是自动的,运维成本更低。
MySQL面试题库 - 这篇文章属于一个选集。
§ 9: 本文