跳到主内容
AIHO 2026 全新改版上线

Cursor + MCP 让 AI 直接操作数据库:从零到生产

适用场景

  • 开发时频繁需要查表结构、跑 SQL 验证
  • AI 生成代码时需要知道数据库 schema
  • 想让 AI 帮写数据库迁移文件
  • 调试慢查询,需要 AI 看真实执行计划

如果你只是偶尔查一次表结构,手动复制粘贴就够,不必上 MCP。MCP 的价值在"高频往返"场景——下面会算这笔账。

为什么用 MCP 而不是复制粘贴

传统做法:手动跑 \d table_name → 复制结果 → 粘给 Cursor → AI 生成 SQL → 手动执行验证 → 报错 → 再复制错误回去。

MCP 做法:Cursor 直接连数据库 → AI 自己查 schema → 生成 SQL → 自己执行验证 → 看到结果/报错 → 自己修正。

省的是中间的复制粘贴往返。在复杂查询调试时,这个往返可能 5-10 次,每次都要切窗口、复制、粘贴。MCP 把这个循环闭合在 AI 内部,你只看最终结果。

MCP 在这里到底做了什么

MCP(Model Context Protocol)是一层标准协议:MCP Server 把数据库能力(查表、执行 SQL、看执行计划)封装成标准化的"工具",Cursor 作为 MCP 客户端调用这些工具。AI 不是"直连数据库",而是"调用 MCP Server 暴露的受控工具"——这点很关键,意味着你能在 Server 这层卡住权限。协议原理见 什么是 MCP,生态选型见 MCP 生态实测

第一步:装 MCP PostgreSQL Server

用 Smithery 一行装好:

npx @smithery/cli install @modelcontextprotocol/server-postgres --client cursor

或手动配 Cursor Settings → MCP → Add Server,编辑 .cursor/mcp.json

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://user:***@localhost:5432/mydb"
      }
    }
  }
}

重启 Cursor,Agent 模式现在能查数据库了。验证:在 Agent 里问"列出所有表",能返回表名就说明连通了。

第二步:安全配置(最重要的一步)

这一步决定了 MCP 是"提效工具"还是"事故源头"。三道防线,全部要做。

防线一:用只读账号

绝对不要用超级用户账号连 MCP。创建专用只读账号:

CREATE ROLE mcp_readonly WITH LOGIN PASSWORD '***';
GRANT USAGE ON SCHEMA public TO mcp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;
-- 让未来新建的表也自动只读可见
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO mcp_readonly;

这样即使 AI 生成了 DROP TABLE,数据库层面也会直接拒绝——权限是最硬的护栏,比"在 prompt 里叮嘱 AI 别删数据"可靠一万倍。

防线二:开发/生产物理隔离

{
  "mcpServers": {
    "postgres-dev": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://mcp_readonly:***@localhost:5432/mydb_dev"
      }
    }
  }
}

只在 dev 环境配 MCP。生产数据库永远不连 MCP,连只读都不连——生产库的连接串一旦进了配置文件,就有泄露和误连风险。

防线三:敏感表用视图隔离

有些表(用户密码 hash、token、支付信息)不该让 AI 看到。用视图暴露脱敏后的子集:

CREATE SCHEMA IF NOT EXISTS public_safe;
CREATE VIEW public_safe.users_safe AS
  SELECT id, username, created_at FROM public.users;

REVOKE SELECT ON public.users FROM mcp_readonly;
GRANT SELECT ON public_safe.users_safe TO mcp_readonly;

AI 能查到用户名和注册时间,但碰不到密码字段。

第三步:实战用法

场景一:查 schema 生成代码

在 Cursor Agent 模式输入:

帮我写一个查询用户订单的 API,需要分页

Cursor 会:

  1. 调 MCP list_tables 看有哪些表
  2. 调 MCP describe_table 看 orders 和 users 表结构
  3. 基于真实字段生成 JOIN 查询 + 分页代码

关键区别:它用的是真实 schema,不是猜的字段名。这能消掉"AI 把 user_id 写成 userId"这类幻觉。

场景二:调试慢查询

这个查询很慢,帮我优化:
SELECT * FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending'

Cursor 会:

  1. EXPLAIN ANALYZE 看真实执行计划
  2. 发现 orders.status 上全表扫描
  3. 建议加索引并解释收益
  4. 生成 migration 文件

它看的是真实执行计划,不是"我觉得这里可能慢"。

场景三:生成迁移

给 orders 表加一个 shipping_address 字段,类型 jsonb,可空

Cursor 会:

  1. 查当前 orders 表结构(确认字段不冲突)
  2. 生成 ALTER TABLE SQL
  3. 生成 Drizzle / Prisma migration 文件
  4. 生成对应的回滚 SQL

权限边界与可写 MCP

操作只读 MCP可写 MCP
查表结构
SELECT 查询
EXPLAIN
INSERT/UPDATE/DELETE
CREATE/DROP TABLE⚠️ 需额外授权
ALTER TABLE⚠️ 需额外授权

建议:日常用只读 MCP,需要写操作时再切到可写 MCP。

如果一定要可写,加这两道闸

  1. 配两个 Server,按需切换postgres-ro(只读,默认用)和 postgres-rw(可写,临时用)。平时不挂可写的,要写时才启用,用完关掉。
  2. 可写账号也别给 DDL 权限:给 INSERT/UPDATE/DELETE 就够日常用,DROP/ALTER 这类结构变更走人工执行 migration,不交给 AI 直接跑。
-- 可写但不能改结构、不能删表
CREATE ROLE mcp_readwrite WITH LOGIN PASSWORD '***';
GRANT USAGE ON SCHEMA public TO mcp_readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO mcp_readwrite;
-- 注意:故意不给 CREATE / DROP / ALTER 权限

踩坑记录

  1. MCP Server 默认无连接池——AI 连续查询会打满 PG 连接数。前面挂 PgBouncer 做连接池,或限制并发。
  2. 大表 SELECT * 卡死——AI 可能跑 SELECT * FROM huge_table。给只读账号设语句超时兜底:
    ALTER ROLE mcp_readonly SET statement_timeout = '10s';
    
  3. 不支持事务——Cursor MCP 每条 SQL 独立执行,不能 BEGIN/COMMIT 包多步。需要原子性的多步操作走存储过程或应用层。
  4. DATABASE_URL 泄露——.cursor/mcp.json 含明文连接串,极易被 git 提交上去。务必加进 .gitignore,用本地覆盖文件 .cursor/mcp.local.json 放真实凭据。
  5. AI 仍会偶尔编字段名——即便连了 MCP,长对话里它可能凭记忆写字段而不重新查。关键查询让它"先 describe_table 再写 SQL"。

延伸阅读