SQL 编写规范核心原则

清晰易读:代码是给人看的,其次才是机器执行。

性能优先:避免低效语法,减少数据库负担。

安全可靠:防范 SQL 注入等风险。

统一风格:团队协作时保持格式一致。

✨ 格式规范

1. 关键字统一大写

-- 正确 ✅

SELECT id, name FROM users WHERE age > 18;

-- 错误 ❌

select Id, Name from Users where age > 18;

2. 缩进与换行

多行对齐:复杂语句换行缩进,用 2/4 空格(避免 Tab)

子句换行:SELECT、FROM、WHERE、JOIN 等独立一行

SELECT

u.id,

u.name,

o.order_date

FROM

users AS u

INNER JOIN orders AS o

ON u.id = o.user_id

WHERE

u.status = 'active'

AND o.total > 1000;

3. 表名与字段名

表名:复数形式(如 users),小写 + 下划线(如 order_details)

字段名:小写 + 下划线(如 created_at)

🔍 命名与别名规范

1. 别名明确性

使用 AS 显式定义别名,避免歧义

-- 正确 ✅

SELECT

u.id AS user_id,

o.id AS order_id

FROM users AS u;

-- 错误 ❌

SELECT u.id uid, o.id oid FROM users u;

2. 避免保留字

不要用 name、order、group 等保留字作为字段名(用 user_name 代替 name)

⚡ 语法规范

1. 避免 SELECT *

-- 正确 ✅

SELECT id, name, email FROM users;

-- 错误 ❌

SELECT * FROM users;

2. 显式 JOIN 代替隐式

-- 正确 ✅(显式 JOIN)

SELECT u.name, o.total

FROM users AS u

INNER JOIN orders AS o ON u.id = o.user_id;

-- 错误 ❌(隐式 JOIN)

SELECT u.name, o.total

FROM users u, orders o

WHERE u.id = o.user_id;

3. 使用 IN 代替多个 OR

-- 正确 ✅

SELECT id FROM products WHERE category_id IN (1, 3, 5);

-- 错误 ❌

SELECT id FROM products WHERE category_id = 1 OR category_id = 3 OR category_id = 5;

🚀 性能优化规范

1. 索引友好写法

避免对索引列使用函数或运算:

-- 错误 ❌(索引失效)

SELECT * FROM users WHERE YEAR(created_at) = 2023;

-- 正确 ✅

SELECT * FROM users WHERE created_at >= '2023-01-01' AND created_at < '2024-01-01';

2. 分页优化

大数据分页用 WHERE + LIMIT 代替 OFFSET:

-- 高效 ✅

SELECT * FROM orders

WHERE id > 1000 -- 基于上次查询的最后一个 ID

ORDER BY id

LIMIT 10;

3. 避免嵌套过深

用 JOIN 或 WITH(CTE)代替多层子查询:

-- 正确 ✅(使用 CTE)

WITH active_users AS (

SELECT id FROM users WHERE status = 'active'

)

SELECT * FROM orders

WHERE user_id IN (SELECT id FROM active_users);

🔒 安全规范

参数化查询

永远不要拼接 SQL 字符串,用预编译语句(如 MyBatis 的 #{}):

-- MyBatis 示例 ✅

SELECT * FROM users WHERE name = #{userName};

权限最小化

禁止为应用账号分配 DROP、GRANT 等高危权限。

📌 注释与文档

1. 关键逻辑注释

-- 统计每日活跃用户(排除测试账号)

SELECT

DATE(login_time) AS day,

COUNT(DISTINCT user_id) AS active_users

FROM user_logs

WHERE

user_id NOT IN (SELECT id FROM test_users) -- 过滤测试用户

GROUP BY day;

2. 复杂逻辑用 CTE 拆分

WITH

monthly_sales AS (

SELECT

user_id,

SUM(amount) AS total_amount

FROM orders

WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'

GROUP BY user_id

)

SELECT

u.name,

ms.total_amount

FROM users AS u

INNER JOIN monthly_sales AS ms ON u.id = ms.user_id;

🛠️ 工具推荐

SQL 格式化工具

SQL Formatter:在线美化 SQL 语句

Prettier(插件版):集成到 IDE 自动格式化

性能分析工具

EXPLAIN 命令(MySQL/PostgreSQL)

pgAdmin(PostgreSQL 性能监控)

🌟 总结

格式统一:团队使用同一套规范(可配置 ESLint 或 EditorConfig)。

性能敏感:关键查询必须通过 EXPLAIN 分析执行计划。

安全第一:参数化查询 + 最小权限原则。

持续优化:定期 Review SQL 代码,删除冗余或低效语句。