1. SQL基础语句概述
SQL作为关系型数据库的标准查询语言,是每个开发者必须掌握的核心技能。我在实际工作中发现,80%的数据库操作都集中在20%的基础SQL语句上。本文将系统梳理这些高频使用的SQL基础语句,涵盖数据查询、操作、表管理等核心功能模块。
初学者常犯的错误是过早追求复杂查询而忽视基础语法。事实上,熟练使用基础语句能解决大多数日常开发需求。我特别整理了每个语句的易错点和性能注意事项,这些都是在实际项目中积累的经验。
2. 数据查询基础
2.1 SELECT语句精要
最基本的SELECT语句结构如下:
SELECT 列名1, 列名2 FROM 表名 WHERE 条件常见新手错误包括:
- 使用SELECT * 查询所有列(影响性能)
- WHERE条件中使用函数导致索引失效
- 忘记处理NULL值(应使用IS NULL判断)
提示:生产环境务必指定具体列名,避免使用SELECT *。我曾遇到一个案例,某表新增了TEXT类型字段后,全表查询性能下降90%。
2.2 条件查询进阶
WHERE子句支持多种运算符:
- 比较运算符:=, >, <, >=, <=, <>
- 逻辑运算符:AND, OR, NOT
- 特殊运算符:BETWEEN, IN, LIKE
LIKE模糊查询的优化技巧:
-- 前导通配符无法使用索引 SELECT * FROM users WHERE name LIKE '%张%' -- 后导通配符可以使用索引 SELECT * FROM users WHERE name LIKE '张%'3. 数据操作语句
3.1 增删改语句详解
INSERT语句标准写法:
INSERT INTO 表名(列1,列2) VALUES (值1,值2)UPDATE语句注意事项:
-- 务必带WHERE条件! UPDATE users SET status=1 WHERE user_id=1001DELETE语句风险控制:
-- 先SELECT确认要删除的数据 SELECT * FROM orders WHERE create_time < '2020-01-01'; -- 再执行DELETE DELETE FROM orders WHERE create_time < '2020-01-01';3.2 事务处理实战
典型事务流程:
BEGIN TRANSACTION; UPDATE accounts SET balance=balance-100 WHERE user_id=1; UPDATE accounts SET balance=balance+100 WHERE user_id=2; COMMIT; -- 出错时执行ROLLBACK4. 表与索引管理
4.1 表结构操作
创建表示例:
CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, salary DECIMAL(10,2), hire_date DATE DEFAULT CURRENT_DATE );添加索引的正确姿势:
-- 单列索引 CREATE INDEX idx_name ON employees(name); -- 复合索引(注意字段顺序) CREATE INDEX idx_dept_salary ON employees(department_id, salary);4.2 约束使用技巧
常用约束类型:
- PRIMARY KEY
- FOREIGN KEY
- UNIQUE
- CHECK
- NOT NULL
外键约束示例:
CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, FOREIGN KEY (user_id) REFERENCES users(user_id) );5. 高级查询技巧
5.1 聚合函数实战
常用聚合函数:
SELECT COUNT(*) AS total, AVG(salary) AS avg_salary, MAX(score) AS max_score, SUM(amount) AS total_amount FROM employee;GROUP BY注意事项:
-- 正确:SELECT中的非聚合字段必须出现在GROUP BY中 SELECT department_id, COUNT(*) FROM employees GROUP BY department_id;5.2 多表连接查询
连接类型对比:
- INNER JOIN:只返回匹配行
- LEFT JOIN:返回左表所有行
- RIGHT JOIN:返回右表所有行
- FULL JOIN:返回所有行
性能优化建议:
-- 使用JOIN ON语法更清晰 SELECT u.name, o.order_date FROM users u JOIN orders o ON u.user_id = o.user_id WHERE u.status = 1;6. 实用语句集锦
6.1 日期处理技巧
获取当前日期:
-- MySQL SELECT NOW(), CURDATE(), CURTIME(); -- SQL Server SELECT GETDATE();日期计算:
-- 三天后的日期 SELECT DATE_ADD(CURDATE(), INTERVAL 3 DAY); -- 两个日期相差天数 SELECT DATEDIFF('2023-12-31', '2023-01-01');6.2 字符串处理
常用字符串函数:
SELECT CONCAT(first_name, ' ', last_name) AS full_name, UPPER(email) AS email_upper, SUBSTRING(phone, 1, 3) AS area_code, LENGTH(address) AS addr_length FROM customers;7. 性能优化基础
7.1 EXPLAIN执行计划
分析查询性能:
EXPLAIN SELECT * FROM orders WHERE user_id=1001 AND status=1;关键指标解读:
- type:ALL(全表扫描) → index → range → ref → eq_ref → const
- rows:预估扫描行数
- Extra:Using filesort, Using temporary等需要优化
7.2 索引优化原则
建立索引的黄金法则:
- 为WHERE、JOIN、ORDER BY字段建索引
- 区分度高的列适合建索引
- 避免过度索引(影响写入性能)
- 注意复合索引字段顺序
8. 安全注意事项
8.1 SQL注入防御
危险写法:
-- 拼接SQL语句极易被注入 String sql = "SELECT * FROM users WHERE name='" + name + "'";参数化查询:
// Java示例 PreparedStatement stmt = conn.prepareStatement( "SELECT * FROM users WHERE name=?"); stmt.setString(1, name);8.2 权限管理建议
最小权限原则:
-- 创建只读用户 CREATE USER 'report_user'@'%' IDENTIFIED BY 'password'; GRANT SELECT ON db_name.* TO 'report_user'@'%';9. 实战案例解析
9.1 分页查询实现
MySQL分页:
SELECT * FROM products ORDER BY create_time DESC LIMIT 10 OFFSET 20; -- 第3页,每页10条SQL Server分页:
SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY create_time DESC) AS row_num, * FROM products ) AS t WHERE row_num BETWEEN 21 AND 30;9.2 数据去重方案
使用DISTINCT:
SELECT DISTINCT department_id FROM employees;使用GROUP BY:
SELECT department_id FROM employees GROUP BY department_id;10. 常见问题排查
10.1 连接失败排查
检查步骤:
- 确认服务是否运行
- 检查连接字符串参数
- 验证网络连通性
- 检查防火墙设置
- 查看数据库错误日志
10.2 性能问题诊断
慢查询分析流程:
- 开启慢查询日志
- 使用EXPLAIN分析
- 检查索引使用情况
- 优化SQL语句结构
- 考虑数据库参数调整
11. 学习资源推荐
11.1 在线练习平台
推荐资源:
- SQLZoo:交互式学习
- LeetCode数据库题库:实战题目
- HackerRank:从易到难挑战
11.2 进阶学习路径
建议学习顺序:
- 基础CRUD → 2. 多表连接 → 3. 子查询 → 4. 窗口函数 → 5. 性能优化 → 6. 事务与锁
12. 版本差异备忘
12.1 MySQL与SQL Server区别
语法差异对比:
| 功能 | MySQL | SQL Server |
|---|---|---|
| 分页 | LIMIT 10 OFFSET 20 | OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY |
| 字符串连接 | CONCAT(str1, str2) | str1 + str2 |
| 当前时间 | NOW() | GETDATE() |
12.2 新特性速览
MySQL 8.0+:
- 窗口函数
- 通用表表达式(CTE)
- JSON增强功能
SQL Server 2019+:
- 智能查询处理
- 大数据集群
- 内存优化增强
13. 开发实用技巧
13.1 调试技巧
临时调试方法:
-- 输出变量值 SELECT @var_name; -- 打印调试信息 SELECT 'Debug point 1' AS debug_info;13.2 代码片段管理
常用代码片段:
-- 快速备份表 CREATE TABLE orders_backup AS SELECT * FROM orders; -- 清空表数据 TRUNCATE TABLE temp_data; -- 复制表结构 CREATE TABLE new_table LIKE old_table;14. 最佳实践总结
14.1 命名规范建议
数据库对象命名:
- 表名:复数形式(users, products)
- 列名:小写加下划线(user_name, order_date)
- 索引:idx_列名(idx_user_name)
- 主键:表名_id(user_id, product_id)
14.2 文档编写标准
SQL脚本注释规范:
/* * 功能:获取活跃用户列表 * 作者:张三 * 日期:2023-07-20 */ SELECT user_id, user_name FROM users WHERE last_login > DATE_SUB(NOW(), INTERVAL 30 DAY);15. 性能对比测试
15.1 查询方式对比
EXISTS vs IN:
-- EXISTS通常性能更好 SELECT * FROM orders o WHERE EXISTS ( SELECT 1 FROM users u WHERE u.user_id = o.user_id AND u.status = 1 ); -- IN适合小数据集 SELECT * FROM orders WHERE user_id IN (SELECT user_id FROM users WHERE status = 1);15.2 索引效果验证
创建索引前后对比:
-- 无索引(执行时间:500ms) SELECT * FROM orders WHERE user_id = 1001; -- 添加索引 CREATE INDEX idx_user_id ON orders(user_id); -- 有索引(执行时间:5ms) SELECT * FROM orders WHERE user_id = 1001;16. 数据导入导出
16.1 批量导入数据
MySQL LOAD DATA:
LOAD DATA INFILE '/path/to/file.csv' INTO TABLE employees FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 ROWS;16.2 数据导出方案
导出为CSV:
SELECT * INTO OUTFILE '/tmp/result.csv' FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' FROM employees WHERE department_id = 10;17. 系统函数参考
17.1 数学函数示例
常用计算函数:
SELECT ABS(-10), ROUND(3.1415, 2), CEILING(4.3), FLOOR(4.9), RAND() AS random_num;17.2 条件判断函数
CASE WHEN用法:
SELECT product_name, CASE WHEN price > 1000 THEN '高价' WHEN price > 500 THEN '中价' ELSE '低价' END AS price_level FROM products;18. 维护与监控
18.1 表维护语句
优化表:
-- MySQL OPTIMIZE TABLE orders; -- SQL Server ALTER INDEX ALL ON orders REBUILD;18.2 监控关键指标
重要性能计数器:
- 连接数
- 缓存命中率
- 锁等待
- 慢查询数量
- 磁盘I/O
19. 云数据库适配
19.1 AWS RDS注意事项
特殊语法限制:
- 无SUPER权限
- 部分系统表不可访问
- 备份恢复方式不同
19.2 阿里云优化建议
云数据库优化:
- 使用读写分离
- 合理设置白名单
- 监控只读实例延迟
- 定期维护统计信息
20. 未来学习方向
20.1 窗口函数入门
基础窗口函数:
SELECT employee_id, salary, AVG(salary) OVER (PARTITION BY department_id) AS dept_avg_salary, RANK() OVER (ORDER BY salary DESC) AS salary_rank FROM employees;20.2 JSON处理技术
MySQL JSON函数:
SELECT user_id, JSON_EXTRACT(profile, '$.address.city') AS city, JSON_CONTAINS(interests, '"reading"') AS likes_reading FROM users;