外观
SQL命名规范
数据库对象命名规范
数据库命名
规范:
命名规则:
- 使用小写字母
- 使用下划线分隔单词
- 简短且描述性
- 避免使用保留字
示例:
app_db- 应用数据库user_db- 用户数据库log_db- 日志数据库test_db- 测试数据库
不推荐:
AppDB- 混合大小写database1- 无描述性user-db- 使用连字符
表命名
规范:
命名规则:
- 使用小写字母
- 使用下划线分隔单词
- 使用复数形式(表示集合)
- 简短且描述性
示例:
users- 用户表orders- 订单表products- 产品表user_orders- 用户订单关联表
不推荐:
User- 单数形式customerOrders- 驼峰命名tbl_users- 多余的前缀user- 过于简短
列命名
规范:
命名规则:
- 使用小写字母
- 使用下划线分隔单词
- 使用单数形式
- 简短且描述性
- 避免使用保留字
示例:
id- 主键user_id- 用户IDname- 名称email_address- 电子邮件地址created_at- 创建时间
不推荐:
userID- 驼峰命名EMAIL- 大写cust_name- 缩写不清晰date- 过于简短
主键命名
规范:
命名规则:
- 使用
id作为表的主键 - 对于复合主键,使用描述性名称
- 保持一致性
- 使用
示例:
id- 单个表的主键user_id- 外键order_product_id- 复合主键
不推荐:
user_id- 作为用户表的主键(应使用id)primary_key- 过于冗长uid- 缩写不清晰
外键命名
规范:
命名规则:
- 使用
{referenced_table}_id格式 - 保持与引用表主键名称一致
- 清晰表达引用关系
- 使用
示例:
user_id- 引用 users 表的主键order_id- 引用 orders 表的主键product_id- 引用 products 表的主键
不推荐:
customer_id- 当引用表名为users时uid- 缩写不清晰user- 过于简短
索引命名
规范:
命名规则:
- 使用
idx_{table}_{columns}格式 - 对于唯一索引,使用
uniq_{table}_{columns}格式 - 对于复合索引,使用列名的缩写
- 保持一致性
- 使用
示例:
idx_users_email- 用户表邮箱索引uniq_users_username- 用户表用户名唯一索引idx_orders_user_status- 订单表用户ID和状态复合索引
不推荐:
index1- 无描述性users_email_index- 格式不一致idx_email- 缺少表名
存储过程命名
规范:
命名规则:
- 使用
sp_{action}_{object}格式 - 使用动词开头
- 清晰表达功能
- 避免使用保留字
- 使用
示例:
sp_get_user- 获取用户信息sp_insert_order- 插入订单sp_update_product- 更新产品信息sp_delete_old_logs- 删除旧日志
不推荐:
getUser- 驼峰命名insert- 过于简短procedure1- 无描述性
函数命名
规范:
命名规则:
- 使用
fn_{action}_{object}格式 - 使用动词开头
- 清晰表达功能
- 避免使用保留字
- 使用
示例:
fn_calculate_total- 计算总计fn_format_date- 格式化日期fn_generate_id- 生成IDfn_validate_email- 验证邮箱
不推荐:
calculateTotal- 驼峰命名format- 过于简短function1- 无描述性
触发器命名
规范:
命名规则:
- 使用
trg_{table}_{event}_{action}格式 event可以是insert、update、deleteaction表示触发器的操作- 清晰表达触发时机和操作
- 使用
示例:
trg_users_insert_audit- 用户插入审计触发器trg_orders_update_status- 订单状态更新触发器trg_products_delete_log- 产品删除日志触发器
不推荐:
trigger1- 无描述性users_trigger- 缺少事件和操作trg_insert_users- 格式不一致
视图命名
规范:
命名规则:
- 使用
v_{name}格式 - 简短且描述性
- 清晰表达视图的用途
- 避免使用保留字
- 使用
示例:
v_active_users- 活跃用户视图v_order_summary- 订单汇总视图v_product_inventory- 产品库存视图
不推荐:
view1- 无描述性ActiveUsers- 驼峰命名v_users- 过于简短
事件命名
规范:
命名规则:
- 使用
evt_{action}_{object}格式 - 清晰表达事件的用途
- 避免使用保留字
- 使用
示例:
evt_cleanup_logs- 清理日志事件evt_update_statistics- 更新统计信息事件evt_backup_database- 备份数据库事件
不推荐:
event1- 无描述性cleanup- 过于简短EventCleanup- 驼峰命名
命名风格指南
大小写规范
推荐风格:
数据库对象:
- 使用小写字母
- 使用下划线分隔单词
- 例如:
users,order_items,created_at
SQL关键字:
- 使用大写字母
- 例如:
SELECT,INSERT,UPDATE,DELETE
函数和存储过程:
- 使用小写字母
- 使用下划线分隔单词
- 例如:
sp_get_user,fn_calculate_total
示例:
sql
-- 推荐风格
SELECT u.id, u.name, o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.active = 1
ORDER BY o.order_date DESC;
-- 不推荐风格
select u.id, u.name, o.order_date
from users u
join orders o on u.id = o.user_id
where u.active = 1
order by o.order_date desc;长度规范
推荐长度:
数据库名称:
- 最大长度:64 字符
- 推荐长度:8-16 字符
表名称:
- 最大长度:64 字符
- 推荐长度:8-20 字符
列名称:
- 最大长度:64 字符
- 推荐长度:4-16 字符
索引名称:
- 最大长度:64 字符
- 推荐长度:10-25 字符
存储过程/函数名称:
- 最大长度:64 字符
- 推荐长度:10-25 字符
缩写规范
使用原则:
避免过度缩写:
- 只使用广泛理解的缩写
- 保持缩写的一致性
- 避免模糊的缩写
推荐缩写:
id- identifierurl- uniform resource locatorip- internet protocolhtml- hypertext markup languagexml- extensible markup language
不推荐缩写:
cust- customer(使用完整单词)addr- address(使用完整单词)desc- description(使用完整单词,避免与保留字冲突)
保留字处理
处理方法:
避免使用保留字:
- 不使用 MySQL 保留字作为对象名称
- 检查保留字列表
- 使用描述性的替代名称
必要时使用引号:
- 如果必须使用保留字,使用反引号包围
- 例如:
`order`(不推荐,应使用orders)
常见保留字:
order,group,user,date,time,type,statusselect,insert,update,delete,from,where
命名规范示例
表结构示例
用户表:
sql
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX uniq_users_username ON users(username);订单表:
sql
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
shipping_address TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 索引
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_user_status ON orders(user_id, status);订单项目表:
sql
CREATE TABLE order_items (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
subtotal DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
-- 索引
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);存储过程示例
获取用户信息:
sql
DELIMITER //
CREATE PROCEDURE sp_get_user(IN p_user_id INT)
BEGIN
SELECT id, username, email, first_name, last_name, active, created_at
FROM users
WHERE id = p_user_id;
END //
DELIMITER ;插入订单:
sql
DELIMITER //
CREATE PROCEDURE sp_insert_order(
IN p_user_id INT,
IN p_total_amount DECIMAL(10,2),
IN p_shipping_address TEXT,
OUT p_order_id INT
)
BEGIN
INSERT INTO orders (user_id, total_amount, shipping_address)
VALUES (p_user_id, p_total_amount, p_shipping_address);
SET p_order_id = LAST_INSERT_ID();
END //
DELIMITER ;函数示例
计算订单总计:
sql
DELIMITER //
CREATE FUNCTION fn_calculate_order_total(p_order_id INT)
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
DECLARE v_total DECIMAL(10,2);
SELECT SUM(subtotal) INTO v_total
FROM order_items
WHERE order_id = p_order_id;
RETURN COALESCE(v_total, 0);
END //
DELIMITER ;格式化日期:
sql
DELIMITER //
CREATE FUNCTION fn_format_date(p_date DATE, p_format VARCHAR(20))
RETURNS VARCHAR(50)
DETERMINISTIC
BEGIN
IF p_format = 'YYYY-MM-DD' THEN
RETURN DATE_FORMAT(p_date, '%Y-%m-%d');
ELSEIF p_format = 'DD/MM/YYYY' THEN
RETURN DATE_FORMAT(p_date, '%d/%m/%Y');
ELSEIF p_format = 'MM/DD/YYYY' THEN
RETURN DATE_FORMAT(p_date, '%m/%d/%Y');
ELSE
RETURN DATE_FORMAT(p_date, '%Y-%m-%d');
END IF;
END //
DELIMITER ;触发器示例
用户审计触发器:
sql
-- 创建审计表
CREATE TABLE user_audit (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
action VARCHAR(20) NOT NULL,
old_data JSON,
new_data JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建插入触发器
DELIMITER //
CREATE TRIGGER trg_users_insert_audit
AFTER INSERT ON users
FOR EACH ROW
BEGIN
INSERT INTO user_audit (user_id, action, new_data)
VALUES (NEW.id, 'INSERT', JSON_OBJECT(
'username', NEW.username,
'email', NEW.email,
'first_name', NEW.first_name,
'last_name', NEW.last_name
));
END //
DELIMITER ;
-- 创建更新触发器
DELIMITER //
CREATE TRIGGER trg_users_update_audit
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
INSERT INTO user_audit (user_id, action, old_data, new_data)
VALUES (NEW.id, 'UPDATE',
JSON_OBJECT(
'username', OLD.username,
'email', OLD.email,
'first_name', OLD.first_name,
'last_name', OLD.last_name,
'active', OLD.active
),
JSON_OBJECT(
'username', NEW.username,
'email', NEW.email,
'first_name', NEW.first_name,
'last_name', NEW.last_name,
'active', NEW.active
)
);
END //
DELIMITER ;视图示例
活跃用户视图:
sql
CREATE VIEW v_active_users AS
SELECT id, username, email, first_name, last_name, created_at
FROM users
WHERE active = TRUE;订单汇总视图:
sql
CREATE VIEW v_order_summary AS
SELECT
o.id AS order_id,
o.user_id,
u.username,
o.order_date,
o.total_amount,
o.status,
COUNT(oi.id) AS item_count
FROM orders o
JOIN users u ON o.user_id = u.id
LEFT JOIN order_items oi ON o.id = oi.order_id
GROUP BY o.id, o.user_id, u.username, o.order_date, o.total_amount, o.status;命名规范检查清单
数据库和表
- [ ] 数据库名称使用小写,下划线分隔
- [ ] 表名使用复数形式,小写,下划线分隔
- [ ] 表名简短且描述性
- [ ] 避免使用保留字
列和键
- [ ] 列名使用小写,下划线分隔
- [ ] 主键使用
id - [ ] 外键使用
{referenced_table}_id格式 - [ ] 时间戳列使用
created_at和updated_at - [ ] 避免使用保留字
索引和约束
- [ ] 索引名使用
idx_{table}_{columns}格式 - [ ] 唯一索引使用
uniq_{table}_{columns}格式 - [ ] 索引名简短且描述性
- [ ] 约束名清晰表达约束类型
存储过程和函数
- [ ] 存储过程使用
sp_{action}_{object}格式 - [ ] 函数使用
fn_{action}_{object}格式 - [ ] 参数名使用
p_{name}格式 - [ ] 变量名使用
v_{name}格式
触发器和视图
- [ ] 触发器使用
trg_{table}_{event}_{action}格式 - [ ] 视图使用
v_{name}格式 - [ ] 命名清晰表达对象的用途
风格和一致性
- [ ] 保持一致的命名风格
- [ ] SQL关键字使用大写
- [ ] 避免过度缩写
- [ ] 名称长度合理
常见问题(FAQ)
Q1:如何处理多个单词的表名?
A1:
- 使用下划线分隔单词
- 使用复数形式
- 例如:
user_orders、product_categories
Q2:如何命名关联表?
A2:
- 使用两个关联表名的组合
- 按字母顺序排列
- 例如:
order_product(连接 orders 和 products 表)
Q3:如何处理缩写?
A3:
- 只使用广泛理解的缩写
- 保持缩写的一致性
- 避免模糊的缩写
- 当不确定时,使用完整单词
Q4:如何命名状态列?
A4:
- 使用
status作为列名 - 使用描述性的状态值
- 例如:
pending、processing、completed、cancelled
Q5:如何命名计算列?
A5:
- 使用描述性的名称
- 清晰表达计算逻辑
- 例如:
total_amount、subtotal、tax_amount
Q6:如何处理国际化表名?
A6:
- 使用英文表名
- 保持一致性
- 避免使用非ASCII字符
- 例如:使用
users而不是用户
Q7:如何命名历史表?
A7:
- 使用
{table_name}_history格式 - 例如:
user_history、order_history
Q8:如何命名临时表?
A8:
- 使用
tmp_{name}格式 - 例如:
tmp_import_users、tmp_calculation_results
