news 2026/3/12 23:51:55

MySQL笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL笔记

条件:创建学生表与老师表

-- 1.0 创建学生的表,并添加数据createtablestudent(stu_idintprimarykey,stu_namevarchar(5)notnullunique,stu_ageintnotnull);insertintostudent(stu_id,stu_name,stu_age)values(24,"小明",18);insertintostudent(stu_id,stu_name,stu_age)values(25,"小王",19);insertintostudent(stu_id,stu_name,stu_age)values(26,"小张",20);insertintostudent(stu_id,stu_name,stu_age)values(27,"小黄",21);insertintostudent(stu_id,stu_name,stu_age)values(28,"小红",22);select*fromstudent;-- 2.0 创建老师表createtableteacher(tea_idintprimarykey,tea_namevarchar(5)notnullunique,tea_ageintnotnull);insertintoteacher(tea_id,tea_name,tea_age)values(1,"王老师",40);insertintoteacher(tea_id,tea_name,tea_age)values(2,"黄老师",41);insertintoteacher(tea_id,tea_name,tea_age)values(3,"张老师",42);insertintoteacher(tea_id,tea_name,tea_age)values(4,"李老师",43);insertintoteacher(tea_id,tea_name,tea_age)values(5,"丁老师",44);

一 : 增删改查

1.0 数据库的增删改查

-- 使用数据库: useuse数据库的名字;-- 1.0 增 create-- 语法:createdatabase数据库的名字;-- 列子;createdatabasedb_text190-- 2.0 删除数据库 drop-- 语法:dropdatabaseifexists数据库的名字;-- 列子dropdatabasedb_text1;dropdatabaseifexistsdb_text1;-- 3.0 改 : 一般修改数据库的字符集 alteralterdatabase数据库的名字charactersetutf8;-- 4.0 查询数据库 showshowdatabases;

2.0 数据库的表的增删改查

-- 1.0 增 create-- 语法:createtable表的名字(字段 类型(长短)约束,);-- 常见的类型int数值类型char不可变字符串varchar可变字符串-- 常见的字段primarykey主键,也就是相当与非空加上不可重复约束notnull非空约束unique不可重复约束-- 列子: 创建一个学生表,createtablestudent(stu_namevarchar(5)notnullunique,stu_ageintnotnull,stu_genderchar(2)notnull);-- 2.0 删除数据表 drop-- 语法:droptableifexists表的名字;-- 列子:droptableifexistsstudents;-- 3.0 修改: alter-- 语法 :altertable表的名字 改的类型 ;-- 改的类型:renametosetadddropchangemodify-- 列子:-- 1.0 将我们的学生表的名字改为老师的名字altertablestudentrenametoteacher;-- 2.0 将我们表的字符集进行修改altertablestudentcharactersetutf8;-- 3.0 添加字段altertablestudentaddstu_genderchar(2)notnull;-- 4.0 修改字段(这里修改整个字段)altertablestudent change stu_name stu_heightdoublenotnull;-- 5.0 修改字段(这里修改的是我们字段类型)altertablestudentmodifystu_agedouble;-- 6.0 删除字段altertablestudentdropstu_age;# 4.0 查showtables; 查询所有的数据表desc表的名字; 查询表的结构

3.0 表中的数据增删改查

-- 1.0 插入数据-- 语法:insertinto表的名字(各个类型)values(各个数据)-- 列子: 向我们的学生表中添加数据insertintostudent(stu_id,stu_name,stu_age)values(24,"小明",18);-- 2.0 删除数据-- 语法:deletefrom表的名字where条件;like这个关键字进行模糊匹配-- 列子:-- 1.0 删除我们表中性别全为男的数据deletefromstudentwherestu_gender='男'-- 2.0 删除我们表中年龄大于20的数据deletefromstudentwherestu_age>20;-- 3.0 改-- 语法:updata.....set.....-- 列子 :-- 1.0 将我们学生的id=24 的学生的姓名改成王五updatestudentsetstu_name="王五"whereid=24;-- 2.0 将id=23 的学生性别修改为'女' 并且他的名字修改为'李四'updatestudentsetstu_gender="女",stu_name="李四"whereid=23;-- 4.0 查-- 语法:selectfrom表的名字where/like条件;-- 列子:-- 1.0 查询我们表中的所有的数据 *select*fromstudent;-- 2.0 查询我们学生表中所有男生的数据select*fromstudentwherestu_gender='男'-- 3.0 查询我们学生表中年龄大于20的数据select*fromstudentwherestu_age>20;-- 4.0 查询我们学生表中学生名字包含字母0的数据 %select*fromstudentwherestu_name="%o%";-- 5.0 查询我们学生表中姓名第二个字母为o 的信息select*fromstudentwherestu_name="_o%";-- 6.0 查询我们学生表中表中的第一个字母为o 的信息select*fromstudentwherestu_name="o%";-- 7.0 查询学生姓名第一个字为'张'的学生信息select*fromstudentwherestu_name="张%";-- 8.0 查询我们表中女生并且女生的年龄大于20 的数据 || 表示或 && 表示并且select*fromstudentwherestu_gender="女"&&stu_age>20;

4.0 总结

数据库数据库中的表数据库中表的数据
createcreateinsert into
dropdropdelete from
alteralterupdate … set
showshowselect … from

二 : 查询的扩展

1.0 字段与函数

-- 1.0 as: 对我们的字段取别名-- 列子-- 1.0 查询表中的出生日期是多少,并命名selectstu_name,2025-stu_ageas出生日期fromstudent;-- 2.0 distinct 消除重复行-- 将我们表中年龄重复的行消除selectdistinctstu_agefromstudent;-- 3.0 order by : 排序 , 升序用asc ,降序用desc-- 列子:-- 1.0 将我们表中的数据按照年龄进行升序排列select*fromstudnetorderbystu_genderasc;-- 2.0 先按照性别升序排列,然后性别相同的 按照年龄降序排列select*fromstudentorderbystu_genderasc,stu_agedesc;-- 4.0 聚合函数count(): 统计总数max(): 最大值min(): 最小值sum(): 总数avg(): 平均值-- 列子-- 1.0 统计学生的总数selectcount(stu_name)fromstudent;-- 2.0 统计性别为男的总数selectcount(stu_name)wherestu_gender='男'fromstudent;-- 3.0 统计表中年龄的最大值selectmax(stu_age)fromstudent;-- 4.0 计算学生年龄的总和selectsum(stu_age)fromstudent;-- 5.0 日期函数sysdate()获取当前时间now()获取当前时间selectsysdate();selectnow();-- 列子: 向我们表中插入时间,时间就用我们当前的时间insertintostudent(stu_name,stu_time)values("小明",now());-- 6.0 字符串函数concat(字段1,字段2...): 将我们字符串拼接成多列 upper(): 将字段中的值转换成大写 lower();将我们的字段转换成小写的 substring(字段,开始,截取的长短): 将我们的字符串进行截取-- 1.0 列: 将我们学生表中的学生的姓名和学生的性别拼接在一起selectconcat(stu_name,'-',stu_age)fromstudent;-- 2.0 列: 将我们学生表中的英文名字 转换成大写的selectupper(stu_name)fromstudent;-- 3.0 列: 将我们学生表中的电话号码 从第5位进行截取, 截取4位selectsubstring(stu_tel,5,4)fromstudent;

2.0 分组查询与分页查询

-- 1.0 分组查询-- 语法: select 字段 from 表名 group by 字段;-- 列:-- 1.0 先对查询的学生信息按性别进行分组 , 然后统计每一组学生的个数selectstu_gender,count(stu_num)fromstusgroupbystu_gender;-- 2.0 对查询的学生的信息 按照性别进行分组 ,然后统计每一组的平均年龄selectstu_gender,avg(stu_age)fromstusgroupbystu_gender;-- 3.0 将我们学生的年龄进行分组(16,17,18,19 四组) , 统计每一组学生的个数 ,并进行排序selectstu_age,count(stu_num)fromstusgroupbystu_ageorderbystu_age;-- 4.0 学生按照年龄进行分组,统计每一组的人数, 筛选出当组人数大于1 的组, 再按照年龄升序显示出来selectstu_age,count(stu_num)fromstusgroupbystu_agehavingcount(stu_num)>1orderbystu_age;-- 5.0 查询性别 位'男' 的学生, 按照年龄进行分组, 然后分别统计每组的人数, 再筛选出当前组人数 >1 的组 ,再按年龄升序显示出来selectstu_age,count(stu_num)fromstuswherestu_gender='男'groupbystu_agehavingcount(stu_num)>1orderbystu_age;
-- 2.0 分页查询当数据表中的记录比较多的时候,如果一次性全部查询出来显示给用户,用户的可读性/体 验性就不太好,因此我们可以将这些数据分页进行展示1.0分页查询怎么实现?(MySQL 实际语法) MySQL 使用关键字:LIMIToffset,sizeoffset:从第几条开始 size:查多少条(每页多少条)2.0案例: 🔹2.1.查询前10条(第一页)SELECT*FROMstudentLIMIT0,10;意思:从第0条开始,查10条。 🔹2.2查询第二页(假设每页10条) 第二页offset=(page-1)*size=(2-1)*10=10SELECT*FROMstudentLIMIT10,10;🔹2.3第 N 页的通用写法SELECT*FROMstudentLIMIT(page-1)*pageSize,pageSize;如果你页面传 page=3,pageSize=10SELECT*FROMstudentLIMIT20,10;3.0面试官常问:分页为什么要用LIMIT? 你可以这样回答:LIMIT只取一小段数据,避免扫描太多行,提高查询效率。4.0再加一个企业常用分页(带排序)SELECT*FROMstudentORDERBYstu_idDESCLIMIT20,10;5.0面试加分题:分页查询慢怎么优化? 给排序字段加索引(最重要) 使用覆盖索引

注意:SQL语句书写和执行顺序 书写:select、form、where、group by、having、order by、limit 执行:from、where、group by、having、select、order by、limit (后续还会学到join,那么它的优先级要高于form)

3.0 数据表的关联关系与外键约束

关联关系:

​ 通过关联关系, 我们可以建立 表与表之间的关系。

​ 常见的关联关系 : 一对一 ,一对多, 多对一 ,多对多

外键约束

-- 1.0 概念:就是一张表的外键与另一张表的主键进行关联-- 2.0 创建一个班级表,其中含有id,namecreatetableclass(idintprimarykeyauto_increment,namechar(10)notnullunique,);-- 3.0 创建一个学生表,其中有name,gender,age,cid,并在外面添加外键约束,使得班级表中的id与学生表中的cid进行关联createtablestudent(namechar(5)primarykey,genderchar(2)notnull,ageint,cidint;);altertablestudentaddconstraintcl_stforeignkey(cid)referencesclass(id);altertable添加外键约束表的名字addconstraint自己起的关联的名字foreignkey(列的名字)references表的名字(关联字段);-- 4.0 添加数据insertintoclass(id,name)values(1,"java001班");insertintoclass(id,name)values(2,"java002班");insertintostudent(name,gender,age,cid)values("小明""男",18,1);insertintostudent(name,gender,age,cid)values("小王","女",18,1);insertintostudent(name,gender,age,cid)values("小潘","男",19,2);-- 5.0 进行查询select*fromclass;select*fromstudent;

级联操作

-- 1.0 注意:我们的班级表 现在和学生表进行关联了,我们不可以直接进行修改班级表中的信息, 比如:updateclasssetid=5wherename="java001班"; 我们想要将java001班的id修改成5,这样直接进行修改是不对的。-- 2.0 方法一:三步走修改关联班级表中的id第一:将我们的学生表中的cid全部修改成NULLupdatestudentsetcid=NULLwherecid=1;第二:修改班级表中的idupdateclasssetcid=5wherename="java001班"; 第三:将我们学生表中的cid=NULL值进行改回来updatestudentsetcid=5wherecidisNULL;

4.0 连接查询与子查询

介绍与前提的数据准备

-- 1.0 创建班级信息表,并添加数据createtableclass(idintprimarykey,`name`varchar(50)notnull;);insertintoclass(id,`name`)values(1,"java班级");insertintoclass(id,`name`)values(2,"运维班级");insertintoclass(id,`name`)values(3,"python大数据班级");-- 2.0 创建学生信息表,添加外键使得其中的cid与class中的id进行关联,最后并添加数据createtablestudent(namevarchar(5),-- 注意这里不可以用name作为主键ageintnotnull,genderchar(1)notnull,cidint);altertablestudentaddconstraintst_clforeignkey(cid)referencesclass(id);insertintostudent(name,age,gender,cid)values("小明",18,"男",1);insertintostudent(name,age,gender,cid)values("小王",18,"女",2);insertintostudent(name,age,gender,cid)values("小潘",19,"男");insertintostudent(name,age,gender,cid)values("小小",19,"女");-- 3.0 inner join 内连接 :就是两张表联合进行查询,但是只能是显示相互对应共同的部分语法:select*from1的名字innerjoin2的名字where1的名字.列名=2的名字.与其关联的名字select*fromstudentinnerjoinclasswherestudent.cid=class.id;-- 4.0 左连接和右连接查询select*fromstudentrightjoinclasswherestudent.cid=class.id;select*fromstudentleftjoinclasswherestudent.cid=class.id;

左连接和右连接(left join ,right join)

1. 左连接(LEFT JOIN)

左连接是:以左表为主,先取左表全部数据,再匹配右表;右表匹配不到的用 NULL 补上。

一句话版本(面试最常用):
LEFT JOIN 保留左表全部数据,右表能对上就显示,对不上就 NULL。


2. 右连接(RIGHT JOIN)

右连接是:以右表为主,先取右表全部数据,再匹配左表;左表匹配不到的用 NULL 补上。

一句话版本:
RIGHT JOIN 保留右表全部数据,左表对不上就 NULL。


✅ 你可以举个 5 秒钟的例子(面试官喜欢)

假设两个表:

student

idname
1张三
2李四
3王五

score

idscore
190
380

LEFT JOIN:先保留 student 的全部 → 对不上 NULL

SELECTs.id,s.name,sc.scoreFROMstudent sLEFTJOINscore scONs.id=sc.id;

结果:

idnamescore
1张三90
2李四NULL
3王五80

RIGHT JOIN:先保留 score 的全部 → 对不上 NULL

SELECTs.id,s.name,sc.scoreFROMstudent sRIGHTJOINscore scONs.id=sc.id;

结果:

idnamescore
1张三90
3王五80

student 没有 id=2 的成绩,也不会显示。

三:存储过程

SQL指令的执行过程

编写sql指令——发送给sql服务器——服务器处理sql指令——服务器执行sql指令——整体结果发送给客户端——客户端收到

SQL指令流程中存在的问题

1.0 相同的SQL要重发一样的流程

2.0 如果要一次性执行多个SQL指令,那么第二个指令需要第一个指令的执行结果作为参数

存储过程的介绍

定义:

对完成特点功能的SQL指令集进行封装,客户端直接调用这个名字,直接就可以执行结果

存储过程的优缺点:

优点:

  1. 高性能

    • 预编译执行,减少解析开销。
    • 减少网络传输(多个SQL合并调用)。
  2. 逻辑封装与复用

    • 业务逻辑封装,统一维护,减少代码冗余。
    • 增强数据安全性(通过权限控制隐藏细节)。
  3. 事务控制

    • 方便实现多步骤事务,保证一致性

    缺点:

  4. 调试维护困难

    • 调试工具有限,逻辑复杂时排查效率低。
  5. 移植性差

    • 语法与数据库绑定,迁移到其他数据库(如PostgreSQL)需重写。
  6. 扩展性限制

    • 不利于水平扩展(集群中存储过程可能跨节点问题)。
    • 增加数据库负载,可能成为单点瓶颈。
  7. 版本管理复杂

    • 与应用程序代码分离,需单独管理版本和依赖。

创建,调用存储过程

-- 1.0 语法:createprocedure名字(in/out参数名字)beginsql指令end;-- 2.0 定义一个存储过程来实现两位数的加法createprocedurepro_text1(inaint,inbint,outcint)beginsetc=a+b;-- set 的意思就是定义变量的意思end;-- 3.0 调用存储过程set@m=0;callpro_text1(3,2,@m)select@mfromdual;-- 为啥要从dual 中进行查询

存储过程中变量的使用

-- 1.0 局部变量的定义: 在存储过程的内部,然后用declare开始,定义在存储过程的最开始-- 2.0 定义一个存储过程,变量要使用局部变量,需要实现 a*a+b*2createprocedurepro_text2(inaint,inbint,outcint)begin-- declare a int default 1; 这里为啥不管声明-- declare b int default 2;seta=a*a;setb=b*2;setc=a+b;end;-- 3.0 定义用户变量: 用set 和@ 即可set@m=0;callpro_text2(2,3@m)select@mfromdual;-- 4.0 无论是局部变量还是全局变量,我们都要用set 对变量的值进行修改-- 5.0 查询结果赋值给变量: 用select ... into ... 语句-- 定义一个存储过程,将我们从表中查询到的数据赋值给他,最后并调用这个存储过程createprocedurepro_text3(outcint)beginselectcount(stu_name)intocfromstudents;end;callpro_text3(@n);select@nfromdual;-- 6.0 注意:建议少用用户变量

存储过程中的参数:in / out / inout

-- 1.0 in 参数:输入参数-- 创建一个存储过程来向表中添加学生的信息createprocedurepro_text4(innamechar(5),inageint,ingenderchar(2))beginselectintostudents(stu_name,stu_age,stu_gender)values(name,age,gender)end;callpro_text4("小明",19,"男");-- 2.0 out : 将存储过程的结果,返回给调用者-- 创建存储过程:根据我们学生的学号来查询学生的姓名createprocedurepro_text5(insidvarchar(11),outsnamevarchar(5))beginselectstu_idintosidfrompro_text5wherestu_name=sname;end;set@sname='';callpro_text5('12345',@sname);seltct@snamefromdual;-- 3.0 inout 输入输出参数 :实际中不建议使用

存储过程中的流程控制语句

分支语句

-- 1.0 单分支: if (条件判断 then sql) end if-- 创建一个存储过程,如果变量的值为1 ,那么就表中添加一个数据createprocedurepro_text6(inaint)beginifa=1theninsertintostudents(name,age)values("小潘",19);endif;end;-- 2.0 双分支: if (条件判断 then sql) (else sql ) end if;-- 创建一个存储过程,如果值=1,那么就添加班级数据。否则就添加学生数据createprocedurepro_text7(inaint)beginifa=1theninsertintoclasses(name,num)values("java001",45);elseinsertintostudents(name,age)values("小明",19);endif;end;-- 3.0 case 语句: (case 变量 ) (when 值1 then sql语句) (when 值2 then sql语句) ..... (end case);--createprocedurepro_text8(inaint)begincase2when1thenselectintostudent(name,age)values("小明",19);when2thenselectintoclass(name,num)values("java001",45)endcase;end;

循环语句

-- 1.0 while 循环: (while 条件判断 do sql ) end while-- 创建一个存储过程,用来不断的向班级表中添加数据,且这个数据的数字部分是递增的createprocedurepro_text9(innumint)begindeclareiint;seti=1;whilei<numdoselectintoclass(name,remark)values(concat("java00",i));seti=i+1;endwhile;end;callpro_text9(4);-- 2.0 repeat 循环:和while的区别就是:把条件判断放到了最后,和end repeat 同行,且条件判断的前面加上 untilcreateprocedurepro_text10(innumint)begindeclareaint;seta=1;repeatinsertintoclasses(name,num)values(concat("java00",i));seti=i+1;untile i>numendrepeat;end;callpro_text10(4)-- 3.0 loop 要注意:停止循环时需要结合if语法:(myloop:loopsql)if条件判断leavemyloopendif)(endloop)createprocedurepro_text11(innumint)begindeclareiint;seti=1;myloop:loopselectintoclasses(name,remark)values(concat("java00",i));seti=i+1;ifi=numleavemyloop;endif;endmyloopend;callpro_text11(5)

存储过程管理

# 1.0 查询存储过程(存储过程是在某一个数据库中的,因此查询的时候要结合我们的数据库进行查询)show procedure status where db='mysql'# 查询存储过程的创建细节show create procedure mysql.pro_text1;# 2.0 修改存储过程# 3.0 删除存储过程drop procedure pro_text1

四:触发器和游标

1.0 游标 (Cursor)

简答回答

  • 游标是用于在 MySQL 中逐行处理查询结果的一种机制。它通常用于需要逐条处理数据的场景,尤其是当我们需要处理一组结果集中的每一条记录时。
  • 通过游标,我们可以在查询结果中“指针式”地移动,按需处理每一条数据。

举个例子

  • 假设你有一张订单表,你需要逐条检查每个订单的状态并进行一些计算,游标可以帮助你遍历这些订单进行逐行处理。

2.0 触发器 (Trigger)

简答回答

  • 触发器是一种特殊的存储过程,它会在对数据库表进行插入、更新或删除操作时自动执行。你可以用触发器来自动化一些操作,比如数据验证、日志记录等。
  • 触发器会在指定的操作(如插入、更新、删除)发生之前或之后自动触发,保证在数据变更时执行额外的业务逻辑。

举个例子

  • 比如你有一个员工表,每次更新员工的工资时,你想记录一条工资变动日志。你可以设置一个触发器,在工资更新时自动插入一条变动记录到日志表中。

五:视图

1.0 :概念和作用

概念:

​ 就是一张表或者多张表联合查询得到的一张虚拟表

作用:

​ 安全性: 比如我通过视图,来查询多张表共同的需要的信息。而不是需要全部数据,保护了隐私的数据

​ 简单性:视图结合了多张表的一些共同信息,我们用户查询视图就可以得到这些信息

不会占用数据文件

2.0 :创建视图

-- 1.0 创建视图的语法createview视图的名字AS我们要选择表中的特性-- 2.0 将学生表中的性别为 " 男 " 的信息提取出来,用视图createviewstu_genderASselect*fromstudentwheregender='男'-- 3.0 创建一个视图,里面包含我们的学生表中学生的年龄和 老师表中老师的年龄createviewview_text1asselectstu_agefromstudentunionselecttea_agefromteacher;-- 4.0 查询我们的视图中的内容select*from我们视图的名字;

3.0 :视图数据的特性

查询操作: 在数据表中添加了新的数据,而且这个数据满足创建视图时的查询语句,通过查询视图也可以查询出新的语句。

​ 当删除表中的某一个数据,满足视图的查询标准,那么这个数据也是从我们的视图中进行删除。

新增视图数据:如果在视图中添加数据,那么数据也是被添加到我们的数据表中。

删除视图数据:从视图中删除数据,那么这个数据在我们的数据表中也被删除了。

修改视图数据:通过修改视图中的数据,我们这个数据在数据表中也是被修改了。

4.0:视图的:查看,修改,删除

desc , alter , drop

# 1.0 查询视图的结构:descview_text1;# 2.0 修改视图方式一:用orreplace进行替换createorreplaceviewview_text1ASselect*fromstudentswherestu_gender='女'方式二:alterviewview_text1ASselect*fromstudentswherestu_gender='男'# 3.0 删除视图dropviewview_text1;

六:索引

1.0 :索引的介绍

1.0 为啥会有索引:

当我们数据库中的表超过三百万条的时候,我们就需要设计索引了。

我们数据库的查询速度会随着我们数据量的增多而减缓。索引的出现就是提升我们数据库的查询速度的。

2.0 原理:

查询语句 > 索引(生成树结构) > 查询到我们表中的数据

就是先将我们数据表中的某一些值拿出来构造出一个数据表的目录。 当我们进行查询的时候,在这个目录中找到对应的数据

地址, 然后再根据地址找到我们表中的数据。 避免我们的全表扫描。

2.0 :索引的分类

主键索引:字段为primary key 。 添加这个字段的时候,会自动的生成这个主键索引

唯一索引:字段为 unique 。 添加这个字段的时候,会自动的生成唯一索引

普通索引:普通字段上创建的索引

组合索引:两个以上的字段创建的索引。

3.0:创建索引

# 1.0 创建唯一索引语法: create unique index 索引的名字 on 表的名字(字段的名字)create unique index index_text1 on students(stu_name);# 2.0 创建普通索引create index index_text2 on students(stu_name);# 3.0 创建组合索引create index index_text3 on students(stu_name,stu_id);# 4.0 查询我们的索引show indexfromstudents;

4.0 :查询,删除索引

# 1.0 索引的使用:创建完索引后无需调用,当根据索引的列进行查询的时候,会自动的触发索引。 组合索引需要根据创建所有的所有字段进行查询时触发。# 2.0 查询我们数据表的索引show indexesfromindex_text1;show keysfromindex_text2;# 3.0 删除索引语法: drop index 索引的名字 on 表的名字; drop index index_text1 on student;

5.0 :索引的使用总结

总结

-- 语法的总结想要的作用(index自己定义的index的名字)on表的名字(字段);1.0优点 索引大大降低了数据库服务器在执行查询操作时扫描的数据,提高查询效率 索引可以避免服务器排序,将随机 IO 编程顺序 IO2.0缺点 索引是根据数据表的列创建的,当数据表中数据发生 DML 操作时,索引页需要更新; 索引文件也会占用磁盘空间;3.0注意事项 数据表中数据不多时,全表扫描可能更快些,不要使用索引; 数据量大但是 DML 操作很频繁时,不建议使用索引; 不要在数据重复度高的列上创建索引(性别); 创建索引之后,要注意查询SQL语句的编写,避免索引失效。

七:事务

1.0 :概念的介绍

一个完整业务的多个dml操作就是我们的事务,类比我们的银行进行转账,分为取钱然后扣钱的俩个操作。

就是一个完整的操作,比如完成银行的转钱(由转账和扣钱)。 就是完成一个业务的多个DML操作就是称之为数据库事务。

列子:以我们给别人进行转钱为列子

我们先要进行扣钱,然后再给别人转钱,不能只扣钱或者转钱。数据库事务就是多个操作的集合。

2.0:ACID特性(数据库的四大特性),面试高频

1.0 原子性: 就是多个DML的操作,要么同时成功和要么同时失败。

2.0 一致性:执行前后的数据必须都是一致的

3.0 隔离性:多个数据库事务这个是相互隔离的,互不干扰

4.0 持久性:事务完整之后,对数据库的操作是永久的。

3.0 :事务管理

1.0 自动提交

就是在mysql中,默认的DML指令是自动提交的,当我们执行DML操作的时候,会自动同步到数据库当中

2.0 事务管理

开启我们的事务,就是关闭自动提交。

(1) 执行 start transaction 开启事务

(2) 执行DML操作

(3) 出现异常的话,执行rollback回滚事务

(4) 都执行成功的话,最后commit提交事务

# 1.0 首先创建两张表:库存表和订单表createtabletb_text1(id1intprimarykey,name1varchar(10),num1intnotnull)createtabletb_text2(id2intprimary,name2varchar(10),num2intnotnull)insertintotb_text1(name1,num1)values('键盘',30);insertintotb_text1(name1,num1)values('耳机',40);# 2.0 开启事务starttransaction;# 2.0 减少库存updata tb_text1setnum=num-1wherename='鼠标';selectaaa# 这里一定会报错的# 3.0 增加订单insertintotb_text2(name,num)values('鼠标',1)# 4.0 事务回滚rollback;# 5.0 体检事务commit;

4.0:隔离级别(读未提交,读已提交)

1.0 读未提交

就是脏读:客户端2读出的是客户端1 没有提交的数据。

2.0 读已提交

T2读的是T1提交后的数据,避免了脏读,但是可能出现不可重复读(虚读)

5.0 :隔离级别(可重复读,串行化)

1.0 可重复读

就是T2查询完数据之后,在事务结束之前其他的事务不能对其数据进行修改, 从而避免了不可重复读的情况。但是可能会出现幻读。

2.0 串行化

同时只允许一个事务对我们数据表进行修改,这样就避免了 脏读,虚度,幻读的情况。

6.0:设置 mysql 默认隔离级别

我们可以设置数据库默认的隔离级别来控制事务之间的隔离性。

数据库默认的隔离级别是可重复读

# 1.0 查看数据库默认的隔离级别select@@transaction_isolation;# 2.0 设置mysql默认的隔离级别setsessiontransactionisolationlevel<readcommitted>;会话 事务 隔离 级别

八 : 主从复制和性能优化

1.0 主从复制 (Master-Slave Replication)

简答回答

  • MySQL 的主从复制是指将一个主数据库(Master)的数据实时复制到一个或多个从数据库(Slave)。主数据库处理写操作,而从数据库负责读取操作,从而实现负载均衡和数据冗余。
  • 复制的实现通过二进制日志(binlog)来进行,主数据库将所有修改操作(如 INSERT、UPDATE、DELETE)记录在 binlog 中,从数据库通过读取并执行这些日志来保持数据同步。

举个例子

  • 假设你的网站有很多用户访问,你可以将读操作(查询)分配给从数据库,减轻主数据库的负担,从而提高系统的性能。

常见用途

  • 负载均衡:通过从数据库处理读操作来分担主数据库的压力。
  • 数据备份:从数据库作为主数据库的备份,确保数据的安全性。
  • 高可用性:主从复制可以用于故障转移,在主数据库发生故障时,从数据库可以提升为主数据库。

2.0 性能优化 (Performance Optimization)

简答回答

  • MySQL 性能优化主要包括查询优化、索引优化和服务器配置优化等几个方面,目的是提高查询效率、减少资源消耗和提升系统响应速度。
常见优化方法:
  1. 查询优化
    • 使用EXPLAIN分析查询执行计划,找出查询瓶颈。
    • 避免 SELECT *,只选择需要的字段,减少不必要的数据加载。
    • 优化查询条件,例如将较慢的 LIKE 操作替换为精确的匹配。
    • 分解复杂查询,将一个复杂的查询拆解成多个简单的查询。
  2. 索引优化
    • 为常用的查询条件(如 WHERE、JOIN)添加适当的索引,提高查询速度。
    • 避免过多索引,虽然索引能提高查询效率,但也会增加写入操作的开销。
  3. 缓存优化
    • 使用Query Cache(如果启用),缓存常见的查询结果,减少数据库查询的压力。
    • 使用外部缓存系统(如 Redis、Memcached)来缓存热点数据,进一步减少数据库的负载。
  4. 数据库配置优化
    • 根据硬件资源调整 MySQL 的配置参数(如innodb_buffer_pool_sizequery_cache_size),使数据库能够高效利用系统资源。
    • 调整连接数、线程数等参数,以保证数据库能在高并发下稳定运行。

举个例子

  • 如果一个查询涉及大量数据的 JOIN 操作,可能会导致性能瓶颈。在这种情况下,可以通过优化索引,或者将查询分解成更小的部分来减少数据库的负载。

面试注意:

  • 主从复制的重点是数据的同步和负载均衡,而性能优化的重点是减少查询时间、减少资源消耗和提高系统稳定性。
  • 在提到优化时,可以举出具体的例子,例如通过使用索引提高了查询性能,或者通过主从复制实现了负载均衡等。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/12 19:49:41

【EF Core】FromExpression 方法有什么用?

中没有专门的介绍&#xff08;只在表值函数映射的例子中看到&#xff09;。咱们先来看看此方法的签名&#xff1a;IQueryable<TResult> FromExpression<TResult>(Expression<Func<IQueryable<TResult>>> expression)看着好像很复杂的样子。其实不…

作者头像 李华
网站建设 2026/3/12 23:09:17

Java并发机制的底层实现原理:从CPU到JVM的全面解析

引言&#xff1a;为什么需要了解底层原理&#xff1f;在日常开发中&#xff0c;我们经常使用volatile、synchronized和原子类来解决并发问题。但仅仅会使用这些工具是不够的&#xff0c;只有深入理解它们的底层实现原理&#xff0c;才能在复杂的并发场景中做出正确的技术选型&a…

作者头像 李华
网站建设 2026/3/13 0:25:17

JetBrains Maple Mono字体终极指南:5分钟提升你的编程体验

JetBrains Maple Mono字体终极指南&#xff1a;5分钟提升你的编程体验 【免费下载链接】Fusion-JetBrainsMapleMono JetBrains Maple Mono: The free and open-source font fused with JetBrains Mono & Maple Mono 项目地址: https://gitcode.com/gh_mirrors/fu/Fusion-…

作者头像 李华
网站建设 2026/3/12 21:16:08

3步突破性能瓶颈:Emscripten组件化架构实战指南

你是否正在为C/C项目Web化后的卡顿问题而头疼&#xff1f;初始加载时间过长、内存占用居高不下、交互响应迟缓&#xff0c;这些问题正在阻碍你的应用实现丝滑体验。今天&#xff0c;我们将通过Emscripten的组件化架构方案&#xff0c;带你从问题诊断到解决方案&#xff0c;最终…

作者头像 李华
网站建设 2026/3/13 1:07:18

温度预测实战:PyTorch神经网络建模全流程解析

温度预测实战&#xff1a;PyTorch神经网络建模全流程解析 【免费下载链接】Pytorch-framework-predicts-temperature PyTorch构建神经网络预测气温 项目地址: https://gitcode.com/gh_mirrors/py/Pytorch-framework-predicts-temperature "为什么我的模型预测总是不…

作者头像 李华
网站建设 2026/3/13 1:00:23

Solana 架构深度解析:如何成为 Web3 的性能怪兽?

当其他公链还在为 TPS 过千挣扎时&#xff0c;Solana 已实现每秒数万笔交易。这头"性能怪兽"究竟藏着哪些黑科技&#xff1f;本文将为你拆解其架构设计的精妙之处。 一、突破常规的共识革命 1.1 PoS 的颠覆性进化 Solana 的共识基础仍是 PoS&#xff0c;但通过创新的…

作者头像 李华