关于 postgresql-code-review
面向 PostgreSQL 代码审查的技能,适用于检查选定代码或整个项目。它聚焦 PostgreSQL 特有的数据类型、索引、查询、扩展、函数及安全实践。
主要功能
- 01检查 JSONB 与数组用法
- 02审查索引及查询效率
- 03检查模式、类型和约束
- 04审查函数、扩展与安全
适用场景
- 01审查 PostgreSQL 数据库变更
- 02查找 JSONB 或数组查询问题
- 03检查 RLS 与权限配置
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ github/ awesome-copilot --skill postgresql-code-review安装后在 Claude Code 中输入/postgresql-code-review确认已加载。
详细介绍
PostgreSQL 代码审查助手
针对 ${selection}(若无选择则为整个项目)提供专业的 PostgreSQL 代码审查。重点关注 PostgreSQL 特有的最佳实践、反模式和独有的质量标准。
🎯 PostgreSQL 特有的审查领域
JSONB 最佳实践
-- ❌ BAD: Inefficient JSONB usage
SELECT * FROM orders WHERE data->>'status' = 'shipped'; -- No index support
-- ✅ GOOD: Indexable JSONB queries
CREATE INDEX idx_orders_status ON orders USING gin((data->'status'));
SELECT * FROM orders WHERE data @> '{"status": "shipped"}';
-- ❌ BAD: Deep nesting without consideration
UPDATE orders SET data = data || '{"shipping":{"tracking":{"number":"123"}}}';
-- ✅ GOOD: Structured JSONB with validation
ALTER TABLE orders ADD CONSTRAINT valid_status
CHECK (data->>'status' IN ('pending', 'shipped', 'delivered'));
数组操作审查
-- ❌ BAD: Inefficient array operations
SELECT * FROM products WHERE 'electronics' = ANY(categories); -- No index
-- ✅ GOOD: GIN indexed array queries
CREATE INDEX idx_products_categories ON products USING gin(categories);
SELECT * FROM products WHERE categories @> ARRAY['electronics'];
-- ❌ BAD: Array concatenation in loops
-- This would be inefficient in a function/procedure
-- ✅ GOOD: Bulk array operations
UPDATE products SET categories = categories || ARRAY['new_category']
WHERE id IN (SELECT id FROM products WHERE condition);
PostgreSQL Schema 设计审查
-- ❌ BAD: Not using PostgreSQL features
CREATE TABLE users (
id INTEGER,
email VARCHAR(255),
created_at TIMESTAMP
);
-- ✅ GOOD: PostgreSQL-optimized schema
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
email CITEXT UNIQUE NOT NULL, -- Case-insensitive email
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}',
CONSTRAINT valid_email CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
);
-- Add JSONB GIN index for metadata queries
CREATE INDEX idx_users_metadata ON users USING gin(metadata);
自定义类型和域
-- ❌ BAD: Using generic types for specific data
CREATE TABLE transactions (
amount DECIMAL(10,2),
currency VARCHAR(3),
status VARCHAR(20)
);
-- ✅ GOOD: PostgreSQL custom types
CREATE TYPE currency_code AS ENUM ('USD', 'EUR', 'GBP', 'JPY');
CREATE TYPE transaction_status AS ENUM ('pending', 'completed', 'failed', 'cancelled');
CREATE DOMAIN positive_amount AS DECIMAL(10,2) CHECK (VALUE > 0);
CREATE TABLE transactions (
amount positive_amount NOT NULL,
currency currency_code NOT NULL,
status transaction_status DEFAULT 'pending'
);
🔍 PostgreSQL 特有的反模式
性能反模式
- 未使用 PostgreSQL 特有的索引:未针对合适的数据类型使用 GIN/GiST
- 误用 JSONB:将 JSONB 当作简单的字符串字段处理
- 忽略数组操作符:使用低效的数组操作
- 分区键选择不当:未有效利用 PostgreSQL 分区
Schema 设计问题
- 未使用 ENUM 类型:对取值范围有限的值使用 VARCHAR
- 忽略约束:缺少用于数据校验的 CHECK 约束
- 数据类型错误:使用 VARCHAR 而非 TEXT 或 CITEXT
- 缺少 JSONB 结构:JSONB 无结构且未进行校验
函数和触发器问题
-- ❌ BAD: Inefficient trigger function
CREATE OR REPLACE FUNCTION update_modified_time()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW(); -- Should use TIMESTAMPTZ
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- ✅ GOOD: Optimized trigger function
CREATE OR REPLACE FUNCTION update_modified_time()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Set trigger to fire only when needed
CREATE TRIGGER update_modified_time_trigger
BEFORE UPDATE ON table_name
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE FUNCTION update_modified_time();
📊 PostgreSQL 扩展使用审查
扩展最佳实践
-- ✅ Check if extension exists before creating
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
-- ✅ Use extensions appropriately
-- UUID generation
SELECT uuid_generate_v4();
-- Password hashing
SELECT crypt('password', gen_salt('bf'));
-- Fuzzy text matching
SELECT word_similarity('postgres', 'postgre');
🛡️ PostgreSQL 安全审查
行级安全(RLS)
-- ✅ GOOD: Implementing RLS
ALTER TABLE sensitive_data ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_data_policy ON sensitive_data
FOR ALL TO application_role
USING (user_id = current_setting('app.current_user_id')::INTEGER);
权限管理
-- ❌ BAD: Overly broad permissions
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app_user;
-- ✅ GOOD: Granular permissions
GRANT SELECT, INSERT, UPDATE ON specific_table TO app_user;
GRANT USAGE ON SEQUENCE specific_table_id_seq TO app_user;
🎯 PostgreSQL 代码质量检查清单
Schema 设计
- 使用合适的 PostgreSQL 数据类型(CITEXT、JSONB、数组)
- 对受约束的值利用 ENUM 类型
- 实现恰当的 CHECK 约束
- 使用 TIMESTAMPTZ 而非 TIMESTAMP
- 为可复用的约束定义自定义域
性能考量
- 合适的索引类型(JSONB/数组用 GIN,范围用 GiST)
- JSONB 查询使用包含操作符(@>、?)
- 数组操作使用 PostgreSQL 特有的操作符
- 恰当使用窗口函数和 CTE
- 高效使用 PostgreSQL 特有的函数
PostgreSQL 特性利用
- 在合适的地方使用扩展
- 在有收益时用 PL/pgSQL 实现存储过程
- 利用 PostgreSQL 的高级 SQL 特性
- 使用 PostgreSQL 特有的优化技术
- 在函数中实现恰当的错误处理
安全与合规
- 在需要的地方实现行级安全(RLS)
- 恰当的角色和权限管理
- 使用 PostgreSQL 内置的加密函数
- 利用 PostgreSQL 特性实现审计追踪
📝 PostgreSQL 特有的审查指南
- 数据类型优化:确保恰当使用 PostgreSQL 特有的类型
- 索引策略:审查索引类型,确保利用 PostgreSQL 特有的索引
- JSONB 结构:校验 JSONB schema 设计及查询模式
- 函数质量:审查 PL/pgSQL 函数的效率与最佳实践
- 扩展使用:核实 PostgreSQL 扩展的使用是否恰当
- 性能特性:检查 PostgreSQL 高级特性的利用情况
- 安全实现:审查 PostgreSQL 特有的安全特性
重点关注 PostgreSQL 的独特能力,确保代码充分利用 PostgreSQL 的独到之处,而不是将其当作通用 SQL 数据库。
评论
支持 Markdown