什么是数据库的三大范式
- 字段不可拆分
- 除了主键之外的其他字段必须完全依赖主键而不能依赖主键的某一部分
- 除了主键之外的其他字段必须直接依赖主键而不能间接依赖主键
数据库中的Join
inner join返回两张表中有匹配关系的行 左外连接返回左侧表所有的行和即使在右表中没有存在也会返回,未匹配的右表列设置为NULL 右外连接也是同样的道理 MySQL中没有一个关键字是全连接,但是可以用union配合right join和left join来实现
Redis是单线程为什么依旧很快
- 基于内存
- 单线程设计
- 避免上下文切换带来的性能开销
- 单线程无需加锁不会出现锁问题,不会加锁释放锁占用资源
- IO多路复用
这里"多路"指的是多个网络连接,"复用"指的是复用同一个线程。Redis会打开一个监听套接字,等待客户端连接。一旦客户端连接上,Redis会将这个连接加入到监听列表。Redis的主线程通过epoll机制,监控这些连接的可读或者可写事件,当有某个线程具备可写或者可读的状态时,就会立刻处理。
慢SQL优化
- 字段类型转化,比如INT转为VARCHAR或者VARCHAR转为INT都会导致原来的索引失效。因为索引是基于原来的数据类型构建的。(类型转换)
- 使用了截取函数或者类型转换函数的字段不会走索引,比如:
SELECT * FROM user WHERE SUBSTR(name, 1, 1) = '张'我们并没有对SUBSTR(name, 1, 1)这个字符串建立对应的索引,尽管我们对name添加了索引,也会导致索引失效。(字段改变) - 不要在字段前面进行加减运算。(字段改变)
- like模糊匹配%在前无法使用索引
- 范围条件在联合索引中的位置,决定了索引能用到多少个字段。 假设创建联合索引
idx_name_age_score(name, age, score),通过 3 个案例看索引使用情况:
案例 1:范围条件在联合索引的 "第一个字段"(最左侧)
查询语句:SELECT * FROM student WHERE name > '张三' AND age = 20 AND score = 90
- 索引使用情况:仅能用到联合索引的第一个字段
name(范围匹配),age和score因name是范围条件而失效,无法走索引。 - 原因:最左侧字段已用范围,后续字段失去 "左前缀匹配" 的基础,无法继续匹配。
案例 2:范围条件在联合索引的 "中间字段"
查询语句:SELECT * FROM student WHERE name = '张三' AND age > 20 AND score = 90
- 索引使用情况:能用到联合索引的前两个字段
name(精确匹配)和age(范围匹配),score因age是范围条件而失效。 - 原因:
name精确匹配满足左前缀,age可范围匹配,但age之后的score无法继续利用索引。
案例 3:范围条件在联合索引的 "最后一个字段"
查询语句:SELECT * FROM student WHERE name = '张三' AND age = 20 AND score > 90
- 索引使用情况:能用到联合索引的所有三个字段
name(精确)、age(精确)、score(范围),全量走索引。 - 原因:前两个字段均为精确匹配,满足左前缀,最后一个字段的范围条件不影响左侧字段的索引使用,仅自身范围匹配。
- 不要使用Select* 、不要使用降序排序、不要使用or
- order by和group by的字段要建立索引
聚簇索引和非聚簇索引
在 MySQL 的 InnoDB 引擎中,每个索引都会对应一颗 B+ 树,而聚簇索引和非聚簇索引最大的区别在于叶子节点存储的数据不同,聚簇索引叶子节点存储的是行数据,因此通过聚簇索引可以直接找到真正的行数据;而非聚簇索引叶子节点存储的是主键信息,所以使用非聚簇索引还需要回表查询,因此我们可以得出聚簇索引和非聚簇索引的区别主要有以下几个:
- 聚簇索引叶子节点存储的是行数据;而非聚簇索引叶子节点存储的是聚簇索引(通常是主键 ID)。
- 聚簇索引查询效率更高,而非聚簇索引需要进行回表查询,因此性能不如聚簇索引。
- 聚簇索引一般为主键索引,而主键一个表中只能有一个,因此聚簇索引一个表中也只能有一个,而非聚簇索引则没有数量上的限制。
数据库的索引是存储在内存中的还是存储在硬盘中的呢
MySQL 的索引主要存储在硬盘中 ,但会根据访问频率和内存情况,将部分热点索引加载到内存(缓冲池)中加速访问。这种 "硬盘存储为主、内存缓存为辅" 的设计,是由数据库的核心需求(数据持久化、支持海量数据)决定的
什么情况下必须要用ElasticSearch来替代MySQL的查询呢
-
一个任务管理系统,如果我要将查询的结果按照多个字段的相似度排序,就需要用到ES,比如搜索"预营销"这个关键字可能出现在任务的标题或者出现在任务的描述等不同的字段,每个字段有不同的优先级,我要根据优先级的高低返回数据,这里就需要用到ES。
-
多维聚合指 "按多个维度(如时间、地区、品类)统计数据,生成报表或实时看板",MySQL 虽支持聚合(
GROUP BY),但在大数据量、多维度场景下性能完全跟不上 ES:- 多维度聚合(如
GROUP BY 任务部门, 任务优先级, 任务开始时间)需多次扫描表或临时表,数据量超过 100 万时,查询耗时可能从秒级变为分钟级; - 不支持 "实时聚合"(如任务优先级需要实时看板需每秒更新 "最高优先级的 Top10任务",MySQL 频繁
GROUP BY会占用大量 CPU,导致业务卡顿); - 聚合结果无法缓存,重复查询需重复计算,效率低。
- 多维度聚合(如