Java 业务开发常见错误 100 例
朱晔
贝壳金服资深架构师
51940 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
代码篇 (23讲)
Java 业务开发常见错误 100 例
15
15
1.0x
00:00/00:00
登录|注册

26 | 数据存储:NoSQL与RDBMS如何取长补短、相辅相成?

你好,我是朱晔。今天,我来和你聊聊数据存储的常见错误。
近几年,各种非关系型数据库,也就是 NoSQL 发展迅猛,在项目中也非常常见。其中不乏一些使用上的极端情况,比如直接把关系型数据库(RDBMS)全部替换为 NoSQL,或是在不合适的场景下错误地使用 NoSQL。
其实,每种 NoSQL 的特点不同,都有其要着重解决的某一方面的问题。因此,我们在使用 NoSQL 的时候,要尽量让它去处理擅长的场景,否则不但发挥不出它的功能和优势,还可能会导致性能问题。
NoSQL 一般可以分为缓存数据库、时间序列数据库、全文搜索数据库、文档数据库、图数据库等。今天,我会以缓存数据库 Redis、时间序列数据库 InfluxDB、全文搜索数据库 ElasticSearch 为例,通过一些测试案例,和你聊聊这些常见 NoSQL 的特点,以及它们擅长和不擅长的地方。最后,我也还会和你说说 NoSQL 如何与 RDBMS 相辅相成,来构成一套可以应对高并发的复合数据库体系。

取长补短之 Redis vs MySQL

Redis 是一款设计简洁的缓存数据库,数据都保存在内存中,所以读写单一 Key 的性能非常高。
我们来做一个简单测试,分别填充 10 万条数据到 Redis 和 MySQL 中。MySQL 中的 name 字段做了索引,相当于 Redis 的 Key,data 字段为 100 字节的数据,相当于 Redis 的 Value:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 业务开发常见错误 100 例》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(19)

  • 最新
  • 精选
  • 👽
    其实,具体使用何种数据库,如果了解其原理,那就很容易弄懂了。 我就说说ES, ES,因为其本身全文索引,和复杂查询的高性能,最主要还是依赖于其分词之后简历的映射表。基本可以理解为类似数据库索引一样的存在。索引的弊端,也就是ES的弊端。 索引,基本目的是空间换时间,用一些冗余的节点数据来优化查询性能。但是带来的问题,一方面是空间的占用,以及维护索引所需要的成本。因为需要维护索引,所以删改数据时性能较差。 ES的索引又更加过分,几乎是针对单个文章的全部内容,建立了分词映射,修改一篇文章内容,可能会大幅度修改映射内容。所以不适合频繁修改的数据。

    作者回复: 说的不错

    30
  • hellojd
    老师没说mongo数据库,我的理解是如果不是acid要求特别高的地方,都可以将mysql替换为mongo.不知道理解对不对。

    作者回复: 非重要数据,并且数据结构不固定的,插入量又很大的原始数据(比如爬虫原始数据)可以考虑Mongo。从个人喜好而言,综合性NOSQL,我更喜欢ES而不是Mongo,Mongo在数据量到TB级别我感觉不稳定,Sharding也不那么好用,一家之言。

    22
  • 似曾相识
    老师 Infludb,和es 这些数据库做辅助数据库,需要保存全量数据吗?还是根据业务保存部分字段?

    作者回复: es一般是保存全量数据,甚至是超全量数据,意思就是比mysql保存的数据还要全。influxdb作为时间序列数据库只能保存加工后的业务或系统指标数据,无法保存实际的业务数据。

    8
  • kyl
    说一下我对mongodb的理解,望老师指正。mongodb因为是文档型数据库以json格式存储,所以可以很方便的存储各种类型的数据,同时mongodb横向扩展只需增加分片比MySQL更加方便,数据量很大的场景下感觉性能优于MySQL。但是mongodb对事务支持比较差,虽然4.0引入了事务,但是可能有坑,另外mongodb不支持表的关联查询,所以还是要根据实际业务场景进行选择。

    作者回复: 基本没错的 mongodb建议用于非重要业务初始数据保存

    2
    6
  • MongoDB 4.2.x提供了相当于关系数据库RR的事务隔离级别;好像也能用于交易数据强acid的需求。感觉用数组字段处理简单的一对多关系很方便。

    作者回复: Mongodb 不建议用于重要业务,只适合边缘数据,比如业务日志、爬虫原始数据等

    5
  • 终结者999号
    老师,我想问一下对于一个高并发的系统,索引库您们保存多长时间呢?没有夜维清理吗?

    作者回复: 至少三个月 取决于业务上让用户查多久的订单 更长期的打到es

    5
  • 汝林外史
    又是干货满满,很多新接触的东西,感谢老师。 对于Mysql擅长的地方的第二点不是很理解: 1.不是不建议设置外键吗? 2.专门弄个索引表放主键与外键的关联关系,那岂不是每张表都要配这么一个索引表,这不浪费内存吗? 3.主键跟关联表是一对多的关系,那这个索引表相对数据表的数据量岂不是几倍的关系,性能能好了吗? 还请老师指教。

    作者回复: 1. 我是指逻辑含义上这个字段是外键的作用,不是指要外键关系的绑定 2. 这个方案是一套针对大数据高并发的系统(比如订单系统的)的复合数据引擎方案,不是说普通的业务表都要这么做 3. 不是几倍的关系,索引表的字段是全量字段的子集,索引表不会做Sharding,这点你没有我的意思,可以再详细看一下文中的说明: 对二级索引进行查询得到主键,只需要查询一棵 B+ 树,效率同样很高。但索引的值不宜过大,比如对 varchar(1000) 进行索引不太合适,而索引外键(一般是 int 或 bigint 类型)性能就会比较好。因此,我们可以在 MySQL 中建立一张“索引表”,除了保存主键外,主要是保存各种关联表的外键,以及尽可能少的 varchar 类型的字段。这张索引表的大部分列都可以建上二级索引,用于进行简单搜索,搜索的结果是主键的列表,而不是完整的数据。由于索引表字段轻量并且数量不多(一般控制在 10 个以内),所以即便索引表没有进行 Sharding 拆分,问题也不会很大。

    5
  • 永夜
    老师你好,我们这边主要做一些交互式数据可视化系统,目前用的主要是postgres数据库,但是一旦数据量比较大,几百万条的数据的一些过滤统计都会比较慢,需要20~30s,我们也需要用到数组,json这样的特殊类型,不知道有没有其它的数据库或者框架能提高这种场景下的效率问题。

    作者回复: 使用ES,没有Sharding的关系型数据库承载不了你这么大的数据量的统计

    2
  • G小调
    老师 有个疑问❓ 你图里写的mysql索引库 是指表上建立了索引的库吗

    作者回复: 是指这个表大多字段都建了索引,主要用于简单搜索,索引库对比Sharding库

    2
    2
  • 那时刻
    请问老师,文章提到的多数据库系统例子里,redis写入是怎么实现的呢?

    作者回复: 取决于缓存的使用策略,比如Cache aside, Read through, Write through,可以根据你需要的方案把写入redis的操作落到读服务或同步写服务去实现。

    1
收起评论
显示
设置
留言
19
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部