🚀 快速安装

复制以下命令并运行,立即安装此 Skill:

npx @anthropic-ai/skills install github/awesome-copilot/sql-code-review

💡 提示:需要 Node.js 和 NPM

SQL 代码审查

对 ${selection}(如果未选择,则为整个项目)执行彻底的 SQL 代码审查,重点关注安全性、性能、可维护性和数据库最佳实践。

🔒 安全分析

SQL 注入预防

-- ❌ 严重:SQL 注入漏洞
query = "SELECT * FROM users WHERE id = " + userInput;
query = f"DELETE FROM orders WHERE user_id = {user_id}";

-- ✅ 安全:参数化查询
-- PostgreSQL/MySQL
PREPARE stmt FROM 'SELECT * FROM users WHERE id = ?';
EXECUTE stmt USING @user_id;

-- SQL Server
EXEC sp_executesql N'SELECT * FROM users WHERE id = @id', N'@id INT', @id = @user_id;

访问控制与权限

  • 最小权限原则:授予所需的最小权限
  • 基于角色的访问:使用数据库角色而非直接的用户权限
  • 架构安全:适当的架构所有权和访问控制
  • 函数/存储过程安全:审查 DEFINER 与 INVOKER 权限

数据保护

  • 敏感数据暴露:避免在包含敏感列的表上使用 SELECT *
  • 审计日志:确保敏感操作被记录
  • 数据脱敏:使用视图或函数对敏感数据进行脱敏
  • 加密:验证敏感数据是否加密存储

⚡ 性能优化

查询结构分析

-- ❌ 错误:低效的查询模式
SELECT DISTINCT u.* 
FROM users u, orders o, products p
WHERE u.id = o.user_id 
AND o.product_id = p.id
AND YEAR(o.order_date) = 2024;

-- ✅ 正确:优化后的结构
SELECT u.id, u.name, u.email
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.order_date >= '2024-01-01' 
AND o.order_date < '2025-01-01';

索引策略审查

  • 缺失索引:识别需要创建索引的列
  • 过度索引:查找未使用或冗余的索引
  • 复合索引:为复杂查询创建多列索引
  • 索引维护:检查是否存在碎片化或过时的索引

连接优化

  • 连接类型:验证是否使用了适当的连接类型(INNER vs LEFT vs EXISTS)
  • 连接顺序:优先处理能产生较小结果集的连接
  • 笛卡尔积:识别并修复缺失的连接条件
  • 子查询与连接:选择最高效的方法

聚合和窗口函数

-- ❌ 错误:低效的聚合
SELECT user_id, 
       (SELECT COUNT(*) FROM orders o2 WHERE o2.user_id = o1.user_id) as order_count
FROM orders o1
GROUP BY user_id;

-- ✅ 正确:高效的聚合
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id;

🛠️ 代码质量与可维护性

SQL 风格与格式

-- ❌ 错误:糟糕的格式和风格
select u.id,u.name,o.total from users u left join orders o on u.id=o.user_id where u.status='active' and o.order_date>='2024-01-01';

-- ✅ 正确:清晰、易读的格式
SELECT u.id,
       u.name,
       o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.status = 'active'
  AND o.order_date >= '2024-01-01';

命名约定

  • 一致的命名:表、列、约束遵循一致的模式
  • 描述性名称:为数据库对象使用清晰、有意义的名称
  • 保留字:避免使用数据库保留字作为标识符
  • 大小写敏感性:在整个模式中保持大小写一致

模式设计审查

  • 规范化:适当的规范化级别(避免过度/不足规范化)
  • 数据类型:为存储和性能选择最佳数据类型
  • 约束:正确使用主键、外键、检查、非空约束
  • 默认值:为列设置适当的默认值

🗄️ 特定数据库最佳实践

PostgreSQL

-- 对 JSON 数据使用 JSONB
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    data JSONB NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 为 JSONB 查询创建 GIN 索引
CREATE INDEX idx_events_data ON events USING gin(data);

-- 对多值列使用数组类型
CREATE TABLE tags (
    post_id INT,
    tag_names TEXT[]
);

MySQL

-- 使用适当的存储引擎
CREATE TABLE sessions (
    id VARCHAR(128) PRIMARY KEY,
    data TEXT,
    expires TIMESTAMP
) ENGINE=InnoDB;

-- 针对 InnoDB 优化
ALTER TABLE large_table 
ADD INDEX idx_covering (status, created_at, id);

SQL Server

-- 使用适当的数据类型
CREATE TABLE products (
    id BIGINT IDENTITY(1,1) PRIMARY KEY,
    name NVARCHAR(255) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    created_at DATETIME2 DEFAULT GETUTCDATE()
);

-- 为分析场景创建列存储索引
CREATE COLUMNSTORE INDEX idx_sales_cs ON sales;

Oracle

-- 使用序列实现自增
CREATE SEQUENCE user_id_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE users (
    id NUMBER DEFAULT user_id_seq.NEXTVAL PRIMARY KEY,
    name VARCHAR2(255) NOT NULL
);

🧪 测试与验证

数据完整性检查

-- 验证参照完整性
SELECT o.user_id 
FROM orders o 
LEFT JOIN users u ON o.user_id = u.id 
WHERE u.id IS NULL;

-- 检查数据一致性
SELECT COUNT(*) as inconsistent_records
FROM products 
WHERE price < 0 OR stock_quantity < 0;

性能测试

  • 执行计划:审查查询执行计划
  • 负载测试:使用真实数据量测试查询
  • 压力测试:验证并发负载下的性能
  • 回归测试:确保优化不会破坏功能

📊 常见反模式

N+1 查询问题

-- ❌ 错误:应用代码中的 N+1 查询
for user in users:
    orders = query("SELECT * FROM orders WHERE user_id = ?", user.id)

-- ✅ 正确:单个优化查询
SELECT u.*, o.*
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

过度使用 DISTINCT

-- ❌ 错误:DISTINCT 掩盖了连接问题
SELECT DISTINCT u.name 
FROM users u, orders o 
WHERE u.id = o.user_id;

-- ✅ 正确:不使用 DISTINCT 的正确连接
SELECT u.name
FROM users u
INNER JOIN orders o ON u.id = o.user_id
GROUP BY u.name;

WHERE 子句中函数误用

-- ❌ 错误:函数阻止索引使用
SELECT * FROM orders 
WHERE YEAR(order_date) = 2024;

-- ✅ 正确:范围条件使用索引
SELECT * FROM orders 
WHERE order_date >= '2024-01-01' 
  AND order_date < '2025-01-01';

📋 SQL 审查清单

安全性

  • 所有用户输入都已参数化
  • 没有使用字符串拼接构建动态 SQL
  • 适当的访问控制和权限
  • 敏感数据得到适当保护
  • SQL 注入攻击向量已被消除

性能

  • 频繁查询的列存在索引
  • 没有不必要的 SELECT * 语句
  • JOIN 已优化并使用适当类型
  • WHERE 子句具有选择性并能使用索引
  • 子查询已优化或转换为 JOIN

代码质量

  • 一致的命名约定
  • 正确的格式和缩进
  • 对复杂逻辑有有意义的注释
  • 使用了适当的数据类型
  • 实现了错误处理

模式设计

  • 表已适当规范化
  • 约束强制执行数据完整性
  • 索引支持查询模式
  • 定义了外键关系
  • 默认值设置得当

🎯 审查输出格式

问题模板

## [优先级] [类别]: [简短描述]

**位置**: [表/视图/存储过程名称以及行号(如适用)]
**问题**: [问题的详细解释]
**安全风险**: [如果适用 - 注入风险、数据暴露等]
**性能影响**: [查询成本、执行时间影响]
**建议**: [带有代码示例的具体修复方案]

**之前**:
```sql
-- 有问题的 SQL

之后:

-- 改进后的 SQL

预期改进: [性能提升、安全收益]


### 总结评估
- **安全评分**: [1-10] - SQL 注入防护、访问控制
- **性能评分**: [1-10] - 查询效率、索引使用
- **可维护性评分**: [1-10] - 代码质量、文档
- **模式质量评分**: [1-10] - 设计模式、规范化

### 三大优先操作
1. **[关键安全修复]**: 解决 SQL 注入漏洞
2. **[性能优化]**: 添加缺失的索引或优化查询
3. **[代码质量]**: 改进命名约定和文档

专注于提供可操作的、与数据库无关的建议,同时突出特定于平台的优化和最佳实践。

📄 原始文档

完整文档(英文):

https://skills.sh/github/awesome-copilot/sql-code-review

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。