用自然语言查询数据
当前阅读:进阶视角
本单元目标
学完本单元后,你将能够使用自然语言直接向数据库提问并获取结构化查询结果,理解 Text-to-SQL 的基本原理与适用边界,并能独立配置一个可用的自然语言查询环境。
概念讲解
Text-to-SQL 是一种将人类自然语言问题自动转换为 SQL 查询语句的技术。它并不是简单地做关键词匹配,而是通过大语言模型理解你的意图,再结合数据库的表结构信息(schema)生成合法的查询代码。你可以把它理解为一个“翻译官”:你说“上个月华东区销量最高的三个产品是什么”,它翻译成 `SELECT product, SUM(sales) FROM orders WHERE region='华东' AND month = DATE_SUB(CURDATE(), INTERVAL 1 MONTH) GROUP BY product ORDER BY SUM(sales) DESC LIMIT 3;`。
但这里有个关键前提:模型并不“看”数据本身,它只“读”你的表结构(字段名、类型、注释)和少量示例数据。因此,字段命名是否清晰、表注释是否完整,直接决定了翻译质量。例如,如果表里有一个字段叫 `crt_tm`,模型很难猜出它是“创建时间”,除非你在注释里写明。此外,Text-to-SQL 适合查询明确的聚合、筛选、排序类问题,但不适合需要业务背景判断的模糊问题——比如“哪些客户比较重要”这种问题,模型无法替你定义“重要”。
当前主流实现方式有两种:一是直接调用支持 SQL 生成的大模型 API(如 GPT-4、Claude),将 schema 注入系统提示词;二是使用开源模型(如 SQLCoder、CodeLlama)本地部署,通过 RAG 方式检索相关表结构后生成 SQL。前者简单但数据需出网,后者更安全但需要一定工程能力。
实操演练
- 准备一个 SQLite 数据库(例如 Chinook 示例库),用命令行或 DB Browser 确认其中至少有两张有关联的表,并检查字段命名是否语义清晰。
- 在 Python 环境中安装 `openai` 库,或使用你已有的 LLM API 密钥,将数据库 schema 提取为文本格式(表名、字段名、类型、主外键关系)。
- 编写一个函数,接收用户自然语言问题,将其与 schema 文本拼接成提示词,调用 LLM API 获取 SQL 语句。
- 对生成的 SQL 做基础校验(如检查是否只包含 SELECT 语句),然后在数据库连接中执行该 SQL,将结果以表格形式打印出来。
- 将上述流程封装为一个简单的命令行脚本,支持连续对话式提问,每次自动追加前一轮的修正反馈。
练习任务
- 用你的脚本对同一数据库提出至少 5 个不同复杂度的自然语言问题(包含多表 JOIN、聚合、时间过滤),记录每次生成的 SQL 是否正确,并修正 prompt 直到全部通过。
- 设计一个包含不清晰字段名的表(如 `a1`、`b2`),测试你的系统在无注释情况下能否正确推断语义,并写一段说明如何通过补充 schema 注释来提升准确率。