关系型数据库存储在磁盘上
数据持久化:磁盘数据理论上如果环镜完善的话,数据永久存在的.
存储在磁盘上的任何类型数据,都是以文件形式存储的,数据库数据也是以文件形式存储在磁盘上面的。文件储存受到磁盘性能制约.
磁盘的读写操作都是机械io(就是磁盘读写的时候需要磁头定位,以及旋转),单词io操作属于毫秒级甚至于10毫秒级
关系型数据库每个表的数据都会形成一个独立的文件
独立的文件分布在磁盘上,当前磁盘的存储单元是4kb.消耗许多4KB存储整个文件。
当存在跨磁盘单元存储时,有可能是物理地址连续的,也有可能是不连续的。难免会增加磁盘IO次数,增加事件开销,导致性能变慢
120KB,消耗30个磁盘单元,磁盘最差需要30次机械臂摆动以及30次磁盘转动,最少一次
对磁盘来讲,数据碎片化越严重,地址越难以连续。
而增删次数越多,碎片化越严重.
所以增加IO次数在所难免.
针对数据库表数据的查询实质上就是在文件内部查找相关数据
那么计算机是如何读取文件内部数据的呢??
首先需要识别这个文件,也就是计算机需要对文件有记忆,一个文件如果有100M大小,计算机不会去记录文件的所有比特值信息,否则也会消耗100M空间.
计算机只会记录头地址.
就是文件的第一个比特地址.
通常我们写汇编,或者c操作地址的时候,也是第一个比特地址
这意味着我们查询文件内部某个数据,必须从文件头部第一个比特值开始查询,因为计算机不记录文件内部的比特之,所以无法从中间或者尾部通过任何比特值定位.
那么不管我们找文件的头部信息,中部信息,还是尾部信息,都必须从头开始找。
这种机制会带来什么缺陷呢,假设表内有100万数据,也就是文件中有1000万数据。
我们要查询尾巴或者中间的某一条数据,需要先删选百万,甚至1000万数据,导致了速度变慢。(关系型数据库的缺点)
建立索引:实质上是选取某一列数据以及行地址构成B+树
聚集索引是所有数据构成b+树(面试点)
https://www.cnblogs.com/s-b-b/p/8334593.html
理论上,数据是过万亿级,建立b+树索引后,会查询很快.
但是现实是,数据库只要运行,运行的数据必须先加载到内存当中,内存大小受限制。
内存存储单元是4KB.
一个8Gb的内存全部给数据库使用,理论上也只有200万内存单元.
而每个内存单元最多只能存放一个变量
或者存储一个变量的一部分.
当数据库数据进入内存之后,需要一条条解析,每条数据都要消耗至少一个内存单元
也就是说,理论上索引很快,但是残酷的现实是内存不够大
也就意味着单表建索引的话也会有上限,就是需要考虑内存问题
这就是分表的本质原因
分表操作加上索引,可以很快的进行查询
但是索引也不能解决大文件存储的弊端
如果切割成小文件查询+索引.
实质上更快,
举例子,1000万存储的文件,我们分割为1000个文件,每个文件存储10000数据,
设计的时候根据相关散列算法能够知道要查找的数据在哪个小文件当中。
散列我们清除,时间复杂度是O(1).也就是忽略不计的
当定位到小文件的时候,里面只有1000数据
我们从里面查询某条数据,浪费会大大减少.
再加上索引就更快了
所以这也是分布式文件计算产生的原因
衍生出了hadoop,spark,以及其他分布式文件计算
本质上是切割再计算。包括ES检索等,zk,zookeeper
这都是快的原因
什么是关系?(关系数据库)
很多解释称为外键,表关联外的类。实际上关系是行与行之间的关联计算.
例如:sum,avg,max,min
关系型数据库擅长的是关联计算.
当文件割成碎片文件,是方便查询的,但是不方便全关联计算.
涉及到关联计算,我们需要关系型数据库
涉及到数据查询,我们需要文件存储以及缓冲数据库.
一些部分关联计算,复杂拆分统计的可以用到hadoop之类的工具.
Hadoop第一步就是拆分文件.
缓存数据库::非关系型数据库:key:value
运行在内存中的.
内存速度是百万倍与磁盘的
所以缓存数据库实际上是把一部分数据存在内存当中
内存有大小限制,不能够存储所有数据。
所以应该选一些高频数据存在内存,提升综合查询速度.
除了缓存数据库,还有本地缓存,一般是程序进程内部缓存,访问本地缓存,相对于访问内存数据库,要更快一些,
一个是进程内内存共享访问,一个是跨进程访问,所以本地缓存更快一些,只不过集群慎重使用本地缓存,需要控制数据之间的同步问题.
缓存数据有一个特点,就是存储在内存当中,断电数据会消失.
所以,所有数据必须被封到磁盘上持久化.
使用场景:关联计算多的,使用关系数据库
只有增加和查询的,文件存储优先
例如使用zookeeper,kafka
加快查询速度的可以缓存到数据库,本地缓存。
所以以后大家在设计存储方案的时候,要根据自身的业务场景,合理使用不同存储方案