
在上一篇《SUDB 实战:一个接口,跑遍整个数据库的增删改查》中,我们演示了用一个 HTTP 接口完成 user 表的增删改查。
这一次,我们走得更深——把 SUDB 当作给 AI 用的数据库操作接口来体验:切换不同数据库、跑复杂分析查询、调用数据库扩展能力,并重点验证一个关键问题:当 AI 可以自由拼 SQL 时,如何守住安全边界?
说明:本文所有请求都在 apiSQL 公开演示环境实测,
sc字段可写任意 SQL。演示库对大部分表设为只读或受限权限——这正是让 AI 直接操作数据库时应有的姿态。如果你要在自己的环境试用,强烈建议从测试库或只读账号开始。
一、约定与鉴权
- 地址:
https://open.apisql.cn/api/demo-area/$sudb - 方法:
POST,Content-Type: application/json;charset=UTF-8 - 鉴权:
Authorization: Bearer <APIKEY>(演示 key 公开,建议存入环境变量)
export APISQL_DEMO_KEY="sk-93e23231a9c8257f2c21854531f42b0a"
请求体的关键是 meta.ds(数据源)和 meta.sc(SQL 语句)。切换数据库,只需改 ds 一个字段。
二、摸清 MySQL 这一侧
先看连的是什么库:
curl -sS -X POST "https://open.apisql.cn/api/demo-area/\$sudb" \
-H "Content-Type: application/json;charset=UTF-8" \
-H "Authorization: Bearer $APISQL_DEMO_KEY" \
--data-binary '{"meta":{"ds":"mysql","sc":"SELECT DATABASE() AS db, VERSION() AS version"}}'
{ "rows": [ { "db": "demodb1", "version": "8.0.34" } ] }
再用 information_schema 一次性看清库里所有表和规模:
--data-binary '{"meta":{"ds":"mysql","sc":"SELECT table_name, table_rows, table_comment FROM information_schema.tables WHERE table_schema = DATABASE() ORDER BY table_name"}}'
结果显示这是一个精心设计的演示库,覆盖多种典型场景:
| 表 | 行数 | 场景 |
|---|---|---|
area |
44464 | 全国行政区划(带经纬度、拼音) |
dw_dim_customer / dw_dim_product / dw_fact_sales_order |
10 / 10 / 579 | 数据仓库维度+事实表 |
ecom_order / ecom_product / ecom_inventory |
26 / 0 / 0 | 电商业务 |
ods_user / ods_role / ods_user_role |
2 / 2 / 6 | ODS 分层权限模型 |
user / user_upsert |
20 / 4 | 基础用户表 |
不用登数据库客户端,一个接口就把库的全貌摸清了。
三、复杂分析:多表 JOIN 聚合
SUDB 执行的是原生 SQL,所以数仓里的多表关联分析照样能跑。统计销售额 TOP5 的客户:
--data-binary '{"meta":{"ds":"mysql","sc":"SELECT c.customer_name, COUNT(*) AS orders, ROUND(SUM(f.amount),2) AS total FROM dw_fact_sales_order f JOIN dw_dim_customer c ON f.customer_id=c.customer_id GROUP BY c.customer_name ORDER BY total DESC LIMIT 5"}}'
{ "rows": [
{ "customer_name": "赵六", "orders": 71, "total": "486245.00" },
{ "customer_name": "张三", "orders": 71, "total": "229271.40" },
{ "customer_name": "李四", "orders": 83, "total": "218053.20" },
{ "customer_name": "王五", "orders": 71, "total": "173979.60" },
{ "customer_name": "李小红", "orders": 73, "total": "160391.40" }
] }
对 AI 来说,这意味着它能直接用一条自然语言意图 → 生成 SQL → 拿到结构化结果,无需人工为每个分析维度预先开发接口。
四、切换数据源:一个字段连上 PostgreSQL
把 ds 从 mysql 改成 postgresql,同一个接口就连到了另一个数据库:
--data-binary '{"meta":{"ds":"postgresql","sc":"SELECT version()"}}'
{ "info": { "command": "SELECT", "rowCount": 1 },
"rows": [ { "version": "PostgreSQL 13.1 (Debian ...) 64-bit" } ] }
(注意 PostgreSQL 的响应会多一个 info.command 字段,能区分执行的是 SELECT 还是写操作。)
看看 PG 这边有什么表和扩展:
--data-binary '{"meta":{"ds":"postgresql","sc":"SELECT extname, extversion FROM pg_extension ORDER BY extname"}}'
{ "rows": [
{ "extname": "hstore", "extversion": "1.7" },
{ "extname": "pg_cron", "extversion": "1.3" },
{ "extname": "pgrouting", "extversion": "3.1.0" },
{ "extname": "postgis", "extversion": "3.0.2" },
{ "extname": "postgis_raster", "extversion": "3.0.2" },
{ "extname": "postgis_topology", "extversion": "3.0.2" }
] }
这个 PG 装了 PostGIS、pgRouting、pg_cron、hstore —— 具备地理空间与路由计算能力。
五、SUDB 透传的是"完整的 SQL 能力"
既然装了 PostGIS,就来做一次真正的空间计算。area 表带有各行政区的经纬度,我们算一下"离郑州最近的 5 个省会":
--data-binary '{"meta":{"ds":"postgresql","sc":"SELECT name, ROUND((ST_Distance(ST_MakePoint(lon::float8,lat::float8)::geography, ST_MakePoint(113.665412,34.757975)::geography)/1000)::numeric,0) AS km FROM area WHERE level=1 AND lon IS NOT NULL ORDER BY km LIMIT 5"}}'
{ "rows": [
{ "name": "河南省", "km": "0" },
{ "name": "山西省", "km": "358" },
{ "name": "山东省", "km": "369" },
{ "name": "河北省", "km": "372" },
{ "name": "陕西省", "km": "437" }
] }
ST_Distance、ST_MakePoint::geography 这些 PostGIS 函数被原样执行——SUDB 不是"简化版的查询工具",你的数据库能跑什么 SQL,它就能跑什么。 DDL、DML、扩展函数,只要账号有权限,都可以。
六、重点:AI 操作数据库的安全边界
一个能执行任意 SQL 的接口交给 AI,最该担心的是:它会不会 DROP TABLE、会不会写坏数据?
我们实测了演示环境的几道防线,全部在数据库层被拦下:
① MySQL:账号权限控制
--data-binary '{"meta":{"ds":"mysql","sc":"DROP TABLE area"}}'
{ "code": "API_GATEWAY_SERVER_ERROR",
"message": "DROP command denied to user 'demo_user1'@'...' for table 'area'" }
CREATE、DROP、TRUNCATE、以及对非 user 表的写入,统统返回 command denied——因为演示账号 demo_user1 本身就没有这些权限。
② PostgreSQL:只读事务
--data-binary '{"meta":{"ds":"postgresql","sc":"CREATE TABLE ai_test_tmp (id int, note text)"}}'
{ "code": "API_GATEWAY_SERVER_ERROR",
"message": "cannot execute CREATE TABLE in a read-only transaction" }
PG 这一侧直接把连接设为只读事务,任何写操作在数据库层被拒。
③ 表级权限
--data-binary '{"meta":{"ds":"postgresql","sc":"SELECT count(*) FROM test_bigdata"}}'
{ "code": "API_GATEWAY_SERVER_ERROR", "message": "permission denied for table test_bigdata" }
连 SELECT 都能按表控制——test_bigdata 这张表就是不对这个账号开放。
这三道防线揭示了 SUDB 的安全哲学:授权不在应用层做花哨的规则,而是收敛到数据库账号权限这一唯一可信来源。 想让 AI 只读,就给它一个只读账号;想让它只能碰某几张表,就在数据库里精确授权。权限清晰、可审计,且无法被应用层的 bug 绕过。
七、给"AI + 数据库"的实践建议
SUDB 让 AI 用一个接口操作数据库变得很简单,但简单不等于放任。结合本文实测,建议:
- 从只读账号起步:让 AI 先做查询、分析、报表,跑顺了再评估是否开放写权限。
- 用独立的数据库账号:为 AI/应用单独建账号,按最小必要原则授权到表级,而非复用管理员账号。
- 敏感环境用只读事务:像演示的 PG 那样,把连接限定为只读,从机制上杜绝写操作。
- 优先在测试库验证:数据结构和查询逻辑先在测试库跑通,再接生产。
- 善用命名参数:用户/模型传入的值走
params的:命名参数,不要拼进 SQL 字符串。 - 保留日志审计:apiSQL 网关记录每次请求的 SQL、来源、耗时,异常操作有迹可循。
结语
这次深度体验里,我们用同一个接口连了 MySQL 和 PostgreSQL,跑了数仓 JOIN 分析、PostGIS 空间计算,也撞了一圈安全边界——DROP 被账号权限挡下、写操作被只读事务拒绝、越权读表被逐表拦截。
SUDB 的价值不只是"省接口",更在于它把数据库的完整能力通过一个稳定入口暴露出来,同时把安全交还给数据库账号权限这一可信基础。这样的组合,恰好适配 AI 时代"用自然语言驱动数据"的需求:能力足够强,边界足够清。
立即体验:apiSQL 官网 · 在线云平台 演示环境所有 SQL 可自由尝试,请从只读查询开始,感受 apiSQL 的能力与克制。