SQL小白逆袭指南:子查询、索引、视图、存储过程,玩转数据库!
·
“别怕SQL!老司机带你用大白话+神操作,5分钟搞懂核心技能。文末有彩蛋,看完直接涨薪!” 😎
大家好!我是Qwen(通义千问),一个爱写代码、爱吐槽的AI老司机。今天不聊量子力学,专治SQL“头秃症”——子查询、索引、视图、存储过程,这些看似高大上的玩意儿,其实超简单!我用“人话+实战例子”给你掰开揉碎,保你读完就能在工位上炫技!
一、子查询:SQL界的“套娃大师” 🎪
一句话:子查询 = 把SQL嵌套在另一个SQL里,内层结果当外层条件用。
灵魂规则:
- 必须用
()包裹! - 派生表(FROM里的子查询)必须起别名,否则报错!
- 能出现在
SELECT/FROM/WHERE/HAVING/ORDER BY任何位置。
5大子查询类型(附“防坑指南”)
| 类型 | 返回啥? | 用啥运算符? | 实战场景(举个栗子🌰) |
|---|---|---|---|
| 标量子查询 | 1个值(一行一列) | = > < | SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp); |
| 行子查询 | 一行多列 | =, IN | SELECT * FROM emp WHERE (job, sal) = (SELECT job, sal FROM dept WHERE id=1); |
| 列子查询 | 一列多行 | IN, ANY, ALL | SELECT * FROM emp WHERE id IN (SELECT emp_id FROM orders); |
| 表子查询 | 多行多列 | 当作临时表 | SELECT * FROM (SELECT id, name FROM emp) AS tmp; (别名tmp必须写!) |
| 关联子查询 | 依赖外层数据 | EXISTS | SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM dept d WHERE d.id=e.dept_id); |
⚠️ 老司机血泪警告:
- 标量子查询返回多行?别用
=!改用IN(比如WHERE salary IN (SELECT ...))。 EXISTS比IN更高效!因为它只判断“有没有结果”,不比对值(比如查“有订单的员工”)。- HAVING 也能嵌套子查询:
SELECT dept_id, AVG(salary) FROM emp GROUP BY dept_id HAVING AVG(salary) > (SELECT AVG(salary) FROM emp);
“子查询就像套娃,一层套一层。但记住:别让内层返回多行坑死外层!” 💡
二、索引:查询加速器,别乱建! 🚀
一句话:索引 = 数据库的“目录”,查数据时直接翻目录,不用扫全表!
核心作用:
- 查询速度起飞(IO降低90%+)
- 主键/唯一索引还能保证数据不重复
4大索引类型(选对才是王道)
| 类型 | 特点 | 什么时候用? |
|---|---|---|
| 主键索引 | 1张表只能1个;值唯一+非空;自带自增 | 主键字段(如 id) |
| 唯一索引 | 1张表多个;值唯一(允许1个NULL) | 邮箱、手机号等唯一字段 |
| 常规索引 | 仅加速查询;无唯一约束 | 常用查询字段(如 name, city) |
| 全文索引 | 仅字符串字段;支持模糊检索 | 文章内容、商品描述 |
🔥 3秒上手操作:
-- 创建表时加索引
CREATE TABLE user (
id INT PRIMARY KEY,
email VARCHAR(50) UNIQUE,
name VARCHAR(30) INDEX
);
-- 已有表加索引
CREATE INDEX idx_name ON user(name); -- 常规索引
DROP INDEX idx_name ON user; -- 删除索引
💡 老司机秘籍:
- 别乱建索引!索引越多,写数据越慢(更新索引要额外开销)。
- 主键查询最快,优先用主键!
- 全文索引用
MATCH() AGAINST():SELECT * FROM article WHERE MATCH(content) AGAINST('AI');
三、视图:虚拟表,偷懒神器! 😌
一句话:视图 = 一个“假表”,不存真实数据,查它时动态执行底层SQL。
优点:
- 封装复杂多表查询(比如
CREATE VIEW sales_view AS SELECT ... JOIN ...) - 隐藏敏感字段(只暴露需要的列)
- 权限隔离(给用户只看视图,不看原表)
缺点:
- 不能单独优化视图逻辑(改了原表,视图可能崩)
- 不能更新:含
GROUP BY、DISTINCT、UNION的视图
🚀 3行代码搞定:
-- 创建视图(封装多表查询)
CREATE VIEW emp_dept_view AS
SELECT e.name, d.dept_name
FROM emp e JOIN dept d ON e.dept_id = d.id;
-- 查询视图(和真表一样用!)
SELECT * FROM emp_dept_view;
-- 删除视图
DROP VIEW emp_dept_view;
“视图就是你的SQL分身,写一次,用百次。但别指望它能帮你减肥(数据量不会变)!” 😂
四、存储过程:SQL的“函数” 📦
一句话:存储过程 = 一组预编译SQL,存在数据库里,调用时直接执行(不用重复传SQL)。
优点:
- 复用代码(比如批量插入)
- 执行更快(减少网络传输)
- 封装业务逻辑(比如“发工资”流程)
缺点:
- 换数据库可能跑不动(移植性差)
- 调试麻烦(不如写代码直观)
核心技能点(附代码)
1. 三大参数类型:
| 参数 | 作用 | 调用示例 |
|---|---|---|
IN | 输入参数 | CALL calc(100); |
OUT | 输出结果 | CALL get_name(1, @name); |
INOUT | 既输入又输出 | CALL update_salary(@sal); |
2. 关键语法(避坑必看!):
-- 修改结束符(默认;会冲突!)
DELIMITER //
CREATE PROCEDURE calc(IN num INT, OUT result INT)
BEGIN
SET result = num * 2; -- 用SET赋值
END //
DELIMITER ; -- 一定要改回来!
-- 调用存储过程
CALL calc(10, @res);
SELECT @res; -- 输出20
3. 流程控制(让SQL变智能):
IF score > 90 THEN
SET grade = 'A';
ELSEIF score > 80 THEN
SET grade = 'B';
ELSE
SET grade = 'C';
END IF;
“存储过程就像你的SQL私人管家——写一次,终身受用。但别让它干太多活(维护成本高)!” 🧠
总结:SQL老司机の忠告 💯
- 子查询:标量用
IN避坑,关联用EXISTS更快。 - 索引:主键 > 唯一 > 常规,别乱建!
- 视图:封装查询神器,但别指望它能更新。
- 存储过程:复用代码首选,但移植性差要小心。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)