🙏 感谢您的支持! 我们在七月份已经筹集了 $65 — 这足够我们工作到下个月。请帮助我们保持进度,进一步支持这个项目。 支持这个项目 →
SQL 代码已复制到剪贴板

课程 10.1 · 阅读时间:~9分钟

本课程涵盖编写高质量SQL代码的基础知识,使其易于阅读和维护。您将学习格式化标准、对象命名规则以及如何有效使用注释。我们将回顾如何使复杂查询对您的团队成员和未来的自己清晰易懂。到本课程结束时,您将能够专业且一致地格式化SQL脚本。

课程10.1:可读性和可维护性SQL代码的最佳实践

在上一个模块中,我们学习了视图和临时表等高级数据工具。现在,随着您的查询变得越来越大和复杂,代码质量成为首要任务。在实际的分析和开发工作中,SQL代码的阅读频率远高于编写频率。

结构良好的代码减少错误,简化调试,并为整个团队节省时间。这不仅仅是风格问题。这是任何SQL开发人员或数据分析师的关键技能。

未结构化和格式良好的SQL查询的可读性比较


为什么代码风格很重要

当查询有5-10行时,其逻辑通常一目了然。但当您转向包含许多JOIN子句、子查询或CTE块的复杂报告时,代码可能会变得过于复杂,甚至对于原作者在一周后也难以解析。

遵循标准可以帮助您:

  • 更快找到错误: 错误的过滤器或缺失的JOIN子句在干净的代码中会显得突出。
  • 扩展解决方案: 结构化代码更容易扩展新字段和条件。
  • 团队协作: 团队成员可以更顺利地审查和维护您的脚本。

格式化和缩进

一致的格式化风格是可读性的基础。SQL对空格或字母大小写不敏感,但有广泛接受的约定。

关键字大小写

一个常见的做法是将SQL关键字(SELECTFROMWHEREJOINGROUP BY)写成大写。这在视觉上将数据库命令与表和列名称分开。

-- 差
select name, price from products where category_id = 1;

-- 更好
SELECT name, price
FROM products
WHERE category_id = 1;

换行和缩进

每个主要子句应在新行开始。如果SELECTGROUP BY包含许多列,则将每列放在自己的行上。

SELECT 
    customer_id,
    first_name,
    last_name,
    email
FROM customer
WHERE active = 1
ORDER BY last_name;

命名约定

为表、列和变量选择良好的名称对代码清晰度至关重要。

小写和snake_case

在SQL中,事实上的标准是使用小写和单词之间的下划线。许多DBMS引擎以不同的方式规范标识符的大小写(例如,PostgreSQL和Oracle),而snake_case有助于避免混淆。

  • 差: CustomerOrdersTotalAmount
  • 更好: customer_orderstotal_amount

对象类型的前缀

有时团队使用前缀快速识别对象类型。

示例:

  • v_表示视图:v_active_customers
  • tmp_表示临时表:tmp_monthly_report
  • t_表示基础表(较少使用)
-- 这显然是一个准备好的视图
SELECT * 
FROM v_customer_payment_summary
WHERE total_amount > 100;

命名和别名

清晰的名称和别名使查询自我文档化。

清晰的表别名

使用简短但有意义的别名,特别是在JOIN时。避免使用t1t2ab等别名。

-- 不清晰
SELECT 
    t1.name, 
    t2.amount
FROM table_a t1
JOIN table_b t2 ON t1.id = t2.ref_id;

-- 清晰
SELECT 
    c.first_name, 
    p.amount
FROM customer c
JOIN payment p ON c.customer_id = p.customer_id;

计算字段的清晰别名

始终为聚合和计算列提供有意义的名称。名为count(*)的报告列看起来不专业。

SELECT 
    category_id,
    COUNT(*) AS total_films_in_category,
    AVG(replacement_cost) AS average_replacement_cost
FROM film
GROUP BY category_id;

注释SQL代码

注释解释为什么某段逻辑存在,当意图不明显时。

  • 单行注释(--): 解释特定的过滤器或公式。
  • 块注释(/* ... */): 描述脚本目的、作者和日期。
/*
  脚本:每月活跃客户消费
  作者:Ivanov I.
  日期:2026-04-16
*/

SELECT 
    customer_id,
    SUM(amount) AS monthly_spent
FROM payment
WHERE payment_date >= '2026-01-01' -- 从年初开始过滤
  AND payment_date < '2026-02-01'
GROUP BY customer_id;

实际示例:清理混乱的查询

让我们比较一个难以阅读的查询与一个可维护的版本。

之前(难以阅读):

select f.title,c.name,count(r.rental_id) from film f join film_category fc on f.film_id=fc.film_id join category c on fc.category_id=c.category_id join inventory i on f.film_id=i.film_id join rental r on i.inventory_id=r.inventory_id group by f.title,c.name having count(r.rental_id)>30 order by count(r.rental_id) desc;

之后(易于维护):

SELECT 
    f.title,
    c.name AS category_name,
    COUNT(r.rental_id) AS rental_count
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c       ON fc.category_id = c.category_id
JOIN inventory i      ON f.film_id = i.film_id
JOIN rental r         ON i.inventory_id = r.inventory_id
GROUP BY f.title, c.name
HAVING COUNT(r.rental_id) > 30
ORDER BY rental_count DESC;

注意:在第二个版本中,关系结构、聚合命名和过滤逻辑立即可见。


本课的关键要点:

  • 将SQL关键字写成大写,以使查询结构可见。
  • 使用换行和缩进,使长查询更易于阅读和审查。
  • 为表和计算字段使用清晰的别名。
  • 应用一致的命名规则,例如表和列的snake_case
  • 注释不明显的业务逻辑和复杂的过滤条件。
  • 在团队中维护共享的风格指南,以加快审查、调试和演变。

常见问题

SQL关键字是否总需要大写?

没有技术要求。DBMS引擎也会解析小写。但一致的大写风格(SELECTFROMWHEREJOIN)提高了可读性并加快了长查询的审查。

SQL中的注释何时真正有用?

注释在逻辑不明显的地方最有用:业务规则、不寻常的过滤器和技术限制。如果代码已经清晰,请避免不必要的注释。

对于可维护性,格式化和命名哪个更重要?

两者都至关重要。格式化快速显示查询结构,而清晰的名称和别名使意图显而易见,无需额外解释。

面试问题

可维护的SQL代码的特征是什么?

可维护的SQL具有一致的格式、清晰的命名、有意义的别名和在不明显的地方简洁的注释。这使得代码更容易审查、修改和支持团队。

为什么糟糕的命名会成为团队级别的问题?

不清晰的名称和别名会减慢审查速度,并增加在更改过程中出错的风险。良好的名称减少了认知负担,使查询逻辑透明。

您将如何在实践中改进混乱的SQL查询?

首先将其拆分为逻辑块(SELECTFROMJOINWHEREGROUP BYORDER BY),并进行适当的换行和缩进。然后替换不清晰的别名,清晰命名计算字段,并在逻辑不明显的地方添加简短的注释。

在下一课中,我们将转向技术优化,学习如何编写不仅干净而且快速的SQL查询。

-> 课程10.2:编写高效的SQL查询