数据库 MCP 查询与写回
数据库 MCP 让 AI 能够直接查询和操作数据库,无需先导出 CSV 再手动分析。本节讲解安全的数据库访问设计,以及常见的查询和写回场景。
安全优先:只读与读写的边界
数据库操作的黄金原则:先只读,按需升级。
graph TD
A[数据库访问需求] --> B{操作类型}
B -- 分析/报表 --> C["只读连接
readonly_user"] B -- 数据录入/更新 --> D{操作频率} D -- 低频,需人工确认 --> E["读写连接
+ 操作前确认提示"] D -- 高频自动化 --> F["独立的 ETL 脚本
不通过 MCP"] C --> C1["SELECT, EXPLAIN, SHOW"] E --> E1["INSERT, UPDATE(限定表)
禁止 DROP, TRUNCATE"] F --> F1["不推荐用 MCP
使用专用数据管道"]
readonly_user"] B -- 数据录入/更新 --> D{操作频率} D -- 低频,需人工确认 --> E["读写连接
+ 操作前确认提示"] D -- 高频自动化 --> F["独立的 ETL 脚本
不通过 MCP"] C --> C1["SELECT, EXPLAIN, SHOW"] E --> E1["INSERT, UPDATE(限定表)
禁止 DROP, TRUNCATE"] F --> F1["不推荐用 MCP
使用专用数据管道"]
PostgreSQL 只读配置实践
第一步:创建专用 MCP 用户
-- 连接到 PostgreSQL 以管理员身份执行
CREATE USER mcp_analyst WITH PASSWORD 'strong_random_password';
-- 授予连接权限
GRANT CONNECT ON DATABASE production_db TO mcp_analyst;
GRANT USAGE ON SCHEMA public TO mcp_analyst;
-- 只读权限(现有表)
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_analyst;
-- 只读权限(未来新建的表)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO mcp_analyst;
-- 验证:mcp_analyst 只能读,不能写
-- REVOKE INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public FROM mcp_analyst;
第二步:配置 MCP Server
{
"mcpServers": {
"postgres-readonly": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://mcp_analyst:strong_random_password@localhost:5432/production_db"
]
}
}
}
常用查询场景
场景一:业务数据快速分析
提示:
请查询数据库,回答以下问题:
1. 本月新增用户数,以及与上月相比的增长率
2. 本周订单总金额,按商品类别分组
3. 最近7天有哪些用户超过30天没有登录(即将流失)
使用高效的 SQL,不要做全表扫描,利用已有的索引。
Claude 会自动:
list_tables()— 了解表结构describe_table("users")— 查看列和索引read_query("SELECT ...")— 执行具体查询- 整合多个查询结果,给出中文分析报告
场景二:数据质量检查
提示:
检查 orders 表的数据质量:
1. 是否有 NULL 值(在哪些列?占比多少?)
2. 是否有重复的 order_id
3. amount 列是否有负值或异常大的值(超过合理范围)
4. created_at 是否有未来日期(数据录入错误)
以 Markdown 报告格式输出,包含具体的 SQL 查询和结果。
场景三:跨表关联分析
提示:
分析用户购买行为:
1. 找出购买次数 >= 5 次的忠诚用户
2. 分析这些用户的平均客单价和首购到复购的平均时间
3. 与普通用户(购买1次)对比以上指标
4. 输出可用于运营活动的用户 ID 列表(保存到文件)
SQLite 本地数据工作流
SQLite 特别适合作为本地数据中转站:
sequenceDiagram
participant F as Filesystem MCP
participant DB as SQLite MCP
participant C as Claude
C->>F: read_file("raw_export.csv")
F-->>C: CSV 内容
C->>DB: create_table("CREATE TABLE raw_data (...)")
C->>DB: write_query("INSERT INTO raw_data ...")
C->>DB: read_query("SELECT ... GROUP BY ... ORDER BY ...")
DB-->>C: 分析结果
C->>F: write_file("analysis_report.md", 报告内容)
建立本地分析数据库的标准提示:
请帮我建立一个本地分析数据库:
1. 读取 ~/ai-workspace/data/exports/ 下所有 CSV 文件
2. 为每个文件创建对应的 SQLite 表(表名 = 文件名去掉扩展名)
3. 自动推断列的数据类型(日期/数字/文本)
4. 导入数据
5. 创建常用的分析视图(如月度汇总、地区汇总)
6. 输出数据库结构摘要
写回操作的安全设计
当 MCP 需要写入数据库时,遵循以下原则:
原则一:最小权限表
-- 为 MCP 写入单独创建限制性表,而不是直接操作业务表
CREATE TABLE ai_generated_reports (
id SERIAL PRIMARY KEY,
created_at TIMESTAMP DEFAULT NOW(),
report_type VARCHAR(50),
content JSONB,
created_by VARCHAR(50) DEFAULT 'claude-mcp'
);
-- 只给 MCP 用户这一张表的写权限
GRANT INSERT ON ai_generated_reports TO mcp_writer;
原则二:软删除而非硬删除
-- 不允许 MCP 执行 DELETE
-- 改为更新状态字段
ALTER TABLE records ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE records ADD COLUMN deleted_by VARCHAR(50);
-- MCP 只执行 UPDATE,不执行 DELETE
UPDATE records
SET deleted_at = NOW(), deleted_by = 'claude-mcp'
WHERE id = ?;
原则三:操作前验证
在让 AI 执行写操作之前,加入验证步骤:
提示(写操作前必须):
1. 先 SELECT 查询将要修改的记录,展示给我看
2. 等我确认后,再执行 UPDATE/INSERT
3. 执行后,再次 SELECT 验证结果符合预期
4. 如果中间任何一步出错,立即停止并报告
本节执行清单
- [ ] 为 MCP 创建专用数据库用户,不使用管理员账号
- [ ] 分析场景只授权 SELECT,明确禁止 DDL 操作
- [ ] SQLite 用于本地数据中转,避免频繁连接生产库
- [ ] 写操作前必须展示将要修改的数据,等待人工确认