Java八股整合(MySQL+Redis)

devtools/2024/9/24 7:05:40/

MySQL

数据库设计三范式

不可再分,部分依赖,传递依赖

主键和外键区别

主键非空约束,唯一性约束,唯一标识一个字段

外键用于和其他表建立连接,是另一张表的主键,可重复可为空可以有多个

为什么不推荐使用外键

因为外键增加了复杂度(增删时要考虑外键约束),增加了额外工作(额外维护外键),不利于分库分表

drop,delete和truncate区别

drop丢弃数据,在删除整个表时使用

delete删除数据,按行删除数据

truncate清空数据,在清空表中数据时使用

drop和truncate是DDL数据定义语言,不能回滚;delete是DML数据库操作语言,提交才生效

数据库设计步骤

需求分析,概念结构设计,逻辑结构设计,物理结构设计,数据库实施,数据库运行和维护

关系型数据库

建立在关系模型上的数据库,包含一对一,一对多,多对多的关系

SQL

结构化查询语言,目的是从数据库中读写数据

整数类型的UNSIGNED属性有什么用

表示不允许负值的无符号整数,提升正整数上限

CHAR和VARCHAR区别

定长和不定长字符串

VARCHAR(100)和VARCHAR(10)区别

最大容量不同,超过时需要修改表结构,100会消耗更多内存(排序时按照100进行),但占用磁盘空间一样

DECIMAL和FLOAT,DOUBLE区别

DE是定点数,存储精确值

为什么不用TEXT和BLOB

无默认值;使用临时表时无法使用内存临时表,只能在磁盘上创建;检索效率低;不能直接创建索引需要指定前缀长度;消耗大量网络和IO带宽;导致DML变慢

DATE和TIMESTAMP区别

D没有时区信息,消耗存储空间更大

NULL和空字符串区别

NULL表示不确定值,无法判断相等(要用IS NULL判断);会占用空间;影响聚合函数结果

空字符串长度为0

Boolean类型如何表示

TINYINT(1),可以存储1或0表示

MySQL基础架构

连接器,查询缓存,分析器,优化器,执行器,插件式存储引擎

MySQL存储引擎

默认InnoDB,唯一事务性存储引擎

是插件式架构,基于表而不是数据库

InnoDB和MyISAM区别

I是行级别锁,M是表级别锁

M无事务支持,不支持外键,不支持MVCC,不支持数据库异常后的安全恢复,性能不如I强

InnoDB数据本身就是索引文件,MyISAM索引文件和数据文件是分离的

事务

逻辑上的一组操作,要么都执行,要么都不执行

ACID原子性,隔离性,一致性,持久性,一致性是目标

并发事务带来的问题

脏读,丢失修改(修改被复写),不可重复度,幻读

并发事务控制方式

锁(共享锁(读锁,S锁),排它锁(写锁,X锁))(行级锁,表级锁(不容易死锁))

意向共享锁(IS锁),意向排它锁(IX锁),意向锁之间互相兼容

MVCC多版本并发控制方法,一份数据存储多个版本,通过隐藏字段,read view,undo log实现

四个事务隔离级别

通过锁和MVCC机制共同实现

默认可重复读

InnoDB行锁

记录锁,单个行记录的锁

间隙锁,锁定一个范围,不包括记录本身

临键锁,锁定一个范围,包括记录本身

默认临键锁,操作的索引是唯一索引或主键则降级为记录锁,只锁住索引本身

当前读和快照读区别

快照读(一致性非锁定读),就是Select语句,读到的是记录的历史版本

当前读(一致性锁定读),给记录加X或S锁

MySQL如何存储IP地址

INET_ATON(),ip转换为无符号整型

INET_NTOA(),无符号整型转换为ip

分析SQL性能

EXPLAIN

索引

底层数据结构

Hash表,通过哈希算法找到key对应的index。冲突时用链表或者红黑树

二叉查找树,性能依赖于平衡度

自平衡二叉查找树,需要多次旋转,每个节点只能存储一个数据,需要多次磁盘IO

红黑树,应用广泛

B树,多路平衡查找树,节点同时存放key和data;叶子结点相互独立;可能未到叶子结点就检索完毕;需要先找到查询下限再中序遍历找上限

B+树,非叶子结点只存key,叶子结点之间有条引用链,检索稳定,只需要链表遍历即可,IO次数更少

索引类型

(索引和数据是否一起存储)

聚簇索引,InnoDB中主键索引。查询快,对排序查找和范围查找速度快。但是依赖有序数据,更新代价大

非聚簇索引,辅助索引和MYSQL的MyISAM引擎的所有索引。更新代价小。但是也依赖有序数据,可能会需要二次查表找到对应数据(key=value时无需回表)

(应用维度划分)

主键索引,普通索引,唯一索引,覆盖索引,联合索引,全文索引

最左前缀原则

使用联合索引时,根据索引字段顺序,从左到右依次匹配查询条件中的字段,查询条件与最左侧字段匹配则会走索引过滤数据

一直向右匹配,直到遇到范围查询(大于小于)为止,对于大于等于,小于等于,between以及前缀匹配like的范围查询不会停止匹配

索引下推

在索引遍历过程中执行部分where语句的判断条件,直接过滤掉不满足的记录,减少回表次数,提高查询效率

将Server层负责的事推给下层存储引擎层处理,减少了数据传输量

推荐给什么样的字段设置索引

非空,经常被查询,被作为条件查询,频繁需要排序,常被用于连接的字段

日志

重做日志redolog

把修改记录在redolog中,持久性

刷盘(放入磁盘)时间:事务提交,log空间不足,事务日志缓存区满,检查点,后台刷新线程,正常关闭服务器

硬盘上的redolog有多个,是日志文件组,每个大小一样

随时写入

归档日志binlog

逻辑日志,用于数据备份,主备,主主,主从,保证同步

statement记录SQL语句原文

row记录原文和操作数据

mixed二者混合

事务提交时写入

两阶段提交

redolog和binlog逻辑不一致

将redolog拆成prepare和commit

恢复数据时处于prepare阶段,无binlog则会回滚

commit阶段无法回滚

回滚日志undolog

用于回滚,保证事务原子性

MYSQL基础架构

连接器:身份验证和权限相关

查询缓存:查询语句查询

分析器:未命中缓存时查看SQL语法(词法分析,语法分析)

优化器:按照最优执行

执行器:执行语句

Server层:跨存储引擎功能实现

存储引擎:数据存储和读取,插件式架构

Redis

基于c语言的非关系数据库,数据保存在内存中,读写快

Redis为什么快

基于内存,有一套高效的事件处理模型,主要是单线程事件循环和IO多路复用,内置了多种优化后的数据类型和结构实现,通信协议实现简单且解析高效

为什么用Redis

访问速度快,高并发,功能全面(能用于分布式锁,限流,消息队列,延时队列等)

Redis Module

可以动态灵活的扩展实现方式,自定义开发

Redis可以做消息队列吗

Redis可以做搜索引擎吗

Redis实现延时服务

1.Redis过期事件监听

2.Redisson内置的延时队列

减少了丢消息的可能(消息持久化),不存在重复消费问题(通过一个队列获取任务)

Redis常用数据类型

String,用于常规数据缓存,计数,分布式锁等。存储序列化后的对象数据,更省内存,Hash是对对象每个字段单独存储(一般用String存对象,需要对某个属性频繁修改则用Hash)

String底层用C语言,但不是用C语言的字符串实现的,而是自己编写了SDS

Set用于存放不能重复数据的场景,或者查找多个数据源的交集和并集差集,或者随机访问元素

List,Hash散列,Zest有序集合,HyperLogLog基数统计,Bitmap位图(存放0和1),Geospatial地理位置

有序集合底层为什么用跳表而不是各种树

平衡树插入和删除时间复杂度都是O(logn),但是需要对树调平衡

红黑树实现复杂,需要旋转和染色,并且按照区间查询操作效率不如跳表

B+树为了减少IO次数,但是Redis存储数据较少,不需要

Redis单线程模型

Reactor模式对应的是Redis中的文件事件处理器,文件事件处理器是单线程方式运行的,所以一般说Redis是单线程模型

文件处理器以单线程方式运行,但是通过IO多路复用监听多个套接字,为不同套接字关联不同的事件处理器,减少了额外创建线程监听客户端的大量连接

文件处理器包含多个socket(客户端连接),IO多路复用程序(支持多客户端连接),文件时间分派器(用于关联socket和事件处理器),事件处理器(连接应答,命令请求,命令回复)

Redis数据过期时间

缓解内存消耗

通过过期字典保存数据过期的时间

删除策略

惰性删除(访问时删除),定期删除,延迟队列(维护麻烦),定时删除(CPU压力大)

Redis采用定期删除+惰性删除

定期删除受到执行时间和过期key比例影响, 超时则中断,比例过大则重复删除流程

大量key集中过期怎么办

避免集中过期,设置随机过期时间,或对过期的key开启lazyfree机制

内存淘汰策略

设置了过期时间的最近最少使用淘汰,将要过期的数据淘汰,设置了过期时间的任意数据淘汰,最近最少使用淘汰,任意数据淘汰,不淘汰,最不常用的淘汰,设置了过期时间的最不常用的淘汰

Redis事务

命令打包顺序执行不被打断

通过MUL TI开始事务,EXEC执行事务,DISCARD取消事务,WATCH监听key,实现

不支持回滚,不满足原子性

支持三种持久化方式:快照,只追加文件,RDB和AOF混合持久化

Redis性能优化

使用批量操作减少网络传输(命令发送,排队,执行,返回结果)

解决大量key集中过期问题

处理BigKey

占用大量内存的key,,可能是程序设计不当,业务数据规模考虑不周到,未及时清理垃圾

会造成客户端超时阻塞,网络阻塞,工作线程阻塞

处理bigkey:分割bigkey,手动清理,采用合适的数据结构,开启lazyfree

处理hotkey

访问次数多的key,可能是重大热搜或者参与秒杀的商品

会占用CPU和带宽

处理hotkey:读写分离,使用Redis Cluster分散存储,二级缓存(放JVM本地内存)

慢查询日志

需要消耗长时间的命令,遍历或排序

慢查询日志每个条目包括:日志标识符,Unix时间戳,执行所需的时间,组成命令参数的数组,客户端IP地址和端口号,客户端名称

缓存穿透

大量请求的key不在缓存中也不在数据库中,导致大量请求提交到数据库上,造成巨大压力

解决方案:缓存无效key,布隆过滤器,接口限流

布隆过滤器用一个很大的bit数组保存所有数据,每个位可以是1和0,判断用户请求值是否在过滤器中,不在则返回错误信息

缓存击穿

热点数据在数据库而不在缓存中,被瞬时大量数据请求打宕机了

解决方案:永不过期(不推荐),提前预热(提前存入缓存并设置合理过期时间),加锁(缓存失效后设置互斥锁保证只有一个请求访问数据库)

缓存雪崩

缓存同一时间大面积失效,大量请求直接访问数据库

由于Redis不可用:Redis集群,多级缓存(本地缓存+Redis缓存)

由于大量缓存同时失效:设置随机失效时间,提前预热(使用定时任务查询热点数据存入缓存,使用消息队列异步预热),持久缓存策略

如何保存缓存和数据库一致性

不一致时异步重试,将重试请求写入消息队列,由专门消费者重试直到成功

或者直接将操作缓存步骤放入消息队列中

推荐先更新数据库再更新缓存,配合消息队列或订阅变更日志

主从库延迟问题使用延迟双删,先删除缓存更新数据库,过一段时间再删除一次缓存

强一致需要牺牲性能


http://www.ppmy.cn/devtools/96090.html

相关文章

百度地图SDK Android版开发 6 显示覆盖物

百度地图SDK Android版开发 6 显示覆盖物 前言地图类中覆盖物的接口覆盖物类Marker示例Polyline示例Polygon示例Arc示例Circle示例Text示例效果图 Marker的更多属性常用属性交互碰撞动画其它属性 折线的更多属性常用属性交互其它 多边形的更多属性常用属性交互其它 Arc的更多属…

Rust 错误处理

Rust 错误处理 Rust 是一种系统编程语言,以其内存安全、高并发和实用性而著称。在 Rust 中,错误处理是一个核心概念,它通过提供 Result 和 Option 类型来鼓励开发者显式地处理可能出现的错误,而不是依赖异常机制。本文将深入探讨 Rust 中的错误处理机制,包括 Result 和 O…

LeetCode //C - 316. Remove Duplicate Letters

316. Remove Duplicate Letters Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. Example 1: Input: s “bcabc”…

动态规划(算法篇)

算法之动态规划 动态规划(dp) 概念: 将递归算法重新写成非递归算法,让后者把那些子问题的答案系统地记录在一个表(dp数组)内,这种方法叫做动态规划通常用于求解具有最优性质的问题(最优子结构&最优子问题),希望找到具有最优…

数据结构队列的单链表实现

1.Queuec.h头文件函数名 #pragma once #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h> typedef int QDataType; typedef struct QueueNode {QDataType data;struct QueueNode* next; }QNode; typedef struct Queue {Q…

MySQL中处理JSON数据:大数据分析的新方向,详解与示例

文章目录 1. MySQL中的JSON数据类型2. JSON函数和运算符3. 创建JSON列的表4. 插入JSON数据5. 查询JSON数据6. 复杂查询和聚合7. JSON 数据的索引8. 总结 在当今的大数据时代&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&a…

【测试用例设计方法】错误猜测法

1.错误推测法的概念 错误推测法就是基于经验和直觉推测程序中所有可能存在的各种错误&#xff0c;有针对性地设计测试用例的方法。 2.错误推断法的基本思想 列举出程序中所有可能有的错误和容易发生错误的特殊情况&#xff0c;根据它们选择测试用例。 3. 错误推测法的应用案例 …

Linux命令更新-网络管理

引言 Linux系统作为一个灵活且强大的操作系统&#xff0c;其网络管理功能也是非常丰富的。本文将深入探讨Linux中常用的网络管理命令&#xff0c;包括ifconfig、ip、route等&#xff0c;并结合实例演示其用法和功能&#xff0c;旨在帮助读者更全面地掌握Linux网络配置与管理。…