01 数据库的三大范式
每个列不可以再拆分
非主键列完全依赖于主键,不能是依赖于主键的一部分
非主键列只能依赖于主键, 不依赖于其他非主键
02 MySQL有关权限的表有哪几个
MySQL服务通过权限表控制用户对数据库的访问,权限表存放在 mysql 数据库
user表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的
db表:记录各个帐号在各个数据库上的操作权限
table_priv表:记录数据表级的操作权限
columns_priv表:记录数据列级的操作权限
03 事务的四大特性(ACID)
原子性:事务内的操作要么全部执行,要么全部不执行
一致性: 事务执行前后,数据应保持一致
隔离性:多个事务执行过程中互不影响
持久性:事务提交后,对数据的改变是持久的
04 索引设计原则
适合索引的列应是经常出现在where字句中的条件列
基数较小的列索引效果越差,没必要加索引,如性别
使用短索引,若要对长字符串列进行索引,应指定一个前缀长度,可以节省大连索引空间
不要过度索引,索引需要额外的磁盘空间,在修改表内容的时候,索引会更新甚至重构,索引列越多,这个时间越长,建议一个表索引不要超过5个,
05 什么是死锁,怎么解决死锁
死锁是指两个或多个事务互相持有对方需要的锁,导致它们都无法继续执行的情况
常见场景:
事务A => 先锁定资源 X,尝试获取资源 Y
事务B => 先锁定资源 Y,尝试获取资源 X
造成结果:双方都无法释放自己持有的锁,也无法获取对方持有的锁,导致死锁
解决方式:
1.设置合理的锁等待超时时间
参数 innodb_lock_wait_timeout(默认50秒):当事务等待锁超过设定时间后,自动回滚当前语句(非整个事务)。
参数 innodb_rollback_on_timeout(默认OFF):设置为 ON 时,超时后回滚整个事务。
-- 设置锁等待超时为20秒
SET GLOBAL innodb_lock_wait_timeout = 20;
2.保持事务简短
尽量缩短事务执行时间,减少锁的持有时间。
避免在事务中执行复杂逻辑
3.按顺序访问资源
确保所有事务以相同的顺序访问表和行。
反例:事务A先更新表1再更新表2,事务B先更新表2再更新表1 → 易死锁。
正例:所有事务统一先更新表1,再更新表2。
4.降低隔离级别
将隔离级别从 SERIALIZABLE(串行化) 或 REPEATABLE READ(可重读读) 改为 READ COMMITTED(读已提交),减少锁的竞争范围
-- 设置隔离级别为READ COMMITTED
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
5. 业务处理不好可以用分布式事务锁或者使用乐观锁
6. 优化索引:确保所有查询都使用索引,避免全表扫描导致的锁表冲突。
06 什么是脏读?幻读?不可重复读?
脏读(Drity Read):
某个事务已更新一份数据,另一个事务在此时读取了同一份数据,
由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
不可重复读(Non-repeatable read):
在一个事务的两次查询之中数据不一致,
可能是两次查询过程中间,其他事务更新了原有的数据。
幻读(Phantom Read):
在一个事务的两次查询中数据笔数不一致,
例如有一个事务查询了几行数据,另一个事务却在此时插入了新的几列数据
先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
07 视图有哪些特点?
视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系。
视图是由基本表(实表)产生的表(虚表)。视图的建立和删除不影响基本表。
对视图内容的更新(添加,删除和修改)直接影响基本表。
当视图来自多个基本表时,不允许添加和删除数据。
视图的操作包括创建视图,查看视图,删除视图和修改视图。
08 SQL的生命周期?
1.应用服务器与数据库服务器建立一个连接
2.数据库进程拿到请求sql
3.解析并生成执行计划,执行
4.读取数据到内存并进行逻辑处理
5.通过步骤一的连接,发送结果到客户端
6.关掉连接,释放资源
09 主键使用自增ID还是UUID
推荐使用自增ID,不要使用UUID。
在InnoDB存储引擎中,主键索引是作为聚簇索引存在的
主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可
如果是UUID由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,导致产生很多的内存碎片,造成插入性能的下降。
在数据量大一些的情况下,用自增主键性能会好一些。
如果没有主键,InnoDB会选择一个唯一键来作为聚簇索引,如果没有唯一键,会生成一个隐式的主键。
10 MySQL主从复制解决了哪些问题?
主数据库出现问题,可以切换到从数据库
可以进行数据库层面的读写分离
可以在从数据库上进行日常备份
负载均衡:降低单个服务器的压力
高可用和故障切换:帮助应用程序避免单点失败