SQL Server 命名规范与 T-SQL 编程风格指南
计算机科学领域只有两件难事:缓存失效和命名规范
—— Phil Karlton
前言
在数据库开发中,良好的命名规范和编程风格是保证代码可维护性的关键因素。本文将系统性地介绍 SQL Server 数据库对象的命名规范、数据类型选择建议以及 T-SQL 编程的最佳实践,帮助开发者建立统一的开发标准。
一、SQL Server 对象命名规范
1.1 命名规范的重要性
命名规范是一套用于选择标识符字符序列的规则,这些标识符用于表示源代码中的变量、类型、函数等实体。采用统一的命名规范可以:
- 降低阅读和理解代码的难度
- 让代码审查聚焦于逻辑而非命名争议
- 使代码质量检查工具能关注更重要的实质问题
1.2 各类对象命名规则详解
以下是 SQL Server 中各类对象的命名规范建议:
数据库对象命名矩阵
| 对象类型 | 命名风格 | 长度限制 | 前缀 | 后缀 | 示例 |
|---|---|---|---|---|---|
| 数据库 | UPPERCASE | 30 | 无 | 无 | MYDATABASE |
| 架构 | lowercase | 30 | 无 | 无 | myschema |
| 常规表 | PascalCase | 128 | 无 | 无 | MyTable |
| 内存优化表(持久化) | PascalCase | 128 | MT_ | _SD | MT_MyTable_SD |
| 内存优化表(非持久化) | PascalCase | 128 | MT_ | _SO | MT_MyTable_SO |
| 时态表 | PascalCase | 128 | 无 | _TT | MyTable_TT |
| 列 | PascalCase | 128 | 无 | 无 | MyColumn |
| 主键约束 | PascalCase | 128 | PK_ | 无 | PK_MyTableID |
| 外键约束 | PascalCase | 128 | FK_ | 无 | FK_MyTable_RefID |
| 存储过程 | PascalCase | 128 | usp_ | 无 | usp_GetUserInfo |
| 标量函数 | PascalCase | 128 | udf_ | 无 | udf_CalculateTax |
| 表值函数 | PascalCase | 128 | tvf_ | 无 | tvf_GetOrderItems |
关键说明:
- 前缀使用:通过前缀可以快速识别对象类型,如
usp_表示存储过程 - 大小写规范:不同对象采用不同的大小写风格增强可读性
- 特殊对象标记:如内存优化表通过前缀和后缀明确标识其特性
二、SQL Server 数据类型选择建议
2.1 数据类型选择原则
选择合适的数据类型需要考虑:
- 存储空间效率
- 计算性能
- 精度要求
- 业务语义表达
2.2 数据类型推荐表
| 类型大类 | 具体类型 | 推荐程度 | 替代方案 | 说明 |
|---|---|---|---|---|
| 精确数值 | int | ★★★★★ | - | 整数首选类型 |
| 精确数值 | decimal | ★★★★★ | - | 精确小数计算必选 |
| 近似数值 | float(24-53) | ★★★★☆ | - | 科学计算适用 |
| 日期时间 | datetime2 | ★★★★★ | - | 替代 datetime 的新类型 |
| 日期时间 | datetimeoffset | ★★★★★ | - | 需要时区信息时使用 |
| 字符类型 | varchar/nvarchar | ★★★★★ | char/nchar | 变长类型节省空间 |
| 二进制类型 | varbinary | ★★★★★ | - | 二进制数据存储 |
2.3 特别注意事项
- 避免使用 money/smallmoney:可能存在精度损失问题,推荐使用 decimal
- 谨慎使用 datetime:datetime2 具有更好的精度和范围
- text/ntext 已弃用:应使用 varchar(max)/nvarchar(max) 替代
三、T-SQL 编程风格指南
3.1 基础编程规范
- 关键字大写:SELECT、FROM、WHERE 等关键字统一大写
- 缩进对齐:使用一致的缩进(建议4个空格)
- 注释规范:复杂逻辑添加清晰注释
-- 示例:规范的查询语句
SELECT
u.UserID,
u.UserName,
o.OrderCount
FROM
dbo.Users u
INNER JOIN dbo.UserOrders o ON u.UserID = o.UserID
WHERE
u.IsActive = 1
AND o.OrderDate >= @StartDate
ORDER BY
o.OrderCount DESC;
3.2 存储过程编程建议
- 参数命名:使用
@前缀,PascalCase 风格 - 错误处理:使用 TRY-CATCH 块
- 返回值:通过 RETURN 或 OUTPUT 参数返回状态
CREATE PROCEDURE usp_GetUserOrders
@UserID INT,
@StartDate DATETIME2 = NULL,
@OrderCount INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
IF @StartDate IS NULL
SET @StartDate = DATEADD(MONTH, -1, GETDATE());
SELECT @OrderCount = COUNT(*)
FROM dbo.Orders
WHERE UserID = @UserID
AND OrderDate >= @StartDate;
SELECT
OrderID,
OrderDate,
TotalAmount
FROM
dbo.Orders
WHERE
UserID = @UserID
AND OrderDate >= @StartDate
ORDER BY
OrderDate DESC;
RETURN 0; -- 成功
END TRY
BEGIN CATCH
-- 记录错误日志
EXEC usp_LogError;
RETURN -1; -- 失败
END CATCH
END
3.3 动态 SQL 安全建议
- 使用参数化查询:避免 SQL 注入
- QUOTENAME 函数:安全处理对象名
- sp_executesql:优先于 EXEC
DECLARE @SQL NVARCHAR(MAX);
DECLARE @TableName NVARCHAR(128) = 'Orders';
DECLARE @DateColumn NVARCHAR(128) = 'OrderDate';
DECLARE @StartDate DATETIME2 = '2023-01-01';
SET @SQL = N'SELECT COUNT(*) FROM ' + QUOTENAME(@TableName) +
N' WHERE ' + QUOTENAME(@DateColumn) + ' >= @StartDateParam';
EXEC sp_executesql @SQL,
N'@StartDateParam DATETIME2',
@StartDateParam = @StartDate;
四、总结
良好的命名规范和编程风格是专业数据库开发的基石。通过本文的规范建议,开发者可以:
- 建立统一的命名体系,提高代码可读性
- 选择最优的数据类型,平衡存储与性能
- 遵循一致的编程风格,降低维护成本
建议团队根据实际项目需求,在本文基础上制定更详细的编码规范文档,并通过代码审查确保规范执行。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



