数据库
2024-12-24 14:44:23 10 举报
AI智能生成
该数据库是一个综合性的信息管理系统,涵盖了各种类型的数据,如文本、图像、音频和视频。它采用了先进的数据存储技术,如关系型数据库、NoSQL数据库和云存储,以确保数据的可靠性、安全性和可扩展性。此外,该数据库还提供了高效的数据查询和检索功能,以及数据可视化工具,以帮助用户更好地理解和分析数据。用户可以通过Web浏览器、移动应用或API接口来访问和操作数据库。
作者其他创作
大纲/内容
非关系型数据库<br>
NoSQL的四种分类<br>
K·V键值对的类型(Redis、)
文档型数据库(MongoDB、ConthDB)
列存储数据库(HBS、分布式文件系统)<br>
图关系数据库
Redis
Redis的一些定义<br>
什么是Redis?
Redis,英文全称是Remote Dictionary Server(远程字典服务)
是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis是一个单线程的,他的性能瓶颈是在在于机器内存的处理速度以及网络的带宽决定的,cpu的影响并不大,单线程就行了<br>
Redis的特性
多样化的数据类型<br>
五种基本类型,三种特殊的类型<br>
可以做持久化的处理<br>
RDB操作<br>
在指定的时间间隔中将内存中的数据集快照写入磁盘<br>
触发生成rdb文件的机制
1.save 的条件满足时,就会自动触发<br>
2.执行flushall后会触发
3.退出redis时也会被触发<br>
如何恢复rdb文件<br>
只需要将rdb文件放到redis的启动目录下,在启动的时候会自动检查恢复rdb中的数据
获取目录的方式
在进入redis的连接后 config get dir就能找到对应的文件夹<br>
rdb方式的优缺点
优点<br>
适合大规模的数据恢复<br>
对数据的完整性要求不高
缺点<br>
需要一定的时间间隔来触发,如果出现服务宕机的情况最后一次修改的数据会不被记录
fork进程触发的时候会占用一定的内存空间
AOF(APPEND ONLY FILE)<br>
把所有写的操作都记录下来,恢复的时候把这个文件再执行一遍,这文件有问题的话是不能启动redis的<br>
redis-check-aof --fix 后加aof文件可以修复aof文件<br>
优缺点
优点<br>
数据完整
缺点<br>
相当于数据文件来说,aof的数据文件要大于RDB<br>
因为AOF存储所有的指令文件大且考虑到IO性能<br>的问题运行的效率也要比rdb的速度慢<br>
为了解决这个问题将AOF文件中相同的指令压缩,只保留一个最新的数据操作指令<br>
恢复的步骤
过程
首先根据库中的数据重新创建一个AOF的文件<br>
读取当前redis中的数据写入新的AOF文件
重写完成后用新的AOF文件替换掉旧的<br>
按照上述的过程时,需要读取所有的数据时会比较消耗性能所以单独开了一个子进程来处理,<br>如果在此过程中数据发生变化需要将数据刷新到重写缓冲区中以此来防止出现数据不一致问题
集群<br>
Reids的主从复制
是指将一台服务器中的数据复制到其他的服务器,数据的复制是单向的,只能从主节点到从节点
指令’
主从复制查看当前库的信息 info replication<br>
主从复制认主操作 slaveof ip 端口号 <br>
自己当主节点 slaveof no one<br>
两种复制方式<br>
全量复制
从节点向主节点发送一个同步(SYCN)请求,主节点会形成一个数据快照,将数据快照发送给从节点,从节点删除原来数据,将快照内的信息写入
发生在初始化阶段
增量复制
通过维护off set这样一个复制偏移量,来让主从节点完成复制的<br>
发生在主节点的数据发生变更时
哨兵模式<br>
配置哨兵的配置文件<br>
文件名称: sentinel.conf<br>
sentinel monitor 被监控的名称 ip port 1<br>
数字1表示如果主机挂了,就让从机进行投票,票数最多的上位<br>
启动哨兵的指令 redis-sentinel 配置文件所在的位置<br>
原主机宕机再回来之后只能到现在的主机下做从机
优缺点
优点
哨兵模式基于主从复制,所有主从复制的优点他都有
主从可以切换,故障可以转移,系统的可用性会更好
哨兵模式就是主从模式的升级<br>
缺点
redis不好在线扩容,集群的容量一旦达到上限,在线扩容就很麻烦<br>
哨兵机制的配置比较繁琐
支持事务
事务
Redis的单条命令是有原子性的,但是事务是不能不保证原子性的<br>
Redis中没有隔离级别的概念
开启事务的命令 multi<br>
执行事务的命令 exec<br>
放弃事务的命令 discard<br>
当编译报错时,整个事务是不生效的;但是当运行时出错时只有出错的语句不执行,剩下的都执行<br>
Redis中watch可以当做乐观锁来用
Redis有线程安全的问题吗
redis本身是一个线程安全的k-v形式的数据库,不需要任何的同步机制,所以他不存在任何线程安全的问题<br>rides6.0中增加的线程安全的模型只是用于处理网络的IO事件,还是只使用主线程来处理指令<br>
为什么redis没有使用多个线程来执行指令
redis出现性能的瓶颈是网络、io、cpu、内存,但是CPU不是主要的点,所以没必要用多线程<br>
如果使用多线程来执行命令还得考虑到加锁的问题,需要付出的代价更高
内存的淘汰策略
Random算法
TTL算法
在设置了过期时间的key中找到更早过期时间的进行有限deed移除
LRU算法
去移除最近很少使用的key
Redis中一种比较常见的内存淘汰算法、在内存中会维护一个大小为16的候选池,按照时间进行排序,每次从其中随机选五个值进行淘汰<br>
LFU算法
redis分布式
分布式锁
是一种跨进程跨机器的互斥锁,<br>
SETNX命令<br>
当key不存在时就返回1存在时就返回0
EXPIR
设置锁的失效时间,避免锁的死锁<br>
遇到的问题<br>
如果程序还没执行完但是失效时间到了怎么办<br>
Redisson中有一个watch dog的机制可以帮助对于key值进行续期<br>
集群模式下遇到主从切换导致锁失效的问题
RedLock<br>
Redis缓存的穿透和雪崩<br>
缓存穿透的概念
当用户要查询一个数据时,缓存的机制中没有,就会向持久层的数据库中进行查询<br>
解决缓存穿透的方法<br>
布隆过滤器
布隆过滤器是一种数据结构,对所有可能查询的参数以hash的形式存储,在控制层先进行校验,不符合的话就进行丢弃<br>
缓存空对象
在缓存中查询不到数的话,就直接放一个空值<br>
方法带来的问题
1.空值如果能够被保存的话就需要更多的空间来存放这些东西<br>
2.即使对空值设置了过去时间还会导致,缓存个持久存储有一段时间不一样,一致性要求比较高的就不行了<br>
缓存击穿的概念
缓存击穿是指一个key值有非常高频率的访问,在这个key值失效的一个很短的时间内,访问直接访问到了持久层的数据库导致宕机<br>
解决缓存击穿的方法<br>
设置热点的数据永不过期
从缓存的角度来看只要热点的key不过期就不会有击穿的情况<br>
加互斥锁
对于每个key同一时间只能有一个线程可以访问持久层数据库<br>
缓存雪崩的概念
是指在一个时间段内,很多缓存几种失效就有可能会导致<br>
解决缓存雪崩的方法<br>
搭建redis集群,一台出问题了还有其他的能补上(异地多活)<br>
限流降级<br>
缓存失效后通过加锁或者队列的方式来控制读写数据库的线程数量<br>
数据预热<br>
先提前访问一下数据,把访问较高的数据放到缓存里面,跟据不同的需要设置不同的过期时间<br>
Redis的订阅发布<br>
指令<br>
订阅一个频道 subscribe 频道名称<br>
发布者发布信息到频道 publish 频道名称 推送的内容<br>
Redis的一些指令<br>
启动Redis : redis-severt 文件目录/配置文件<br>
连接到Redis: redis-cli -p 6379<br>
关闭指令: shutdown<br>
reids有十六个数据库,select 数字可以切换数据库<br>
清除当前数据库中的数据: flushdb<br>
清空全部数据库中的数据: flushall<br>
设置访问的密码: config set requirepass+密码<br>
输入访问的密码: auth 密码<br>
查看数据库的大小: dbsize<br>
查看所有的key值: keys *<br>
判断当前的key是否存在 EXISTS<br>
移动当前的key: move key <br>
删除当前的key: del key<br>
设置过期的时间: expire name 时间<br>
查看当前key的剩余时间: ttl name<br>
setex (set with expire): setex key 时长 value<br>
setnx (set if not exist) 不存在了再设置(分布式锁中经常使用): setnx key value<br>
同时操作多个值<br>
同时设置多个值:mset key1 value1 k2 value2... <br>
msetnx是一个原子性的操作要不同时成功,要不同时失败<br>
同时获取多个值: mget key1 key2<br>
查看当前key值的类型: type name<br>
追加字符串,如果有key就在后面进行拼接,如果没有就像当于set: append key value<br>
获取字符创的长度: strlen key<br>
自增一: incr key <br>
自增一个指定的长度 incrby key 长度<br>
自减一: decr key <br>
自减一个指定的长度 decrby key 长度<br>
组合命令<br>
先get再进行set操作(得出的value值是set之前的值) getset key value<br>
从原来的删除插入到新的 lpoplpush 原来的key 目标key<br>
List类型的指令<br>
所有的list命令都是以l开头的,底层的结构是链表结构<br>
将一个值或者多个值插入到列表中 lpush key values<br>
从右边插值 rpush key values <br>
从左开始删除一个值 lpop key<br>
从右开始删除一个值 rpop key<br>
通过下标来获取某个值 index key<br>
获取值的长度 llen key
移除值 lrem key 移除的个数 value<br>
移除值 ltrim key 开始下标 结束下标<br>
往外取数组的元素 lrange kye 开始下标 结束下标<br>
替换数组的元素 lset kye 下标 替换的内容<br>
在之前/之后插入一个值 linsert key before/after 原有值 新插入的值 <br>
Set类型的指令
所有set命令都是以s开头<br>
添加值 sadd key values<br>
看看set中的所有的元素: smember key<br>
判断某个value是否在key中: sismember key value<br>
获取set集合中元素的个数: scard key<br>
移除key中的value: srem key value<br>
从key中随机取出一个元素: srandomme key<br>
随意移除一个value: spop key <br>
移动value从一个key到另一个key : smove key1 key2<br>
求两个集合的查集 : sdiff key1 key2<br>
求两个集合的并集 : sunion key1 key2
求两个集合的交集 : sinsert key1 key2
Hash类型的指令
value的值是一个map类型,其本质和String类型没太大的区别<br>
获取值 hget KEY key<br>
添加操作
添加多个操作 hmset KEY key1 value1 key2 value2........<br>
添加多个操作 hset KEY key1 value1 ........<br>
取值操作
获取多个值 hmget KEY key1 key2<br>
获取单个的值 hget KEY key<br>
获取全部的数据 hgetall KEY <br>
删除数值的操作 hdel KEY key<br>
判断个数 hlen KEY<br>
判断是否存在 hexsit KEY<br>
获取KEY下的所有key hkeys KEY<br>
获取KEY下的所有value hkeys KEY<br>
获取值后加一 hincrby KEY key 1<br>
如果不存在的话才会进行设置 hsetnx KEY key value<br>
Zset类型的指令
所有的命令都是以z开头的,其实就是有序的set
添加值的操作 zadd KEY 数值 value<br>
移除值的操作 zrem KEY value<br>
a获取有序集合中的个数 zcard KEY <br>
获取集合区间值的个数 zcount KEY 最小值 最大值<br>
添加值的操作 zrangebyscore KEY -inf +inf<br>
geospatial地理位置<br>
命令以geo开头,两级的数据库无法添加,一般会通过java程序导入数据<br>
底层的原理其实就是zset
添加值的操作 geoadd KEY 纬度 经度 名称<br>
获取经纬度的操作 geopos KEY 名称<br>
查看两个坐标的直线距离 geodist KEY 名称1 名称2 距离单位<br>
查询坐标为中心集合中距离半径内的名称 geodist KEY 纬度 经度 距离半径 withdist<br>
找出位于指定元素周围的其他元素 gedradiusb KEY 名称 距离半径<br>
Hyperloglog<br>
基数统计的算法,指令是以pf作为前缀的<br>
添加值的操作 PFADD KEY values...<br>
计数的操作 PFCOUNT KEY <br>
取key2和key3的交集 pfmerge KEY1 key2 key3 <br>
BitMaps
位图存储机构,用来处理之后两种状态的数据,即用0和1进行标识<br>
存储数据 setbit key 位数 0、1<br>
获取数据 getbit key 位数 <br>
统计数量 bitcount key 区间<br>
MongoDB<br>
子主题
定义
MongoDB是一个基于分布式文件存储的数据库,C++编写主要用来从处理大量的文件<br>
MongoDB是一个介于关系型数据库和非关系型数据库之间的数据库,是非关系型数据库中功能最丰富的,最像关系型数据库的<br>
子主题
ES数据库
基本定义
索引(Index)
相同类型文档的集合、类似于数据库的表<br>
文档(Document)<br>
这里的文档就是指的一条一条的数据,类似于数据库中的行,保存时以JSON的形式进行保存<br>
字段(Filed)
字段就是JSON中的字段,类似于mysql中的column<br>
映射(Mapping)
是索引文档中的约束,例如字段类型的约束,类似于数据库的表结构
DSL
JSON风格的请求语句,类似于SQL语句
分词器<br>
分词器功能<br>
在创建文档索引时对文档的内容进行索引<br>
在用户进行查询时对查询的内容进行分词<br>
组成包含三部分<br>
character filters<br>
在tokenizer之前对文本进行处理,例如删除字符替换字符,处理一些特殊符号什么的<br>
tokenizer<br>
将文本按照一定的规格切分成词条(term)例如keyword,就是不进行分词<br>
tokenizer filters<br>
对tokenizer输出的词条进行进一步的处理,例如大小写转啥的
IK分词
安装原因<br>
ES本身自带的分词器在进行中文分词的时候不太友好,对汉字分词时一个一个分会使得查找不准确
分词方式
ik_max_word<br>
这种形式分词分的比较多,能组成中文的词都会分一遍
ik_smart<br>
最少分词,能组成最长的词语时就不会再往下分<br>
分词内容可以实现个性化的设置<br>
找到ik分词器中config目录下的IKAnalyzer.cfg.xml文件在其中可以设置那些词可以分词,那些就不做分词操作<br>
对索引和文档的操作
索引<br>
创建
PUT /索引名称<br>
查找
直接get /索引名称<br>
新增字段
PUT /索引名称/_mapping<br>
<br>
删除
delete /索引名称<br>
修改
索引只能增删不能进行修改<br>
操作索引库的大概代码<br>
<br>
文档
创建<br>
POST请求
POST /索引库名/_log/id<br>
查找<br>
GET请求
GET /索引库名/_log/id
删除
DELETE请求
DELETE /索引库名/_log/id
修改<br>
全量修改<br>
先删除再重新插入,如果原来就没有这个操作则只进行插入操作<br>
语法只是将创建请求的POST请求方式转换为PUT请求方式
部分修改
直接更改其中的某个字段,语法是POST /索引库名/_update/id<br>
操作文档的大概代码<br>
插入
<br>
查找<br>
<br>
更新
全量更新<br>
全量更新跟插入的操作是一样的<br>
局部更新
<br>
DSL语法<br>
常见的查询语法<br>
查询所有<br>
查询出测试的数据,一般测试用match_all
全文检索<br>
利用分词器对用户查找的数据进行分词,然后利用倒排索引进行查找(match、multi_match(支持多个条件))<br>
match和multi_match
match<br>
单个条件查找<br>
multi_match
根据多个字段查询,参与查询的字段越多,查询性能越低
精确查找<br>
根据精确地词条进行查询,一般用来插keyward、Boolen、日期等类型的数据(id、range、term)<br>
<br>
关键字<br>
term
根据词条进行精确查询,是不进行分词操作的<br>
子主题
range
根据值的范围进行查询
gte代表大于等于,gt则代表大于
lte代表小于等于,lt则代表小于
模糊查询
关键字用match
地理查询<br>
distinct根据经纬度进行查询(geo_distance)<br>
查询矩形范围内的数据<br>
<br>
查询附近的数据
<br>
<br>
复合查询
复合查询可以将上述的各种条件组合起来(bool、function_score)<br>
得分算法<br>
<br>
<br>
<br>
布尔查询<br>
布尔查询是一个或者多个子查询的组合<br>
关键字<br>
must
必须查询的字段,类似与<br>
should<br>
选择性匹配子查询类似于或
must_not<br>
必须不匹配,类似非
filter
必须匹配不参与算分 <br>
排序<br>
如果进行排序的话,es原本的算分规则将会失效
语法
地理字段<br>
普通类型<br>
分页操作<br>
原理<br>
由于es经常是以集群的方式存在的,在保存数据时具有随机性,在查询<br>时会将每个机器上到目前的数据都取出来进行排序,再取当前要取的那部分的数据<br>
<br>
分页方式
from+size<br>
优点是支持随机分页、缺点是存在分页上限的问题,默认是10000条
场景是常遇到的互联网使用场景,可以前后分页<br>
after search<br>
优点是没有查询的上限、缺点是查询的时候只能往后查,不能往前<br>
scroll<br>
原理是将查询出的数据在内存中形成一个快照,后续的查询能在快照中取数据的就在快照中取<br>
优点是没有查询的上限,缺点是数据不具有实时性,目前已经不推荐使用了<br>
高亮操作
如果是混合字段时,指定某个字段设置高亮时需要更改默认值<br>
高亮的API包括DSL的创建和对于结果的解析<br>
<br>
查询语句汇总<br>
<br>
聚合操作
实现对文档数据的统计、分析和计算,并且参与聚合的数据必须是不能分词的<br>
<br>
聚合的三要素<br>
聚合名称、类型和聚合的字段
聚合操作的分类<br>
桶(Bucket)
用途<br>
用来对文档进行分组<br>
TermAggregation<br>
按照文档的字段值进行分组<br>
Date Histogram<br>
按照日期梯度分组,例如一周为一组或者一个月为一组<br>
默认的情况下,Bucket聚合会统计Bucket中文档的数量用_count表示,并且按照顺寻从大到小排列<br>并且,不指定query条件的情况下默认对所有的数据进行聚合<br>
<br>
<br>
度量<br>
用以计算一些值,比如最大值、最小值、平均值<br>
AVG(平均值)、MAX(最大值)、MIN(最小值)、Stats(同时求几种值)<br>
管道<br>
以其它聚合的基础进行聚合
<br>
自动补全的接口<br>
<br>
基本语法
<br>
<br>
数据同步
同步调用<br>
ES集群<br>
面临的两个问题<br>
海量数据存储问题<br>
将数据进行分片操作,分成N个(share),分别存储到不同的节点上
单点故障问题
将分片的数据进行备份(replica)<br>
分片分出的备份不会被放到同一个节点上<br>
配置es的集群名名称一样时,es默认会分配到同一个集群<br>
es的脑裂问题<br>
问题原因<br>
当es为集群布置时,当主节点和备用节点之间的网络通信出现异常时,备用节点默认主节点宕机,重新进行选举,选取成功后新的主节点和原来的备用节点会发生一些冲突<br>
解决方案<br>
为了避免脑裂问题的出现,需要要求选票的结果超出(eligile节点的数量+1)/2才能当先为主,音系eligible中的节点数量最好为单数<br>
分布式查询分为两个阶段
scatter phase 分散阶段<br>
coordinating node 会把请求分发到每一个分片上<br>
gather phase 聚合阶段<br>
coordinating node 汇总date node的搜索结果,并处理为最终结果返回给用户<br>
es集群的故障转移
mast节点故障之后,新的主节点会排查原来主节点上有什么分片信息,将其同步得到其他健康的节点上,用以确每个分片都有自己的备份分片信息<br>
节点类型<br>
master eligible 节点
参与集群选择主节点<br>
主节点可以擦管理集群的主节点、管理分片的信息、处理创建和删除索引库的操作<br>
date 节点<br>
对数据进行crud操作<br>
分布式新增如何确定分片<br>
coordinating 节点<br>
请求的路由和负载均衡<br>
合并查询到的结果并返回给用户
<br>
<br>
关系型数据库
mysql
存储引擎
InnoDB
MySQL 默认的事务型存储引擎,只有在需要它不支持的特性时,才考虑使用其它存储引擎
子主题
MyISAM
两者的对比<br>
InnoDB
MyISAM
支持事务
不支持事务
行级锁和表级锁都支持<br>
只支持表级锁(适合查询)
数据和索引存储一个文件<br>
数据和索引分开存储
支持外键
不支持外键
索引
索引的定义<br>
索引是一种帮助数据查询的数据结构
索引的分类
主键索引(PRIMARY KEY)<br>
唯一的标识,主键不能重复,只能有一个列作为主键<br>
唯一索引 (UNIQUE KEY)<br>
索引列的值必须唯一,但是允许有空值
常规索引(index/key)<br>
默认的,index/key来表示
联合索引
又叫做复合索引,多列索引,专门用于复合查询,效率大于多个索引的合并<br>
显示表所有的索引信息
show index from 表名<br>
聚集索引和非聚集索引的区别
聚簇索引就是按照每张表的主键构造一颗B+树,每张表只能有一个聚簇索引
InnoDB 主键使用的是聚簇索引
如果表设置了主键,则主键就是聚簇索引
如果表没有主键,则会默认第一个NOT NULL,且唯一(UNIQUE)的列作为聚簇索引
以上都没有,则会默认创建一个隐藏的row_id作为聚簇索引
普通索引也叫二级索引,除聚簇索引外的索引,即非聚簇索引。
索引那些情况下会失效
查询的字段中如果包含or就可能会导致索引失效<br>
查询的字段中使用like语句是%如果在左边也可能会导致失效
联合索引时没有遵守最左匹配原则时<br>
最左匹配原则
由于联合索引由多个索引字段构成在进行结构创建时遵循先以最左边的索引做为树状图上面部分<br>
自身的优化器认为全表扫描比使用索引快时<br>
对字段进行判空处理、运算处理、判断大小处理、作为连接的字段编码不一致时<br>
B+树和B树的区别<br>
B树将数据和索引信息放到了一起,B+树非叶子节点只放置主键(非叶子节点就能存储更多的数据),叶子节点按照从小到大的顺序放置<br>
B+树的叶子节点上采用双向链表的形式存放数据<br>
SQL的优化<br>
当只要一行数据时使用limit 1
用not exists代替not in<br>
not exists用到了连接能够发挥已经建立好的索引的作用,not in不能使用索引。
对操作符的优化,尽量不采用不利于索引的操作符
应该用小的结果驱动大的结果(left join 左边表结果尽量小如果有条件应该放到左边先处理, right join同理反向)
不用SELECT * ,如果查询大数据量的表时SELECT 后面跟每个字段的名称<br>
数据库的范式<br>
范式一:每一列都是不可再生的<br>
范式二:在范式一的基础上,非主键内容完全依赖于主键
范式三:在范式二的基础上,非主键的内容只依赖于主键,不依赖于其他键
事务<br>
数据库的特性
原子性:每一个都是不可分割的
持久性:数据被修改后就会永久保存
一致性:无论数据怎样进行变化,数据的总量是不变的
隔离性:数据发生变化不会影响其他的数据
事务并发访问可能会引起的问题<br>
脏读:一个事务读取到了其他事务未提交的内容
不可重复读:同一个事务在执行过程中多次查询的返回结果不同,与脏读的区别主要在于此执行过程还没结束<br>
幻读::一个事务在两次查询之间,另一个事务插入了新的满足查询条件的行。导致两次查询结果集不同。
隔离级别<br>
未提交读(Read UnCommit):读取到未进行提交的内容,可能会导致脏读<br>
已提交读(Read Commit):大多的数据库默认的隔离级别,一个事务在提交前所做的所有的操作都是不会被看到的,可能会导致不可重读的情况发生、<br>
可重复读(Repeable Read):数据库默认的隔离级别,同一事务的多个实例在并发读取事务时会看到同样的数据行<br>
串行化(Serializable) 最高的隔离级别,强制事务的执行顺序进行排序执行,使之不可能会发生冲突<br>
事务的实现方式<br>
编程式事务<br>
需要自己写代码在什么地方开启 提交事务<br>
<br>
声明式事务<br>
使用@Transactional声明
参数
<br>
事务的传播方式
支持当前事务的
Propagation.REQUIRED
默认的事务传播级别,它表示如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。
Propagation.SUPPORTS<br>
如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。
Propagation.MANDATORY
如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。
不支持当前事务的<br>
Propagation.REQUIRES_NEW
表示创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部⽅法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法会新开启⾃⼰的事务,且开启的事务相互独⽴,互不⼲扰。
Propagation.NOT_SUPPORTED<br>
以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起
Propagation.NEVER:
以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常
嵌套事务的
Propagation.NESTED<br>
如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED。
undo log和red0 log的区别<br>
缓冲池
内存中的一块区域,对数据进行修改操作时现在这个区域进行然后以一定的频率进行统一IO,可以降低IO的操作次数,如果缓冲池中没有就到磁盘中取<br>
数据页
InnoDb中磁盘管理的最小单元,大小大概为16kb,其中存储的是行数据
redo log<br>
重做日志,记录的是事务提交时数据页的物理修改,用来实现事务的持久性<br>
两部分组成
重做日志缓冲(redo log buffer)<br>
在内存中,缓冲池中的数据发生变化就会将对应的数据也记录到日志缓冲文件中】
重做日志文件(redo log file)在磁盘中数据恢复时就用的这个<br>
undo log<br>
回滚日志,主要记录修改前的数据,主要的功能包含两个:回滚日志和MVCC,是一种逻辑日志<br>
MVCC多版本并发控制
基于数据版本对于并发事务进行访问<br>
基于undoLog(回滚日志的控制连)<br>
TRX_ID
事务id
每一次更新的事务的id<br>
DOB_ROLL_PRT<br>
指针信息:指向了上一个版本的数据信息<br>
无论事务是否已经已经提交都会被记录到版本链中,且undolog用完之后不会立即被删除,mysql在确定这个控制连不会被使用时才会进行删除<br>
概念模型图<br>
<br>
ReadView
这里延申两个定义<br>
快照读<br>
这个就是指最普通的select查询语句,MVCC就是在快照读的时候用的<br>
当前读 <br>
指在修改数据之前进行查询的操作(INSERT\UPDATE\读写锁啥的)<br>
是一种数据结构、包含四个字段
m_ids
当前活跃的事务编号集合<br>
min_trx_id<br>
最小活跃编号<br>
max_trx_id
预分配的事务编号,当前最大的事务+1<br>
creator_trx_id
当前readView创建者的事务编号<br>
不同隔离级别生成<br>
在RC的隔离级别下,每一次进行快照读都会生成一个新的ReadView
在RR的隔离级别下,仅在第一次进行快照读会生ReadView,后面再使用这个快照读都会使用这个
连续多次进行快照读的情况下,ReadView会被多次进行复用,避免了幻读的情况<br>
也会有例外(两次快照读的中间存在当前读的情况下就会重新生成ReadView)<br>
判断规则
<br>
sql优化<br>
如何定位慢查询sql
mysql的慢日志查询<br>
slow_query_log =1 开启慢日志查询的开关<br>
long_query_time
设置超过多长时间的为慢日志<br>
慢日志存储位置<br>
/var/lib/mysql/localhost-slow.log<br>
explain解析原因<br>
属性<br>
possible-key<br>
sql中可能使用的索引<br>
key<br>
实际命中的索引<br>
key-length<br>
索引占用的大小<br>
extra<br>
实际占用的大小<br>
type
这条sql连接的类型,性能由好到差
NULL
查询的语句没有使用到表<br>
system
查询系统中的表
const
根据主键进行查询
req_ref
主键索引或者唯一索引
ref
索引查询
range
走索引但是是范围查询<br>
index
索引树扫描<br>
all
全盘扫描<br>
子主题
通过判断req_ref或者req的内容来判断是否走了索引,没有就建索引<br>
通过type来判断是否有进一步的优化空间,是否存在全盘扫描<br>
通过extra来判断是否出现了回表,如果出现且允许的话可以通过添加索引列或者减少查询列来结局
视图
视图的概念
视图是一个虚表,由查询的语句定义出来的,可以当做表来使用<br>
视图中的数据没有实际的物理存储
可更新视图:在定义的时候需要添加 WITH CHECK OPTION,这样的话就可以用视图实现对基本表的更新操作
基础知识
数据表的类型
<br>
MYISAM
INNODB
事务支持 <br>
不支持
支持
数据行锁定
不支持
支持
外键约束<br>
不支持
支持
全文索引
支持
不支持<br>
表空间的大小
较小
较大,约为两倍
两者物理文件上面的区别<br>
InooDB在数据库表中只有一个*.frm文件,以及上级目录下的ibdata1文件<br>
MYISAM对应文件
*.frm表结构的定义文件
*.MYD数据文件<br>
*.MYI索引的文件<br>
外键
添加外键的语句
建表时的的语句
KEY `FK_teacherid` ( `teacher_id` ),<br>CONSTRAINT `FK_teacherid` FOREIGN KEY ( `teacher_id` ) REFERENCES `teacher` ( `teacherid` )
修改表时添加外键<br>
alter table 表名 ADD CONSTRAINT `约束名` FOREIGN KEY ( `作为外键的列` ) REFERENCES `哪个表` ( `哪个字段` )<br>
以上的操作都是物理外键,因为删除表的时候会很麻烦想,要找到依赖,一般的不进行使用
数据库列的类型
数值类型
int 标准的整数 4个字节<br>
int后面的括号只是表示显示多少
bigint 较大的数据 8个字节<br>
float 浮点型 4个字节<br>
double 浮点型 8个字节<br>
decimal 字符串类型的浮点数 金融计算的时候一般使用这个<br>
字符串类型
char 固定大小的字符串 0-255<br>
varchar 可变的字符串 0-65535长度<br>
tinytext 微型的文本 2^8-1<br>
text 文本串 2^16-1 <br>
时间类型<br>
date YYYY-MM-DD<br>
time hh:mm:ss<br>
datetime YY-MM-DD hh:mm:ss<br>
timestamp 为时间戳,1970.1.1到现在的毫秒数<br>
指令
操作库的指令
显示所有的数据库
show databases<br>
查看数据库中所有的表<br>
show tables<br>
查看某张表
describe 表名<br>
修改表的名称
alter table 表名 rename as 新表名<br>
添加表的字段到指定的列
alter table 表名 add 列名 类型 after 那一列<br>
修改表中的字段
修改字段的类型
alter table 表名 modify 列名 约束类型<br>
修改字段的名称
alter table 表名 原字段名 先字段名 约束类型<br>
删除表中的字段<br>
alter table 表名 drop 字段名称<br>
聚合函数<br>
拼接字符的函数<br>
SELECT CONCAT('学号:',emp_no) '学号' FROM salaries<br>
计数用的count<br>
count(列名) 会忽略null的<br>
count(*) 不会忽略null值的 本质是计算行数 <br>
count(1) 不会忽略null值的 本质是计算行数 但是这个是把所有的值都当做一,速度比count(*)更快<br>
窗口函数<br>
专有窗口函数<br>
聚合窗口函数
avg\
窗口函数和普通情况下聚合函数的区别<br>
普通环境下聚合函数是将多条数据变为一条,但是窗口函数的情况下原来是多少条数据后续还是会是多少条数据<br>
分组: <br>
<br>
集群设置<br>
使用情况:当库中的数据超过千万级就不建议使用单库了
集群的模式<br>
读写分离的模式
及主从复制的情况,一个住负责写,利用数据库同步写的情况写入到从服务器中<br>
主从复制<br>
master节点负责写,更新binlog日志<br>
binlog日志是一种二进制的文件,记录了DDL和变更信息的语句
创建一个dump线程将binlog中的内容推送到save节点上<br>
从节点连接上主节点的时候,会创建一个IO线程将主节点同送来的数据写到relady log(中继日志)中<br>
从节点再开一个线程,将中继日志中的数据再从节点中执行,进行同步i<br>
从节点记录自己的binlog日志<br>
同步的延时怎么处理<br>
重要数据直接读主库,非关键的业务读分库<br>
读从库失败后再读主库的内容<br>
优缺点<br>
配合MHA中间件(主服务器挂掉可以选举)实现高可用性
适用于读多写少的互联网应用<br>
架构复杂度提升,成本提高
分片的集群模式<br>
及分库分表的集群模式
优缺点
架构的复杂性提上了,成本提高
每个节点数据只是所有数据的一个子集
适用于十亿级数据总量大型应用
不具备高可用性质
分片的算法
范围法
及根据范围进行分割 <br>
优点,机构见到那、扩展时比较容易,适合范围i的搜索<br>
缺点:数据分布不均匀,局部的负载压力大,适用于 流水账类型的应用<br>
Hash法
也分为取模(最简单的类型来说就是对于id进行取余)与一致性Hash<br>
优点:数据分配均衡
缺点:提前部署对应足够的节点,适用于预算比较充足的大型互联网应用<br>
分表方式<br>
水平分表<br>
及分库分表形式的分表,表所有的数据结构都是相同的,解决数据量大的一个存储问题<br>
垂直分表<br>
将一张大表按“列”拆分为两张以上的小表,通过外键关联来获取数据(拆分模块就类似于这样,类似于订单表,订单表明细表这些)<br>
InoDB的存储方式 行--->页(page一页大概可以存储16k的数据)-->区(Extent基本时1MB的存储空间即64个页)<br>在1.0后引入了压缩页的概念:及通过压缩使一页中可以存储更过的数据,跨页需要解压,解压的效率比较低<br>
何设计才可以让系统从未分库分表动态切换到分库分表上?
停机迁移方案
对于公司没有停机时间要求的,可以写个工具直接刷数据<br>
双写迁移方案
线上系统里面,之前所有写库的地方,增删改操作,除了对老库增删改,都加上对新库的增删改
然后像第一种一样写个工具,把新库没有的或者老库的变更时间新于新库时间的<br>
使用的中间件MyCat或者ShardingSphere
0 条评论
下一页