mysql/redis/habase/mongodb/es数据库杂谈

					嗷嗷嗷嗷,保持思考,保持智障。哈哈哈。

用的越多,越感觉自己是智障。尤其是是什么,为什么,怎么办,一套三连下来,真的是哑口无言。

使用数据库,一直存在一个问题就是,一张表的数据量是要在多少以内。
按照组内经验主义就是,sqlsever几千万都没问题,join很快。

mysql就不行了。阿里是建议五百万左右吧,公司内部是一千万左右。不能超过2表join
(这个更多是设计的问题,舍得放空间我觉得问题会好很多。

像sqlsver,那个节点连接图,真的看的头晕,还是mysql相对简洁很多,更多从架构的角度来彻底解决问题

毕竟当数据量非常巨大的时候,你单表支持500万还是2000万,没啥意义,反正都要分表分库,

尤其有一次sqlsever 老业务出了问题,单表join过亿,速度偶尔巨慢,我整整查了3天,从代码查到数据库,查到人都懵了,最后跑到DBA团队身边坐了几个小时,最后讨论是偶尔不走索引,其实带来了我得视野扩展,导致我逐渐走向其他DB的路上越来越远)。

不求甚解的时候就这样了。经验主义会在很多地方造成问题。你对整个代码功能的设计缺乏思路。

首先为什么是五百万或者一千万了。
肯定有原因。B+树看了又看,反正当时不懂,根本不会联想。但是刷lettocde,看着一群逗就有感觉了。树的的深度越深,那么速度越慢。

其实又回到了b+树本身
在这里插入图片描述

B这是一个聚簇索引,那么我要查数据要索引经过几层。
那么其实问题 mysql存储多少数据的问题?转化为 几层高度对于B+树存储的数据量。
在这里插入图片描述

看起来多高都没问题,因为数据量接近于O(logN),但是这是现实世界。不是天顶星世界。世界存在损耗,也就是读取硬盘/内存/SSD,都需要时间。
假设树高为2
1个根节点(16k为一页,这里是为了符合硬盘读取)
若干个叶子节点
1611024/(8+6)=1170
8为主键ID大小,6为指向指针大小。
非叶子节点存储1170个数据,然后到叶子节点,注意看图
在这里插入图片描述

看这个里面的大小,加入一行是1k,那么这里面就能存储16行
那么叶子节点就是1170*16=18720

再加一层 1170117016=21902400,数据量就2kw。但是要是做宽表,或者数据表爆炸大,数据量要4k 。
两层为4680条数据
三层为5475600,也就是500W左右,比较符合阿里的要求。所以设计还是要根据自身需求来,我们公司推荐1000W也OK。

===================-=============愚蠢的分割线
mongo db为什么用B树()
mongodb 都说数据量大,速度快。想知道为什么
我以前第一反应难道做的事 hashmap这种数组链表结构或者开放链法。
但是感觉不太靠谱。毕竟hash冲突我感觉会非常爆炸

mong db作为带头大哥,选择了B树。
B树相对于B+树差别就在于非叶子节点也带有数据,那么其实有点相当于跳表,跳跃节点直接命中,直接命中就可以返回数据了。这样子最好的时间复杂度会O(1).减少IO读取次数,但是不是很可能出现读的非常深的场景吗?如果每次读的特别深,岂不是爆炸。因为数据量增多,但是page页面里面容量的index变少,岂不是导致二叉树的高度变高?最后IO可能又增加。

上面的理解全是错的。知乎上面那群架构师,我也是佩服的不行。

我吐血看了很久很久很久,这个问题困扰了我接近3天(导致这篇文章迟迟写不出来卡死了)。因为我感觉无法说服我自己,虽然百度看一下,好像很有道理,用b-tree,但是TM的,感觉不对,最后仔细查阅资料,最后我还是信stack和wiredTigger本身。根本不用b-tree(还有这里是b树,没有b-这个概念,只是斜杠)。
在这里插入图片描述

一定要记住No sql概念本身,本身就是数据内聚不需要考虑其他。

那么mongodb同学怎么支持到大数据量了的?

支持大数据量一个是查询,一个是插入
插入支持大数据量的插入,非常简单,一个是水平扩展。二个是低事务性。同时还可以降低持久性。
不过新版本的持久性应该都是默认开启的。
虽然普通做Mysql感觉不到,但是看了一些文档,之后发现还是有undolong,redlog等来保持数据的可靠

大数据量的查询,一个是B-tree,二个是不是非常好支持Join,默认都是当一个文档直接嵌入做的。
三个是 内存映射(MMAP)

内存映射这个就是 访问数据,一般是常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要从磁盘到用户主存的一次数据拷贝过程

其实我更觉得是No sql这个概念,nosql代表了,数据之间没有关系,所以很减少复杂度增加了性能

=======================================感觉智商受到侮辱的分割线
hbase db为什么支持大量数据
每次看到这个问题,我就想起了以前kafka当年吹的最猛的时候,百万级并发。
当时一直的概念是
1.磁盘的页缓存
2.磁盘顺序读写
3.零拷贝
在现在我对1、2、3的理解随着TM的响应式编程(谈到响应式就要谈NIO,然后就是AIO,AIO他妈的又是看系统层面,就要谈零拷贝,谈几种实现,感觉就蛋疼),被逼的提升性能,阅读数据变多,而理解变深刻了。

基于HDFS做一个文件存储。
然后hbase是列式存储,有点像倒排索引,但是还是不是的。结构图如下
在这里插入图片描述

感觉这样子存储非常方便啊,加一个字段非常简单。

然后支持大数据插入也只能干顺序储存,就是LSM树。
存数据库完全是顺序存储,所以大数据一来,那么我们存数据完全都存在一个page里面,保证只存硬盘一次。
但是假如插入不是可能导致数据在硬盘里面不连续了吗?
这里会进行自动排序了,至于怎么重排,不知道了。

勉强不划水的分割线====
es为什么支持数据量,并且快
es做倒排索引,优点查询快。
但是每次重构索引比较麻烦

还有我非常喜欢这个近乎实时的功能,这就完全可以将数据慢慢刷新。各位大牛们,真的是骚操作玩到爆炸。从数据硬件到结构设计,真的是想尽办法去提升性能。基于不同的需求。

然后支持数据量大。一个是内存放倒排索引的,一个二叉树索引。当然只要内存够多,倒排索引直接全放进来也是可以的。

二个是,水平分片。根据id直接路由到不同的分片上。如果是模糊查询,直接query每一个,然后等聚合。

划水的分割线======
redis
redis本质上还是NIO+单线程解决问题,其实我现在个人感觉,更多是从java程序本身把通用的业务,比如缓存抽出来,做单独扩展。因为现在经常使用本机内存做缓存出问题。
然后做了很多数据压缩和结构问题。各种细节问题。
只带来两个局限的地方.
1:外部IO
2:结构相对局限,做到存储对象这种场景,要弄序列化和反序列化。不是很好

以后还是把查询的文档写出来,感觉更加正式。
参考文档:
https://en.wikipedia.org/wiki/B%2B_tree(wikipedia,竟然有推导,真惭愧)
https://www.cnblogs.com/ChromeT/p/12463751.html
https://www.cnblogs.com/yellowgg/p/11272908.html (二分查找推导为LogN,妈蛋,算法导论的推导过程已经忘光。以前看算法导论觉得推的贼顺,但是推完就忘。)
对于B+树也一样。也是每层查找到对半的节点,直接往下,然后底层继续对半查询,这里也反馈了为什么主键要顺序主键。
https://blog.csdn.net/csdnlijingran/article/details/102309593
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_why_we_wrote_this_book.html (ES 2.X的文档)

https://www.cnblogs.com/huxiao-tee/p/4660352.html (mmap)
https://mongoing.com/archives/35143 (WiredTiger)
https://zhuanlan.zhihu.com/p/102628897
https://blog.csdn.net/zc19921215/article/details/89283260(LSM)
https://www.cnblogs.com/niutao/p/10627217.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值