高性能 NoSQL

2019 年 3 月 20 日 性能与架构

关系数据库经过几十年的发展,已经非常成熟,但同时也存在不足:

  • 存储的是行记录,无法存储数据结构

例如微博的关注关系,“我关注的人”是一个用户ID列表,使用关系数据库只能将列表拆成多行,然后查询组装,无法直接存储一个列表。

  • schema 扩展不方便

表结构是强约束的,业务变更时扩充很麻烦。

  • 在大数据场景下 I/O 较高

如果对大数据量的表进行统计运算,I/O会很高,因为即使只针对某列进行运算,也需要将整行数据读入内存。

  • 搜索功能较弱

全文搜索只能使用 Like 进行整表扫描,性能非常低。

针对这些不足,产生了不同的 NoSQL 解决方案,在某些场景下比关系数据库更有优势,但同时也牺牲了某些特性,所以不能片面的迷信某种方案,应将其作为 SQL 的有利补充。

NoSQL != No SQL,而是:

NoSQL = Not Only SQL

典型的 NoSQL 方案分为4类:

  1. K-V 存储

解决存储数据结构的问题,以 Redis 为代表。

  1. 文档数据库

解决 schema 强约束的问题,以 MongoDB 为代表。

  1. 列式数据库

解决大数据下 I/O 问题,以 HBASE 为代表。

  1. 全文搜索引擎

解决全文搜索性能问题,以 ElasticSearch 为代表。

1. K-V 存储

Redis 是典型,其 value 是具体的数据结构,包括 string, hash, list, set, sorted set, bitmap, hyperloglog,常被称为数据结构服务器。

以 list 为例:

LPOP key 是移除并返回队列左边的第一个元素。

如果用关系数据库就比较麻烦了,需要操作:

  • 为每条数据添加 位置编号,否则没法判断哪条数据是第一条。不能用ID作为位置编号,因为会往列表头部插入数据。

  • 查询出第一条数据。

  • 删除第一条数据。

  • 更新从第二条开始的所有数据的位置编号。

Redis 的缺点主要体现在不支持完成的ACID事务,只能保证隔离性和一致性,无法保证原子性和持久性。

2. 文档数据库

最大的特点是 no-schema,无需在使用前定义字段,读取一个不存在的字段也不会导致语法错误。

特点:

  1. 新增字段简单。

  2. 兼容历史数据,即使没有新增字段,不会出错。

  3. 很容易存储复杂数据,使用 JSON 描述数据,比关系数据库方便得多。

以电商为例,不同商品的属性差异很大,如冰箱和电脑,这种差异性在关系数据库中会有很大的麻烦,而使用文档数据库则非常方便。

文档数据库的主要缺点:

  1. 不支持事务

  2. 无法实现 join 操作

3. 列式数据库

关系数据库是按行来存储的,列式数据库是按照列来存储数据。

按行存储的优势:

  • 同时读取多个列时效率高,一次磁盘操作就把一行数据中的各列都读取到内存了。

  • 能够一次完成对一行中多个列的写操作,保证了对行数据写操作的原子性和一致性;如果使用列式存储,可能出现多次写操作,因为这些列都不在一起存储。

在某些场景下,这些优势就成为劣势了,例如,计算超重人员的数据,只需要读取体重这一列进行统计即可,但行式存储会将整行数据读取到内存中,很浪费。

而列式存储中,只需要读取体重这列的数据即可,I/O 将大大减少。

除了节省I/O,列式存储还有更高的压缩比,可以节省存储空间。普通行式数据库的压缩比在 3:1 到 5:1 左右,列式数据库在 8:1 到 30:1,因为单个列的数据相似度更高。

列式存储的随机写效率远低于行式存储,因为行式存储时同一行多个列都存储在连续空间中,而列式存储将不同列存储在不连续的空间。

一般将列式存储应用在离线大数据分析统计场景,因为这时主要针对部分列进行操作,而且数据写入后无须更新。

4. 全文搜索引擎

关系数据库通过索引进行快速查询,但在全文搜索的情景下,索引就不够了,因为:

  • 全文搜索的条件可以随意排列组合,索引很难满足。

  • 全文搜索的模糊匹配方式,索引无法满足,只能用 like,效率极低。

假设有一个交友网站,信息表如下:

  • 美女1:我要找在上海做PHP的哥哥。

需要匹配性别、地点、语言列。

  • 美女2:我要找北京爱旅游的哥哥。

需要匹配性别、地点、爱好列。

实际搜索中,各种排列组合非常多,关系数据库很难支持。

全文搜索引擎是使用倒排索引技术,建立单词到文档的索引,例如上面的表信息建立倒排索引:

所以特别适合根据关键词来查询文档内容。

小结

上面介绍了几种典型的NoSQL方案,及各自的适用场景和特点,您可以根据实际需求进行选择。


内容整理自《从0开始学架构》

点击👇阅读原文,查看文章列表


登录查看更多
1

相关内容

NoSQL 全称是 Not Only SQL,是一种不同于关系型数据库的数据库管理系统设计方式。
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【SIGMOD2020-腾讯】Web规模本体可扩展构建
专知会员服务
29+阅读 · 2020年4月12日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
67+阅读 · 2020年3月9日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【大规模数据系统,552页ppt】Large-scale Data Systems
专知会员服务
60+阅读 · 2019年12月21日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
数据库之架构:主备+分库?主从+读写分离?
架构文摘
8+阅读 · 2019年4月23日
亿级订单数据的访问与储存,怎么实现与优化
ImportNew
11+阅读 · 2019年4月22日
亿级订单数据的访问与存储,怎么实现与优化?
码农翻身
16+阅读 · 2019年4月17日
使用 Canal 实现数据异构
性能与架构
20+阅读 · 2019年3月4日
优化哈希策略
ImportNew
5+阅读 · 2018年1月17日
领域应用 | 图数据库及其在恒昌的应用简介
开放知识图谱
6+阅读 · 2017年10月10日
Spark的误解-不仅Spark是内存计算,Hadoop也是内存计算
Bidirectional Attention for SQL Generation
Arxiv
4+阅读 · 2018年6月21日
Arxiv
6+阅读 · 2018年5月18日
Arxiv
5+阅读 · 2018年5月1日
VIP会员
相关资讯
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
数据库之架构:主备+分库?主从+读写分离?
架构文摘
8+阅读 · 2019年4月23日
亿级订单数据的访问与储存,怎么实现与优化
ImportNew
11+阅读 · 2019年4月22日
亿级订单数据的访问与存储,怎么实现与优化?
码农翻身
16+阅读 · 2019年4月17日
使用 Canal 实现数据异构
性能与架构
20+阅读 · 2019年3月4日
优化哈希策略
ImportNew
5+阅读 · 2018年1月17日
领域应用 | 图数据库及其在恒昌的应用简介
开放知识图谱
6+阅读 · 2017年10月10日
Spark的误解-不仅Spark是内存计算,Hadoop也是内存计算
Top
微信扫码咨询专知VIP会员