【小白教程】用Neo4j图数据库优化Text2SQL:零基础构建语义关系图谱,提升大模型SQL生成准确率
本文介绍如何使用Neo4j构建数据库语义关系图谱,解决Text2SQL中表关系理解问题。通过自动提取MySQL表结构、人工定义表间关系,将数据库结构转化为图模型,使大模型能理解表间语义关联。方法显著提升SQL生成准确率,文章提供了完整的环境配置、数据提取、图谱构建代码及开源项目,帮助开发者快速集成到实际应用中。
前言
在大模型驱动的智能数据时代,Text2SQL 的准确性严重依赖对表结构和表间关系的理解。传统方法依赖 Prompt 工程或 Schema 描述,效果不稳定。
本文带你用 Neo4j 构建“数据库语义图谱”,让大模型“看得懂关系”,显著提升 SQL 生成准确率!
💡 核心思想:将 MySQL 表结构 + 人工定义的关系 → 写入 Neo4j → 供大模型检索/推理 → 生成更精准 SQL
🧭 本文流程一览
- ✅ 环境配置 —— 安装依赖 & 配置数据库连接
- 📊 自动提取表结构 —— 从 MySQL 动态获取字段、主键、外键
- 🔗 人工定义表关系 —— 补充业务语义,构建完整图谱
- 🧱 写入 Neo4j —— 创建节点、关系、约束
- ▶️ 一键运行主函数 —— 自动化构建图谱
- 🎁 开源项目推荐 —— 快速集成到你的大模型应用!
1️⃣ 环境配置
1.1.安装neo4j
docker run -d \
--name neo4j-apoc \
-p 7474:7474 \
-p 7687:7687 \
-v ./volume/neo4j/data:/data \
-v ./volume/neo4j/plugins:/plugins \
-e apoc.export.file.enabled=true \
-e apoc.import.file.enabled=true \
-e apoc.import.file.use_neo4j_config=true \
-e NEO4J_AUTH=neo4j/neo4j123 \
neo4j:5.26.11-ubi9
1.2.安装必要依赖
pip install pymysql py2neo
1.3.MySQL 配置
MYSQL_CONFIG = {
"host": "localhost",
"port": 13006,
"user": "root",
"password": "your_password", # ← 替换为你的密码
"database": "text2sql_db",
"charset": "utf8mb4",
}
1.4.Neo4j 配置
NEO4J_URI = "bolt://localhost:7687"
NEO4J_USER = "neo4j"
NEO4J_PASSWORD = "your_password"# ← 替换为你的密码
1.5.数据库连接函数
from py2neo import Graph
import pymysql
def connect_mysql():
return pymysql.connect(**MYSQL_CONFIG)
def connect_neo4j():
return Graph(NEO4J_URI, auth=(NEO4J_USER, NEOOJ_PASSWORD))

1.6.执行数据库脚本
DROP TABLE IF EXISTS `t_customers`;
CREATE TABLE `t_customers` (
`customer_id` int NOT NULL AUTO_INCREMENT COMMENT '客户ID',
`customer_name` varchar(100) NOT NULL COMMENT '客户姓名',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '电子邮箱',
`address` text COMMENT '地址',
`city` varchar(50) DEFAULT NULL COMMENT '城市',
`country` varchar(50) DEFAULT '中国' COMMENT '国家',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`customer_id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客户信息表';
DROP TABLE IF EXISTS `t_order_details`;
CREATE TABLE `t_order_details` (
`detail_id` int NOT NULL AUTO_INCREMENT COMMENT '明细ID',
`order_id` int NOT NULL COMMENT '订单ID',
`product_id` int NOT NULL COMMENT '产品ID',
`quantity` int NOT NULL COMMENT '销售数量',
`unit_price` decimal(10,2) NOT NULL COMMENT '销售时的单价',
`line_total` decimal(12,2) NOT NULL COMMENT '行小计(quantity * unit_price)',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`detail_id`),
UNIQUE KEY `uk_order_product` (`order_id`,`product_id`),
KEY `product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='销售订单明细表';
DROP TABLE IF EXISTS `t_order_details`;
CREATE TABLE `t_order_details` (
`detail_id` int NOT NULL AUTO_INCREMENT COMMENT '明细ID',
`order_id` int NOT NULL COMMENT '订单ID',
`product_id` int NOT NULL COMMENT '产品ID',
`quantity` int NOT NULL COMMENT '销售数量',
`unit_price` decimal(10,2) NOT NULL COMMENT '销售时的单价',
`line_total` decimal(12,2) NOT NULL COMMENT '行小计(quantity * unit_price)',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`detail_id`),
UNIQUE KEY `uk_order_product` (`order_id`,`product_id`),
KEY `product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='销售订单明细表';
DROP TABLE IF EXISTS `t_order_details`;
CREATE TABLE `t_order_details` (
`detail_id` int NOT NULL AUTO_INCREMENT COMMENT '明细ID',
`order_id` int NOT NULL COMMENT '订单ID',
`product_id` int NOT NULL COMMENT '产品ID',
`quantity` int NOT NULL COMMENT '销售数量',
`unit_price` decimal(10,2) NOT NULL COMMENT '销售时的单价',
`line_total` decimal(12,2) NOT NULL COMMENT '行小计(quantity * unit_price)',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`detail_id`),
UNIQUE KEY `uk_order_product` (`order_id`,`product_id`),
KEY `product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='销售订单明细表';
2️⃣ 自动提取 MySQL 表结构(智能识别主外键)
def get_tables_from_database(connection):
"""自动扫描数据库,提取表名、字段、主键/外键标记"""
tables = {}
with connection.cursor() as cursor:
cursor.execute("SHOW TABLES")
table_names = [row[0] for row in cursor.fetchall()]
for table_name in table_names:
cursor.execute(f"SHOW COLUMNS FROM {table_name}")
columns = cursor.fetchall()
fields = []
for col in columns:
field_name = col[0]
key_type = col[3] # PRI=主键, MUL=外键候选
if key_type == "PRI":
fields.append(f"{field_name} [主键]")
elif key_type == "MUL":
fields.append(f"{field_name} [外键]")
else:
fields.append(field_name)
tables[table_name] = {"name": table_name, "fields": fields}
return tables
🌟 优势:无需手动维护字段列表,自动感知数据库变更!
3️⃣ 手动定义表间关系(补充业务语义)
⚠️ 自动提取无法识别业务逻辑关系,需人工补充!
RELATIONSHIPS = [
{
"from_table": "t_customers",
"to_table": "t_sales_orders",
"description": "客户创建销售订单",
"field_relation": "customer_id → order.customer_id",
},
{
"from_table": "t_sales_orders",
"to_table": "t_order_details",
"description": "订单包含多个明细项",
"field_relation": "order_id → detail.order_id",
},
{
"from_table": "t_products",
"to_table": "t_order_details",
"description": "产品属于订单明细",
"field_relation": "product_id → detail.product_id",
},
{
"from_table": "t_user",
"to_table": "t_user_qa_record",
"description": "用户产生问答记录",
"field_relation": "id → record.user_id",
},
]
✍️ 建议:description 用自然语言描述,方便大模型理解!
4️⃣ 写入 Neo4j 图数据库
4.1.创建唯一性约束(防止重复)
def create_constraints(graph):
graph.run("CREATE CONSTRAINT IF NOT EXISTS FOR (t:Table) REQUIRE t.name IS UNIQUE")
print("✅ 节点唯一约束已创建")
4.2.创建表节点(包含字段信息)
def create_table_nodes(graph, tables):
for table_name, info in tables.items():
graph.run(
"""
MERGE (t:Table {name: $name})
SET t.label = $label, t.fields = $fields
""",
name=info["name"],
label=table_name,
fields=info["fields"]
)
print("✅ 表节点创建完成!共创建 %d 个表节点" % len(tables))
4.3.创建表关系(带语义描述)
def create_table_relationships(graph):
for rel in RELATIONSHIPS:
graph.run(
"""
MATCH (from:Table {name: $from_table})
MATCH (to:Table {name: $to_table})
MERGE (from)-[r:REFERENCES {
description: $description,
field_relation: $field_relation
}]->(to)
""",
from_table=rel["from_table"],
to_table=rel["to_table"],
description=rel["description"],
field_relation=rel["field_relation"]
)
print("✅ 表关系创建完成!共创建 %d 条关系" % len(RELATIONSHIPS))
5️⃣ 主函数:一键构建图谱!
def main():
print("🚀 开始构建 Text2SQL 语义图谱...")
mysql_conn = connect_mysql()
neo4j_graph = connect_neo4j()
try:
# 步骤1:获取表结构
tables = get_tables_from_database(mysql_conn)
print(f"📊 检测到 {len(tables)} 张数据表")
# 步骤2:清空旧数据(谨慎操作!)
print("🗑️ 清空 Neo4j 中的旧数据...")
neo4j_graph.delete_all()
# 步骤3:创建约束
create_constraints(neo4j_graph)
# 步骤4:创建表节点
create_table_nodes(neo4j_graph, tables)
# 步骤5:创建表关系
create_table_relationships(neo4j_graph)
print("🎉 图谱构建完成!现在可用 Cypher 查询或供大模型调用")
except Exception as e:
print(f"❌ 构建失败: {str(e)}")
raise
finally:
mysql_conn.close()
print("🔌 数据库连接已关闭")
if __name__ == "__main__":
main()
6️⃣ 根据表名称查询关系
from py2neo import Graph
import os
def test_get_table_relationships():
"""
从 Neo4j 图数据库中查询预定义表之间的 REFERENCES 关系。
表名已写死在代码中,数据库连接信息从环境变量读取。
:return: list of dict,每个 dict 包含 from_table, relationship, to_table
"""
# 从环境变量读取数据库配置
NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687")
NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "neo4j123")
table_names = ["t_customers", "t_sales_orders", "t_products", "t_order_details"]
# 连接图数据库
graph = Graph(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
# Cypher 查询语句
query = """
MATCH (t1:Table)-[r:REFERENCES]-(t2:Table)
WHERE t1.name IN $table_names
AND t2.name IN $table_names
AND t1.name < t2.name
RETURN
t1.name AS from_table,
r.field_relation AS relationship,
t2.name AS to_table
"""
# 如果没有表名,直接返回空结果(虽然这里不会为空)
if not table_names:
return []
# 执行查询
try:
result = graph.run(query, table_names=table_names).data()
print("查询结果:", result)
return result
except Exception as e:
print(f"[ERROR] 查询图数据库失败: {e}")
return []
PASSED [100%]查询结果: [{'from_table': 't_customers', 'relationship': 'customer_id references customer_id', 'to_table': 't_sales_orders'}, {'from_table': 't_order_details', 'relationship': 'order_id references order_id', 'to_table': 't_sales_orders'}, {'from_table': 't_order_details', 'relationship': 'product_id references product_id', 'to_table': 't_products'}]
🌈 项目亮点
- ✅ 集成 MCP 多智能体架构
- ✅ 支持 Dify / LangChain / LlamaIndex / Ollama / vLLM / Neo4j
- ✅ 前端采用 Vue3 + TypeScript + Vite5,现代化交互体验
- ✅ 内置 ECharts / AntV 图表问答 + CSV 表格问答
- ✅ 支持对接主流 RAG 系统 与 Text2SQL 引擎
- ✅ 轻量级 Sanic 后端,适合快速部署与二次开发
运行效果:
数据问答
数据问答
💬 结语:让 Text2SQL 不再“瞎猜”
用 Neo4j 构建语义图谱,本质是为大模型提供结构化知识库。不再依赖模糊的 Schema 描述,而是通过“图关系”让模型理解“谁关联谁”、“怎么关联”。
最后
为什么要学AI大模型
当下,⼈⼯智能市场迎来了爆发期,并逐渐进⼊以⼈⼯通⽤智能(AGI)为主导的新时代。企业纷纷官宣“ AI+ ”战略,为新兴技术⼈才创造丰富的就业机会,⼈才缺⼝将达 400 万!
DeepSeek问世以来,生成式AI和大模型技术爆发式增长,让很多岗位重新成了炙手可热的新星,岗位薪资远超很多后端岗位,在程序员中稳居前列。
与此同时AI与各行各业深度融合,飞速发展,成为炙手可热的新风口,企业非常需要了解AI、懂AI、会用AI的员工,纷纷开出高薪招聘AI大模型相关岗位。
最近很多程序员朋友都已经学习或者准备学习 AI 大模型,后台也经常会有小伙伴咨询学习路线和学习资料,我特别拜托北京清华大学学士和美国加州理工学院博士学位的鲁为民老师给大家这里给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料,这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】

AI大模型系统学习路线
在面对AI大模型开发领域的复杂与深入,精准学习显得尤为重要。一份系统的技术路线图,不仅能够帮助开发者清晰地了解从入门到精通所需掌握的知识点,还能提供一条高效、有序的学习路径。
但知道是一回事,做又是另一回事,初学者最常遇到的问题主要是理论知识缺乏、资源和工具的限制、模型理解和调试的复杂性,在这基础上,找到高质量的学习资源,不浪费时间、不走弯路,又是重中之重。
AI大模型入门到实战的视频教程+项目包
看视频学习是一种高效、直观、灵活且富有吸引力的学习方式,可以更直观地展示过程,能有效提升学习兴趣和理解力,是现在获取知识的重要途径
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
海量AI大模型必读的经典书籍(PDF)
阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。
600+AI大模型报告(实时更新)
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
AI大模型面试真题+答案解析
我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】

更多推荐
所有评论(0)