面试官:说说你对NoSQL的了解,为什么要有NoSQL

一般而言架构都是随着需求而改动的,以需求为导向。现在关系型数据库还是主流,也是我们系统中必不可少的一部分。

但是应对有些需求的时候,关系型数据库往往就撑不住了,需要非关系型数据库来补充它。关系型数据库会有哪些问题呢?

关系型数据库

行存储结构

关系型数据库是行存储结构,所以当你只想拿一行里面的几列时,从硬盘读取到内存中的数据也会是整行的数据,当数据量很大的时候,IO就吃不消了。当然是可以通过垂直分表来解决这种情况,但是垂直分表也会带来复杂性,具体不展开可以看我写的这篇文章mysql分库分表

还有例如头条的关注列表,如果放在关系型数据库中,那肯定就是你的id,你关注的人的id,这样一行数据保存着,然后关注的人有10个就会有10条这样的记录,然后你查看你关注的列表的时候,就需要从数据库里面查10行记录,然后组装起来返回给前端展示。

强结构

强结构的意思就是关系型数据库的表结构有很强的约束,必须按照这么个格式存储,就不够灵活。所以当有新需求需要加字段的时候就需要修改表的结构,如果表的数据很多的话修改表的结构可能会长时间锁表,而导致表的不可用。

没内存型数据库快

例如redis,人家在内存里,咱们关系型数据库比不上它的速度。

全文检索能力弱

如果提供全文检索,一般关系型数据库只能like全表扫描,性能很差,虽然像mysql也有全文索引。但是我觉得术业有专攻。因为数据库的这些厂商想扩张一下他们软件的广度,他们当然想自己软件支持所有的需求,然后让大家都来用它。如果效果真的这么好的话,像elasticsearch还活的下去嘛。例如mongodb4要支持acid事务等等这类。

一个软件基础的设计就决定了它在一方面是优的,一方面是欠缺的。**一般而言想实现本来就不属于它的领域的东西,要么会牺牲性能,要么会牺牲灵活性。**所以我如下讲的是针对每个类型NoSQL的优势点,也就是它们的最强点。

NoSQL (not only sql)

NoSQL其实就是关系型数据库的补充,就目前而言我们是不可能离开关系型数据库的,所以NoSQL就来弥补关系型数据库在某些情况下的不足。这里把常见的NoSQL分为4类:K-V类、文档型、列式存储型、全文搜索型

1、K-V类

全称Key-Value,这应该是我们都熟悉就像Map一样。代表数据库就是redis,redis的value还分了很多结构,例如:list、set、sorted set、hash、string等。

它是存储在内存中的,所以速度快常用来作为缓存服务器。 而且因为它的结构导致有些操作比关系型数据库简单

举个例子例如List的[LPUSHX key value]操作,将一个值插入到已存在的列表头部,列表是有序的,如果在关系型数据库中得怎么办,插入一条数据,并且将控制位置的那个字段例如叫index,设为1。那是不是还得修改本来的那些数据,把后面所有行的index值都加一,这样才能控制有序,之后删除哪条数据,还得维护修改index。操作是比较麻烦的。

但是它ACID事务只支持I和C也就是隔离性和一致性,不支持原子性和持久性。所以在一些对事务要求的情况下就不适合了。

2、文档型

这个类型它的结构没有约束,可以存储任意结构,因为是文档嘛。啥意思呢,就是例如关系型数据库中规定这个表字段就两个,一个id,一个name。如果你想存个sex字段你就得修改表结构。那文档型不用,因为文档型存储的数据格式一般都是Json,Json里面的字段我任意填,无拘无束。

{
 "id":"1",
 "name":"aa"
}
复制代码

我塞下一条我这样写

{
 "id":"2",
 "name":"bb",
 "sex":"man"
}
复制代码

而且这种类型的数据库容易存复杂的结构,因为Json是一种强大的描述语言,可以清楚的描述复杂的数据结构。如果复杂的数据结构放到关系型数据中那可能就得分很多表。例如我用户基本信息一个表、用户爱好的电影一个表,用户爱好的音乐一个表、用户爱好的游戏一个表,巴拉巴拉的,这些Json就能一次性搞定不需要分这么多表。

代表的数据库有MongoDB。3.2之前的版本不支持join操作,之后出了个lookup来实现join操作。4.0版本之前是不支持事务的,之后虽说支持事务,但是业界还是很少用它来保证事务的

3、列式存储型

也就是按列来存储数据,关系型是按行存储。 按行存储的好处是业务可以简单的获取一行也就是多个列的数据,因为按行存储数据都是连续的,所以磁盘一次操作就读取所有列的数据。

但是按列的话,因为列的存储是不连续的,所以磁盘读取效率比行低

按行存储写如果操作也是一行一起的,保证的所有列的数据要么都成功写入,要么的失败 。 如果是按列的话就有可能有些列成功,有些列失败

但是在大数据统计的时候,一般就统计某一列或者某几列的数据。如果这时候是按行存储的话,那么每次从磁盘读取到内存时都会读取整行数据导致IO过大和资源的浪费。

所以节省I/O就采用按列存储,这样每次只需要拿想要的列进行统计。

代表的数据库是HBase,多用于离线的大数据分析和统计。为啥离线?上面说了写的操作可能会有问题,并且整行读的效率低,所以一般都是线上数据拷过来弄成列数据库,专门用户数据分析。

4、全文检索型

这种型的数据库主要是用在传统关系型数据库在全文检索无力的情况下。因为搜索的条件很多,例如找对象在网站搜,女+170+杭州+爱吃辣+爱健身+爱旅游+28岁。来想想关系型数据库得怎么建这个索引。。。就是搜索条件的排列组合太多了。所以关系型数据库吃不消。这时候记得引入全文检索型数据库。

全文检索引擎采用倒排索引,也就是每个单词都是索引,建立单词到文档的索引,这样满足你搜索条件的当此的结果都会快速的显示出来。

代表的有Elasticsearch,分布式文档存储方式。使用方式就是我们从关系数据库中导出数据,转换成Json格式然后将其输入Elasticsearch中建立索引然后使用。

具体Elasticsearch的东西这里不做深入分析,不然就跑题了。有需自己查找相关资料。还有虽然Elasticsearch也是面向文档的,但是人家的重点在于全文检索,所以就这样分类。

总结

关系型数据库和非关系型数据库相辅相成,所以我们要根据各自的优缺点和需求进行相应的架构。 没有最好只有最合适。


如果错误欢迎指正! 个人公众号:yes的练级攻略

猜你喜欢

转载自juejin.im/post/5cbc13b06fb9a0685a3f014a