MySQL进阶基础:索引、视图、存储过程与常用函数
一、索引基础MySQL的“查询加速器”刚开始用MySQL的时候可能大家都有这样的感受表数据少的时候查询速度飞快但一旦数据量涨到几千、几万条查询就变得慢吞吞。这时候索引就该登场了——它就像书籍的目录能帮MySQL快速定位到目标数据不用逐行扫描全表大大提升查询效率。1. 索引的核心认知首先要明确索引不是“万能的”它有优势也有弊端我们要合理使用而不是盲目创建。定义索引是MySQL中一种特殊的数据结构它关联着表中的一列或多列数据能快速找到对应的数据行无需扫描整个表。优势最核心的作用就是提升查询效率尤其是在大数据量的表中效果会非常明显比如从“扫描10万行”变成“扫描10行”。弊端索引会占用额外的存储空间而且每次对表进行插入、修改、删除操作时MySQL都要同步更新索引会降低这些操作的效率。所以不是索引越多越好按需创建才是关键。2. 常用索引类型及使用场景MySQL的索引类型有很多新手重点掌握以下4种就能覆盖大部分基础场景主键索引PRIMARY KEY最常用、最特殊的索引每张表只能有一个主键索引主键字段的值必须唯一且非空比如学生表的“学号”。创建表时只要指定主键MySQL会自动创建主键索引无需手动操作。唯一索引UNIQUE用于保证字段的值唯一但允许为空比如用户表的“手机号”“邮箱”。如果插入的数据与已有数据重复会报错适合用来避免重复数据。普通索引INDEX最基础的索引没有任何约束仅用于提升查询效率。适合在查询频率高、但没有主键/唯一约束的字段上创建比如商品表的“商品名称”。联合索引由多个字段组合而成的索引比如“姓名手机号”适合多字段联合查询的场景。注意联合索引遵循“最左前缀原则”查询时要尽量匹配左边的字段才能触发索引。3. 索引的基础操作实操必备掌握以下3个核心操作就能轻松管理索引新手直接复制语法替换表名、字段名即可使用创建索引CREATE INDEX索引名 ON 表名(字段名);普通索引如果是唯一索引用 CREATE UNIQUE INDEX 索引名 ON 表名(字段名);删除索引DROP INDEX索引名 ON 表名;注意主键索引不能用这个语法要删除主键索引需先删除主键约束。查看索引SHOW INDEX FROM表名;能查看表中所有索引的详细信息包括索引类型、关联字段等。--实操案例假设我们有一张学生表student包含字段学号id主键、姓名name、手机号phone实操如下 --1. 给name字段创建普通索引 CREATE INDEX idx_student_name ON student(name); --2. 给phone字段创建唯一索引 CREATE UNIQUE INDEX idx_student_phone ON student(phone); --3. 查看student表所有索引 SHOW INDEX FROM student; --4. 删除name字段的普通索引 DROP INDEX idx_student_name ON student;二、视图简化查询的“虚拟表”在实际开发中我们经常会遇到一些复杂的查询——比如多表连接、聚合查询每次都要写长长的SQL语句既麻烦又容易出错。这时候视图就能帮我们“偷懒”它就像一个“虚拟表”把复杂的查询结果保存起来后续查询直接调用视图即可不用重复写复杂SQL。1. 视图的核心作用简化查询将复杂的SQL多表连接、子查询等封装成视图后续查询只需执行“SELECT * FROM 视图名”大大减少代码量。隐藏敏感数据比如员工表中有“工资”“身份证号”等敏感字段我们可以创建视图只展示“姓名”“部门”等非敏感字段避免敏感数据泄露。统一查询逻辑如果多个场景需要用到相同的复杂查询只需创建一个视图所有场景统一调用后续修改查询逻辑时只需修改视图无需修改所有相关代码。2. 视图的基础操作视图的操作和普通表类似但要注意视图是“虚拟表”它本身不存储数据数据来源于底层的真实表修改视图的数据会同步修改底层表的数据反之亦然。创建视图CREATE VIEW 视图名 AS 复杂查询语句;比如CREATE VIEW v_student_course AS SELECT 学生.姓名, 课程.课程名 FROM 学生 JOIN 课程 ON 学生.学号课程.学号;查询视图和查询普通表完全一样SELECT * FROM 视图名; 也可以添加WHERE、ORDER BY等条件。修改视图ALTER VIEW 视图名 AS 新的查询语句;当底层表结构变化或查询逻辑需要调整时使用。删除视图DROP VIEW 视图名;删除视图不会影响底层的真实表数据只是删除这个“虚拟表”的定义。--实操案例基于student表学号id、姓名name、班级class和score表学号id、课程名course、分数score实操如下 --1. 创建视图查看各学生的姓名、班级和对应课程分数 CREATE VIEW v_student_score AS SELECT s.name, s.class, sc.course, sc.score FROM student s JOIN score sc ON s.id sc.id; --2. 查询视图 SELECT * FROM v_student_score WHERE score 80;查询分数大于80的学生信息 --3. 修改视图新增“及格状态”字段 ALTER VIEW v_student_score AS SELECT s.name, s.class, sc.course, sc.score, IF(sc.score 60, 及格, 不及格) AS pass_status FROM student s JOIN score sc ON s.id sc.id; --4. 删除视图 DROP VIEW v_student_score;3. 视图与表的核心区别这里用一句话区分表是真实存储数据的视图是基于表的查询结果不存储数据。简单来说表是“仓库”视图是“仓库的镜子”——镜子能看到仓库里的东西但本身不存放东西镜子里的内容会随着仓库的变化而变化。三、存储过程与函数封装重复逻辑的“工具”如果我们需要反复执行一段相同的SQL逻辑比如批量插入数据、复杂的计算每次都写一遍代码不仅繁琐还容易出错。存储过程和函数就是用来解决这个问题的——它们能将重复的SQL逻辑封装起来像“函数”一样调用提升开发效率还能保证逻辑的一致性。1. 存储过程基础存储过程是一组预先编译好的SQL语句的集合它可以接收参数、执行复杂的逻辑比如循环、判断适合处理批量操作、复杂业务逻辑。核心作用封装重复逻辑减少代码冗余提高执行效率存储过程预先编译每次调用无需重新编译增强代码的可维护性修改逻辑只需修改存储过程无需修改所有调用处。基础操作创建CREATE PROCEDURE 存储过程名(参数) BEGIN SQL语句集合; END;调用CALL 存储过程名(参数);存储过程不能直接用SELECT调用必须用CALL删除DROP PROCEDURE 存储过程名;实操案例--创建一个存储过程批量插入3条学生数据到student表实操如下 --1. 创建存储过程 CREATE PROCEDURE add_student_batch() BEGIN INSERT INTO student(id, name, class) VALUES(101, 张三, 高一(1)班), (102, 李四, 高一(2)班), (103, 王五, 高一(1)班); END; --2. 调用存储过程 CALL add_student_batch(); --3. 删除存储过程 DROP PROCEDURE add_student_batch;2. 函数基础函数和存储过程类似也是封装SQL逻辑但它有一个核心区别函数必须有返回值而存储过程可以没有返回值。函数适合用于数据计算、数据转换等场景比如计算两个日期的差值、拼接字符串。基础操作创建CREATE FUNCTION 函数名(参数) RETURNS 返回值类型 BEGIN SQL语句; RETURN 返回值; END;调用SELECT 函数名(参数);函数可以直接用在SELECT语句中因为它有返回值删除DROP FUNCTION 函数名;实操案例--创建一个函数根据学生分数返回评级90优秀、80-89良好、60-79及格、60以下不及格实操如下 --1. 创建函数 CREATE FUNCTION get_score_grade(score INT) RETURNS VARCHAR(20) BEGIN DECLARE grade VARCHAR(20); IF score 90 THEN SET grade 优秀; ELSEIF score 80 THEN SET grade 良好; ELSEIF score 60 THEN SET grade 及格; ELSE SET grade 不及格; END IF; RETURN grade; END; --2. 调用函数 SELECT name, score, get_score_grade(score) AS grade FROM student s JOIN score sc ON s.id sc.id; --3. 删除函数 DROP FUNCTION get_score_grade;3. 存储过程与函数的核心区别新手必区分对比维度存储过程函数返回值可以没有返回值也可以有多个返回值必须有且只有一个返回值调用方式用CALL调用不能用在SELECT中用SELECT调用可以嵌入在SQL语句中适用场景复杂业务逻辑、批量操作比如批量插入、批量更新数据计算、数据转换比如日期计算、字符串处理四、常用函数MySQL的“实用小工具”在日常查询和数据处理中我们经常需要对数据进行转换、计算比如拼接字符串、计算日期差、四舍五入MySQL内置了很多常用函数不用我们自己写复杂逻辑直接调用即可。1. 字符串函数最常用用于处理字符串类型的数据比如拼接、截取、转换大小写等常用的有CONCAT(字符串1, 字符串2)拼接两个或多个字符串比如CONCAT(Hello, MySQL) → HelloMySQL。SUBSTR(字符串, 起始位置, 长度)截取字符串比如SUBSTR(MySQL学习, 1, 5) → MySQL。TRIM(字符串)去除字符串前后的空格比如TRIM( MySQL ) → MySQL。LOWER(字符串)将字符串转换为小写UPPER(字符串)将字符串转换为大写。2. 日期函数高频使用用于处理日期和时间类型的数据比如获取当前时间、格式化日期、计算日期差等常用的有NOW()获取当前的日期和时间格式YYYY-MM-DD HH:MM:SS。CURDATE()获取当前日期格式YYYY-MM-DDCURTIME()获取当前时间格式HH:MM:SS。DATE_FORMAT(日期, 格式)格式化日期比如DATE_FORMAT(NOW(), %Y年%m月%d日) → 2026年04月12日。DATEDIFF(日期1, 日期2)计算两个日期的差值返回天数日期1 - 日期2。3. 数值函数基础必备用于处理数值类型的数据比如四舍五入、取整等常用的有ROUND(数值, 小数位数)四舍五入比如ROUND(3.1415, 2) → 3.14。CEIL(数值)向上取整比如CEIL(3.1) → 4FLOOR(数值)向下取整比如FLOOR(3.9) → 3。MOD(数值1, 数值2)取余数比如MOD(10, 3) → 1。实操案例--基于student和score表直接调用常用函数查看效果 --1. 字符串函数 SELECT CONCAT(name, -, class) AS 学生信息 FROM student;拼接姓名和班级 --2. 日期函数 SELECT name, score, DATE_FORMAT(NOW(), %Y年%m月%d日) AS 查询时间 FROM score WHERE score 80;添加查询时间 --3. 数值函数 SELECT score, ROUND(score/10, 1) AS 十分制分数, MOD(score, 10) AS 个位数分数 FROM score;