有了 MySQL 为何要用 NoSQL?

回复 PDF 领取资料html

这是悟空的第 87 篇原创文章
mysql

本文来自个人一次真实面试经历。web

这家公司的真名就叫作“三藏”,和个人名字“悟空”很契合,唐三藏给悟空面试,合情合理,还带有一丝趣味,因此我就去面试了。三藏公司是一家小厂,技术负责人面的我,欲知面试结果,文末揭晓面试

本文主要内容以下:sql

1、MongoDB 和 MySQL

1.面试官:看你的简历上写了 MongoDB,说下 MongoDB 和 MySQL 的区别吧。mongodb

其实对于这个问题,我事先有准备,简历上写了 MongoDB,面试官确定会问 MongoDB 和 MySQL 的区别。数据库

MongoDB 是非关系型的数据库(NoSQL),属于文档型数据库,文档数据库就是为了解决关系数据库带来的问题。最大的特色是 no-schema,能够存储和读取任意的数据。小程序

存储的数据格式就是 JSON(或者 BSON)。JSON 格式咱们都比较熟悉,好比 Rest API 请求返回的 Response 就是 JSON 格式的。JSON 格式的数据和 XML 格式的区别是 JSON 更简单,没有那么多的标签来定义字段名。也就是说 JSON 是自描述的。另外 JSON 格式存进 MongoDB 中后,即便读取一个 JSON 中不存在的字段也不会致使 SQL 那样的语法错误数组

MongoDB 优势

因为文档数据库具备 no-schema 特性,用起来有如下几个明显的好处缓存

(1)新增的字段不会出错。

好比用户表增长一个昵称的字段,不须要像关系型数据那样执行更新表结构的语句。咱们直接查询这条文档出来就能够看到新增的字段了。

(2)查询历史数据不会出错。

上面提到新增了一个昵称字段,可是历史数据中是没有这个字段,若是查询历史数据,则返回的数据中不会有这个字段,虽然查询不会报错,可是取值时,会返回 null。若是业务代码中用到了昵称字段,则须要作兼容性处理。

(3)轻松存储复杂数据。

由于是用 JSON 存储,而 JSON 又能够表示复杂的数据结构,好比字段能够存数组,字段能够嵌套字段,并且能够存不少字段。换作 MySQL,则须要设计几张表来存。MongoDB 存数据的结构,特别适合电商这种业务场景,好比两种不一样的商品,属性差异就很大,可是用 JSON 存就能够轻松应对。

可是文档数据库有什么缺点呢 ?

MongoDB 缺点

(1)目前 4.0 之前不支持多文档事务。

结合 MongoDB 文档模型内嵌数组、文档的支持,目前的单文档事务能知足绝大部分开发者的需求。为了让 MongoDB 能适应更多的应用场景,让开发变得更简单,MongoDB 4.0 将支持复制集内部跨一或多个集合的多文档事务,保证针对多个文档的更新的原子性。而在将来的 MongoDB 4.2 版本,还会支持分片集群的分布式事务。

咱们来看下 MongoDB 不一样版本支持的功能:

MongoDB 的不一样版本

MongoDB 的事务接口很是简单,开发者只须要将须要保证原子性的更新序列放到一个 session 的 开始事务提交事务之间便可。下面是 Java 使用 MongoDB 事务的示例代码:

(2) 不支持关联查询。

咱们都知道 MySQL 是支持关联查询的,也就是能够执行 Join 操做。好比有两张表:用户表和订单表,订单表中有用户的 id,且性别只存在用户表中。若是想购买了手机的男性用户,用关联查询,一步就能搞定。可是若是用 MongoDB,则须要查两次,先查询订单表中购买手机的用户,再查询这些用户中哪些是男性。

2、关系型数据的缺点

2.面试官:这个项目为何不用关系型数据库?关系型数据库有哪些缺点?

顺着面试官的思路,能够知道面试官想问的是关系型数据库有哪些不足之处。

关系型数据库的不足之处

(1)存储的是行记录

不能存储数组、嵌套字段等格式的数据。

(2)扩展表结构不方便

操做不存在的列会报错,而增长列又须要执行 SQL 语句才行。并且修改时须要特别注意,由于更新表时会长时间锁表,这对线上环境可能形成严重影响。

(3)占用内存高

关系型数据库在对大量数据的表进行统计之类的运算时,占用内存会很高,由于它即便只针对某一列进行运算,也会将整行数据从存储设备读入内存。

(4)全文搜索性能差

相似于 MySQL 的关系型数据库,只能用 like 进行整表扫描的匹配,效率很低。现现在,有不少场景须要支持模糊匹配,并且必须支持高效查找。好比查询包含关键字的日志信息,又或者是根据某个商品关键字查询商品列表。

针对以上的不足之处,咱们这个项目用了两种非关系型的数据存储方案:MongoDB 和 ElasticSearch。

3、NoSQL 的分类和特色

3.面试官:你知道的有哪些 NoSQL 数据库?分别有什么特色?

NoSQL(NoSQL = Not Only SQL ),意即"不只仅是SQL"。

我知道的有 Redis、MongoDB、HBase、全文搜索引擎 Elasticsearch。他们是不一样的非关系型存储方案。

K-V 存储型

好比 Redis,它能够用 K-V 键值对的方式来存储数据,而存储的值能够有好几种格式,如 string、hash、list、set、bitmap 等。

文档存储型

好比 MongoDB,存储的 JSON 格式的文档,解决了关系型数据库的表约束的问题,好比查询不存在的字段会报错。另外也解决了部分存储格式的问题,因JSON 能够表示数组,还能够嵌套字段存储。

列式存储型

好比 HBase,按照列来存储数据,解决了大数据场景下的 I/O 问题。

关系型数据库按照来存储数据,因此称做行式数据库。按照来存储有如下优点:

  • 读一行数据就能读取到多个列,只须要一次磁盘操做就能把多个列的数据读取到内存中。
  • 写一行数据能够对多个列进行写操做,保证了行数据的原子性和一致性。而对列式存储的多列写操做,可能会致使有些列成功,有些失败,产生数据的不一致。

全文搜索引擎

这个用到的最多的地方就是日志系统,还有搜索商品信息等相似场景。以下图所示的电商网站。

搜索手机

咱们项目中用到日志搜索就是利用 ELK。

Elasticsearch 就是 ELK 中的 E。Elasticsearch 就是全文搜索引擎,注意:他是一种 NoSQL 方案,并非 NoSQL 数据库。

Logstash 就是 ELK 中的 L。它是 Elastic Stack 的核心产品之一,可用来对数据进行聚合和处理,并将数据发送到 Elasticsearch。Logstash 是一个开源的服务器端数据处理管道,容许您在将数据索引到 Elasticsearch 以前同时从多个来源采集数据,并对数据进行充实和转换。

Kibana 就是 ELK 中的  K。是一款适用于 Elasticsearch 的数据可视化和管理工具,能够提供实时的直方图、线性图等。

以下图所示:

搜索日志

传统的关系型的数据库主要是经过索引来进行快速查询,但若是放在全文搜索的场景下,就行不通了。

咱们来看看为何关系型数据库很难作到高效的全文搜索:

  • 由于在全文搜索中,搜索的条件是能够随意排列组合的,好比字段 A、B、C,能够排列成 6 种,若是要用索引来支持快速查询的话,则须要建立多个索引,这是很是麻烦的,同时,多个索引对数据的插入效率也是有影响的。
  • 模糊匹配只能用 like 查询,而 like 查询是整表扫描,效率是很是低的。

以前我写过一篇 Elasticsearch 原理的:《别只会搜日志了,求你懂点原理吧》,经过倒排索引实现高效的全文检索。下面举个倒排索引的例子给你们看看:

假如数据库有以下电影记录

1-大话西游

2-大话西游外传

3-解析大话西游

4-西游降魔外传

5-梦幻西游独家解析

分词,将整句分拆为单词

序号 保存到 ES 的词 对应的电影记录序号
A 西游 1,2, 3,4, 5
B 大话 1,2, 3
C 外传 2,4, 5
D 解析 3,5
E 降魔 4
F 梦幻 5
G 独家 5

检索:独家大话西游

独家大话西游 拆分红 独家大话西游

ES 中 A、B、G 记录 都有这三个词的其中一种, 因此 1,2, 3,4, 5 号记录都有相关的词被命中。

1 号记录命中 2 次, A、B 中都有 ( 命中 2 次 ) ,并且 1 号记录有 2 个词,相关性得分:2 次/2 个词=1

2 号记录命中 2 个词 A、B 中的都有 ( 命中 2 次 ) ,并且 2 号记录有 2 个词,相关性得分:2 次/3 个词= 0.67

3 号记录命中 2 个词 A、B 中的都有 ( 命中 2 次 ) ,并且 3 号记录有 2 个词,相关性得分:2 次/3 个词= 0.67

4 号记录命中 2 个词 A 中有 ( 命中 1 次 ) ,并且 4 号记录有 3 个词,相关性得分:1 次/3 个词= 0.33

5 号记录命中 2 个词 A 中有 ( 命中 2 次 ) ,并且 4 号记录有 4 个词,相关性得分:2 次/4 个词= 0.5

因此检索出来的记录顺序以下

1-大话西游 ( 关性得分:1 )

2-大话西游外传 ( 相关性得分:0.67 )

3-解析大话西游 ( 相关性得分:0.67 )

5-梦幻西游独家解析 ( 相关性得分:0.5 )

4-西游降魔 ( 关性得分:0.33 )

Elasticsearch 与 mysql 的对比

序号 Mysql Elasticsearch
1 Mysql 服务 ES 集群服务
2 数据库 Database 索引 Index
3 表 Table 类型 Type
4 记录 Records ( 一行行记录 ) 文档 Document ( JSON 格式 )

另外的 NoSQL 还有图形数据库,这里不作展开。

关系型和 NoSQL 怎么选?

4.面试官:关系型和 NoSQL 怎么选呢?

关系型和NoSQL数据库的选型,考虑几个指标,数据量、并发量、实时性、一致性要求、读写分离、安全性、运维性等。根据这些指标,软件系统可分红几类。

  • 管理型系统,如运营类系统,首选关系型。
  • 大流量系统,且多字段、数据量增加快,首选 NoSQL。
  • 日志型系统,首选 Elasticsearch
  • 搜索型系统,指站内搜索,非通用搜索,如商品搜索,首选 Elasticsearch。
  • 事务型系统,如库存、交易、记帐,选关系型+缓存+一致性协议。
  • 离线计算,如大量数据分析,首选列式数据库。
  • 实时计算,如实时监控,能够选时序数据库,或列式数据库。

面试结果:技术负责人以为还行,但 HR 今天不在,等 HR 下次通知吧。后续就没通知了。完。

参考资料: 

https://mongoing.com/archives/5560 

https://time.geekbang.org/column/article/8377 

https://dzone.com/articles/history-databases-%E2%80%9Cno-tation%E2%80%9D 

https://www.runoob.com/mongodb/nosql.html

- END -

写了两本 PDF,欢迎下载学习。

周日写的文章《大佬,你的网站崩了》忘了嵌入视频,此次给你们看下。

文末阅读原文也能够进入到这个网站。

我是悟空,努力变强,变身超级赛亚人!

本文分享自微信公众号 - 悟空聊架构(PassJava666)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索