告别手写SQL!openEuler+MySQL8.0+大模型自研InnoAI SQL助手|NL2SQL自动查询+智能性能调优完整实战
·
一、项目前言&背景
1.1 业务痛点
日常企业数据场景存在两大核心痛点:
- 业务人员不会写SQL:运营、产品想要统计订单数据,必须依赖后端/DBA开发人员写查询,沟通成本高、报表交付慢;
- DBA重复低效工作:海量慢SQL人工分析EXPLAIN执行计划、手动设计索引,重复性运维工作占用大量精力;
- 传统NL2SQL工具安全性差:很多开源工具未做SQL拦截,存在删改表、篡改数据风险,密钥硬编码极易泄露。
1.2 项目核心价值
本项目基于openEuler国产操作系统+MySQL8.0+腾讯云TokenHub大模型聚合平台,打造轻量化一体化智能SQL工具:
- 自然语言一键生成只读SQL:仅允许
SELECT语句,自动拦截INSERT/UPDATE/DELETE/ALTER等危险操作; - 自动执行查询+AI业务解读:查询结果表格化输出,大模型自动生成通俗易懂的业务总结,替代人工报表;
- 全自动SQL性能调优:解析
EXPLAIN执行计划,定位全表扫描、文件排序等瓶颈,直接输出可执行索引创建SQL与优化后语句; - 双端交互入口:服务器终端交互式菜单 + Streamlit可视化Web面板,运维/业务人员按需使用;
- 完善安全机制:敏感账号密钥独立
.env配置文件,文件权限设置600,全程不打印明文密码。
1.3 开发周期&人员
- 开发人数:1~3人小组单人开发均可
- 总周期:3个工作日(每日8小时)
- Day1:openEuler环境部署、MySQL8.0搭建、大模型API申请、运维知识点梳理
- Day2:Python分层脚本开发、NL2SQL、SQL调优、终端主程序联调
- Day3:多场景测试、提示词优化、权限安全加固、整体验收
二、整体技术方案与四层架构
2.1 软硬件环境清单
硬件环境
| 类别 | 参数规格 | 用途 |
|---|---|---|
| 虚拟机/云ECS | CPU≥2核,内存≥4GB,磁盘≥20GB | 运行openEuler、MySQL、Python程序 |
软件环境
| 软件 | 版本 | 作用 |
|---|---|---|
| 操作系统 | openEuler/RHEL9 | 底层运行系统,国产适配 |
| MySQL | 8.0.45 | 存储电商订单测试数据order_info |
| Python | 3.11.9(源码编译) | 项目开发主语言 |
| 大模型平台 | 腾讯云TokenHub | 兼容DeepSeek V4 Pro、Qwen3.5-Plus |
| Web框架 | Streamlit | 零前端可视化网页面板 |
| Python依赖 | pymysql、python-dotenv、langchain-openai、tabulate | 数据库连接、配置读取、大模型调用、表格渲染 |
网络&账号资源
- 服务器外网可访问443端口,用于调用大模型API;
- 腾讯云账号完成实名认证,获取TokenHub API Key。
2.2 四层分层架构详解

层级1:接入交互层(双入口)
面向运维、业务、开发人员,两种使用模式完全复用底层逻辑:
- 命令行终端:
python3 main.py交互式菜单,适合服务器本地运维快速排查; - Web可视化页面:Streamlit
web_main.py,浏览器访问,图形化输入、一键复制SQL、表格展示结果,非技术人员友好。
层级2:Python程序核心层(5个核心文件,解耦设计)
main.py:项目总调度入口,封装NL2SQL查询、AI总结、SQL调优三大核心业务,终端/Web共用底层函数;mysql_client.py:数据库统一封装类,管理连接、安全校验、执行SQL、获取EXPLAIN执行计划;prompts.py:提示词工程统一管理,内置NL2SQL、SQL调优两套Prompt,附带正则提取纯净SQL工具;web_main.py:Streamlit前端页面,输入校验、页面美化、结果渲染;.env:独立配置文件,存放数据库账号、大模型密钥,敏感信息与代码隔离。
层级3:底层数据持久层
openEuler虚拟机部署MySQL8.0.45,创建testdb数据库、order_info电商订单表,预置20条测试订单数据,作为项目唯一数据源。
层级4:AI大模型服务层
腾讯云TokenHub聚合平台作为统一AI网关,一套代码无缝切换多款开源大模型,统一鉴权、计费、运维,兼容OpenAI标准接口。
三、完整环境搭建实操(openEuler)
3.1 openEuler系统初始化
1)关闭防火墙与SELinux
# 关闭SELinux永久生效
sed -i '7s/enforcing/disabled/' /etc/selinux/config
# 关闭并禁用防火墙
systemctl disable --now firewalld
systemctl status firewalld
# 修改主机名
hostnamectl set-hostname server
bash
2)时间同步+安装系统依赖
# 配置阿里云时间服务器
vim /etc/chrony.conf
server ntp.aliyun.com iburst
systemctl restart chronyd
chronyc sources
# 安装编译全套依赖
dnf install -y gcc gcc-c++ make cmake zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel libffi-devel tk-devel wget tar vim tree net-tools openssh-server
3.2 源码编译安装Python3.11.9

# 上传源码至/usr/local/src
cd /usr/local/src
tar -zxvf Python-3.11.9.tgz
cd Python-3.11.9
# 编译配置
./configure --prefix=/usr/local/python3.11 --enable-shared
make -j$(nproc) && make install
# 配置动态链接库
echo "/usr/local/python3.11/lib" > /etc/ld.so.conf.d/python311.conf
ldconfig
# 全局软链接,不覆盖系统Python
ln -s /usr/local/python3.11/bin/python3.11 /usr/local/bin/python3
ln -s /usr/local/python3.11/bin/pip3.11 /usr/local/bin/pip3
bash
# 验证安装
python3 -V
pip3 -V
# 校验SSL(大模型接口必备)
python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
配置阿里pip镜像源
mkdir ~/.pip
vim ~/.pip/pip.conf
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
# 安装项目依赖
pip3 install --upgrade pip
pip3 install pymysql python-dotenv tabulate langchain langchain-openai streamlit
3.3 MySQL8.0.45部署初始化
1)解压安装并初始化
# 上传MySQL压缩包,移动至/usr/local/mysql
tar -xvf mysql-8.0.45-linux-glibc2.28-x86_64.tar.xz
mv mysql-8.0.45-linux-glibc2.28-x86_64 /usr/local/mysql
cd /usr/local/mysql
# 创建mysql用户组与系统用户
groupadd mysql
useradd -r -g mysql -s /sbin/nologin mysql
mkdir data
chmod -R 750 data
chown -R mysql:mysql /usr/local/mysql
# 初始化数据库(保存输出的初始密码)
bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
# 后台启动
bin/mysqld_safe --user=mysql &
2)修改root密码、配置systemd服务
# 登录数据库修改密码
bin/mysql -u root -p
mysql> alter user 'root'@'localhost' identified with mysql_native_password by '123456';
mysql> flush privileges;
exit;
# 编写my.cnf配置
vim /etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
port = 3306
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
tmpdir = /tmp
socket = /tmp/mysql.sock
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
default-storage-engine=INNODB
log_error = error.log
# systemd服务文件
vim /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=notify
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE=65535
LimitNPROC=65535
Restart=on-failure
RestartPreventExitStatus=1
TimeoutSec=0
[Install]
WantedBy=multi-user.target
# 重载并开机自启
systemctl daemon-reload
systemctl enable --now mysqld.service
# 配置环境变量
echo "export PATH=$PATH:/usr/local/mysql/bin" >> ~/.bash_profile
source ~/.bash_profile
mysql -V
3)创建业务库与订单测试表
create database testdb;
use testdb;
create table order_info(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',
user_id INT COMMENT '用户ID',
order_name VARCHAR(200) COMMENT '商品名称',
pay_amount DECIMAL(10,2) COMMENT '支付金额',
create_time DATETIME COMMENT '下单时间'
) ENGINE=InnoDB COMMENT='电商订单业务表';
-- 插入20条测试数据
INSERT INTO order_info(user_id,order_name,pay_amount,create_time)
VALUES
(1001,'智能手机',2999.00,'2026-05-01 10:20:00'),
(1001,'有线入耳耳机',199.00,'2026-05-02 14:10:00'),
(1002,'14英寸轻薄笔记本电脑',5499.00,'2026-05-03 09:30:00'),
(1002,'无线蓝牙鼠标',89.00,'2026-05-03 09:35:00'),
(1003,'平板学习机',1799.00,'2026-05-04 11:05:00'),
(1003,'平板专用保护壳',49.00,'2026-05-04 11:08:00'),
(1004,'机械游戏键盘',349.00,'2026-05-05 16:42:00'),
(1004,'电竞头戴耳机',459.00,'2026-05-05 16:48:00'),
(1005,'大屏智能电视',3299.00,'2026-05-06 08:15:00'),
(1005,'电视壁挂支架',129.00,'2026-05-06 08:20:00'),
(1006,'无线快充充电器',129.00,'2026-05-03 13:22:00'),
(1006,'降噪蓝牙耳机',399.00,'2026-05-03 13:25:00'),
(1007,'电竞显示器',1899.00,'2026-05-07 10:10:00'),
(1007,'显示器增高支架',79.00,'2026-05-07 10:15:00'),
(1008,'折叠平板支架',39.00,'2026-05-04 15:30:00'),
(1008,'便携充电宝',159.00,'2026-05-04 15:33:00'),
(1009,'台式游戏主机',6999.00,'2026-05-08 09:05:00'),
(1009,'电竞防滑鼠标垫',59.00,'2026-05-08 09:08:00'),
(1010,'手机钢化膜',29.00,'2026-05-05 17:12:00'),
(1010,'桌面收纳支架',45.00,'2026-05-05 17:16:00');
3.4 腾讯云TokenHub大模型API配置


- 访问腾讯云官网,注册并实名认证;
- 进入TokenHub控制台 → API Key管理 → 创建密钥,保存
sk-xxx密钥; - 模型推荐:
deepseek-v4-pro/Qwen3.5-Plus(无多余思考链,避免SQL解析报错)。
四、项目核心代码分层讲解
4.1 项目目录创建
mkdir -p /opt/mysql_ai_tools
cd /opt/mysql_ai_tools
touch main.py mysql_client.py prompts.py web_main.py .env
4.2 .env 配置文件(安全加固 chmod 600)
# MySQL数据库配置
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=123456
MYSQL_DB=testdb
# 腾讯云TokenHub大模型配置
LLM_API_KEY=sk-jUJebmj56mEQhhBep04A3AIaVlVV2NA97F45iimZ***
LLM_BASE_URL=https://tokenhub.tencentmaas.com/v1
LLM_MODEL_NAME=deepseek-v4-pro
LLM_TEMPERATURE=0
权限加固(关键安全操作)
chmod 600 /opt/mysql_ai_tools/.env
4.3 mysql_client.py 数据库封装&SQL安全拦截
核心亮点:内置危险SQL黑名单,仅放行SELECT查询,防止数据误删改;统一管理连接释放,自动获取EXPLAIN执行计划。
# -*- coding: utf-8 -*-
import pymysql
import os
import re
from dotenv import load_dotenv
load_dotenv()
class Mysql80Client:
def __init__(self):
self.host = os.getenv("MYSQL_HOST", "127.0.0.1")
self.port = int(os.getenv("MYSQL_PORT", "3306"))
self.user = os.getenv("MYSQL_USER", "root")
self.password = os.getenv("MYSQL_PASSWORD", "")
self.database = os.getenv("MYSQL_DB", "testdb")
self.conn = None
self.connect()
def connect(self):
try:
self.conn = pymysql.connect(
host=self.host,port=self.port,user=self.user,password=self.password,
database=self.database,charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor
)
except Exception as e:
raise Exception(f"数据库连接失败:{str(e)}")
@staticmethod
def _check_sql_safety(sql: str) -> None:
# 危险操作黑名单,拦截增删改、DDL语句
sql_trim = sql.strip().upper()
danger_keywords = ["INSERT", "UPDATE", "DELETE", "DROP", "ALTER", "CREATE", "TRUNCATE", "REPLACE"]
for kw in danger_keywords:
if re.search(r'\b' + re.escape(kw) + r'\b', sql_trim):
raise Exception(f"安全拦截:禁止执行 {kw} 语句,仅支持SELECT")
def execute_query(self, sql: str):
self._check_sql_safety(sql)
with self.conn.cursor() as cursor:
cursor.execute(sql)
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return columns, rows
def get_explain_plan(self, sql: str):
self._check_sql_safety(sql)
explain_sql = f"EXPLAIN {sql}"
with self.conn.cursor() as cursor:
cursor.execute(explain_sql)
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return columns, rows
def close(self):
if self.conn and not self.conn._closed:
self.conn.close()
4.4 prompts.py 提示词工程+SQL提取工具
统一管理两套Prompt,严格约束大模型输出格式,搭配正则三层匹配提取纯净SQL,解决模型输出杂乱问题。
# -*- coding: utf-8 -*-
import re
class UnifiedPrompt:
# 全局订单表结构,统一维护一处
TABLE_SCHEMA = """
表名: order_info (订单信息表)
字段说明:
- id: 订单ID (主键,BIGINT)
- user_id: 用户ID (INT)
- order_name: 商品名称 (VARCHAR)
- pay_amount: 支付金额 (DECIMAL(10,2))
- create_time: 下单时间 (DATETIME)
"""
# 自然语言转SQL提示词
NL_TO_SQL_PROMPT = f"""
你是严谨MySQL8.0工程师,根据用户业务需求生成标准SELECT语句。
表结构:{TABLE_SCHEMA}
强制规则:
1. 仅输出SELECT,禁止任何增删改、建表语句;
2. 只能使用给定字段,禁止编造字段;
3. SQL关键字大写,中文别名无空格;
4. SQL包裹在```sql ```代码块,不输出多余解释文字;
用户需求:{{user_input}}
"""
# SQL性能调优提示词
SQL_TUNE_PROMPT = f"""
你是资深MySQL DBA,根据SQL+EXPLAIN执行计划输出优化方案。
表结构:{TABLE_SCHEMA}
待分析SQL:{{sql_input}}
执行计划数据:{{explain_data}}
输出要求:
1. 点明核心性能问题(全表扫描、文件排序、无索引等);
2. 给出可直接执行的建索引SQL;
3. 输出优化改写后的完整SQL;
4. 分点简洁输出。
"""
# 三层正则提取纯净SQL
@staticmethod
def extract_sql(response_text: str) -> str:
if not response_text:
return ""
# 优先级1:标准markdown sql代码块
match = re.search(r"```sql\s*(.*?)\s*```", response_text, re.DOTALL | re.IGNORECASE)
if match:
return match.group(1).strip()
# 优先级2:兜底匹配SELECT开头语句
match = re.search(r"(SELECT\s+.*?;)", response_text, re.DOTALL | re.IGNORECASE)
if match:
return match.group(1).strip()
return ""
prompt_helper = UnifiedPrompt()
4.5 main.py 核心调度+终端交互入口
实现两大核心业务:自然语言查询、SQL性能调优;内置SQL清洗工具,兼容各类模型输出格式,终端菜单循环交互。
完整代码见项目PDF文档,核心逻辑:
- nl2sql_query:自然语言生成SQL、执行查询、AI业务总结
- sql_tune_analyze:获取EXPLAIN、AI分析性能瓶颈、输出调优方案
- main_cli:终端交互式菜单
4.6 web_main.py Streamlit可视化网页
核心能力
- 左侧侧边栏导航,切换「数据查询」「SQL调优」两大页面;
- 输入前置校验:区分自然语言输入与SQL输入,防止用户操作混淆;
- 美化页面CSS、表格、代码复制按钮、加载动画;
- 完全复用
main.py底层业务函数,无重复开发。
4.7 Streamlit后台systemd常驻服务
vim /etc/systemd/system/mysql-ai-web.service
[Unit]
Description=InnoAI SQL Streamlit Web服务
After=network.target mysqld.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mysql_ai_tools
ExecStart=/usr/local/python3.11/bin/python3 -m streamlit run web_main.py --server.address 0.0.0.0 --server.port 8501 --server.headless true
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
# 重载并开机自启
systemctl daemon-reload
systemctl enable --now mysql-ai-web
# 查看服务器IP,浏览器访问 ip:8501
hostname -I
五、项目功能实测演示
5.1 自然语言查询测试用例
测试需求:1001、1002、1003 每个用户的订单总消费金额与订单笔数,按总消费从高到低排序
1)自动生成SQL
SELECT user_id AS 用户ID, SUM(pay_amount) AS 总消费金额, COUNT(id) AS 订单笔数
FROM order_info
WHERE user_id IN (1001, 1002, 1003)
GROUP BY user_id
ORDER BY 总消费金额 DESC
2)查询结果表格
| 用户ID | 总消费金额 | 订单笔数 |
|---|---|---|
| 1002 | 5588.00 | 2 |
| 1001 | 3198.00 | 2 |
| 1003 | 1848.00 | 2 |
3)AI自动业务总结
- 用户分层明显:1002为高价值用户,总消费5588元,客单价远超其他两位用户;
- 三位用户订单笔数均为2单,复购节奏高度相似;
- 样本数据订单数量统一,建议扩大数据范围验证用户消费规律。
5.2 SQL性能调优实测
待优化SQL
SELECT user_id AS 用户ID, SUM(pay_amount) AS 总消费金额, COUNT(id) AS 订单笔数
FROM order_info
WHERE user_id IN (1001, 1002, 1003)
GROUP BY user_id
ORDER BY 总消费金额 DESC
执行计划问题
type=ALL全表扫描、Using temporary; Using filesort临时表+文件排序,无任何索引命中。
AI输出优化方案
- 创建覆盖索引
ALTER TABLE order_info ADD INDEX idx_user_id_pay_amount (user_id, pay_amount);
- 优化改写SQL
SELECT user_id AS 用户ID, SUM(pay_amount) AS 总消费金额,COUNT(*) AS 订单笔数
FROM order_info
WHERE user_id IN (1001, 1002, 1003)
GROUP BY user_id
ORDER BY 总消费金额 DESC;
六、项目安全&稳定性设计
6.1 数据安全防护
- SQL黑白名单拦截:仅放行SELECT,自动拦截所有增删改、DDL危险语句;
- 配置文件权限隔离:
.env设置600权限,仅root可读,不打印账号密钥明文; - 数据库使用只读逻辑,无数据写入/修改操作,避免业务数据损坏。
6.2 程序稳定性保障
- 全流程异常捕获:数据库连接、大模型API、SQL语法错误统一捕获,程序不崩溃;
- 输入容错:空白输入、超长需求、无匹配数据友好提示;
- SQL标准化清洗:统一处理中文标点、全角空格、关键字粘连,解决模型输出语法报错;
- 数据库连接自动关闭,避免长连接占用资源。
6.3 系统兼容性
- 系统:openEuler/RHEL国产Linux兼容;
- 数据库:锁定MySQL8.0.45,适配InnoDB索引规范;
- 大模型:兼容所有OpenAI接口标准MaaS平台,一键切换DeepSeek/Qwen系列模型。
七、踩坑记录&解决方案
- Python编译后SSL缺失:编译时必须带上
openssl-devel依赖,否则大模型HTTPS接口调用失败; - 大模型输出携带思考链,SQL提取失败:选用不带推理思考的模型,增加正则过滤多余文本;
- Streamlit外部无法访问:启动参数添加
--server.address 0.0.0.0,开放局域网访问; - MySQL8.0认证插件报错:修改root账号认证方式为
mysql_native_password; - .env密钥泄露风险:必须执行
chmod 600,禁止其他用户读取配置文件。
八、项目拓展优化方向
- 权限精细化:增加Web页面登录鉴权,区分普通查询用户与调优管理员;
- 多表关联支持:扩展表结构,支持多表JOIN场景NL2SQL生成;
- 慢SQL批量分析:支持批量导入多条SQL,批量输出索引优化方案;
- Docker容器化:打包openEuler、MySQL、Python环境,一键部署;
- 本地私有大模型适配:兼容本地部署Qwen/DeepSeek离线模型,无需外网API;
- 导出报表:查询结果支持Excel下载,自动生成业务分析报告文件。
九、项目总结
- 落地价值:轻量化一站式AI数据库工具,零SQL基础业务人员可自主查询数据,解放DBA重复调优工作,适配中小企业轻量化数据平台;
- 技术学习点:覆盖国产openEuler运维、MySQL8.0深度运维、Python分层架构、大模型Prompt工程、NL2SQL落地、Streamlit低代码Web开发、systemd服务部署;
- 适用人群:计算机专业实训项目、运维工程师、后端开发、AI应用开发学习者完整实战案例;
- 部署门槛:低配虚拟机即可运行,3天完整从零搭建完成,代码模块化易二次开发改造。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)