云计算百科
云计算领域专业知识百科平台

多表智能生成需求分析与实现方案

多表智能生成需求分析与实现方案

作为低代码平台的核心能力升级,我们需要将现有的“单表文字转结构”接口扩展为“多表系统级生成”,支持用户通过自然语言描述,自动生成一套完整的多表数据库模型(例如OA系统、进销存等)。以下将详细拆解需求,并给出从后端到前端的完整实现方案。


1. 需求拆分

1.1 核心目标
  • 输入:用户输入一段自然语言,描述一个业务系统的需求(例如:“设计一个简单的OA系统,包含员工、部门、请假申请,员工属于部门,请假申请由员工发起”)。

  • 输出:生成一组具有关联关系的数据库表结构,并以可视化方式展示,允许用户确认、修改,最终落地到平台的元数据库,并自动创建物理表。

1.2 功能模块分解
模块子功能说明
1. 大模型交互 1.1 设计提示词模板,引导模型输出标准格式的多表描述 要求模型返回 JSON 格式,包含表列表、字段、关系、索引等信息
1.2 调用现有大模型接口,传入用户需求,获取原始响应 复用已有接口,但需要适配多表输出
1.3 解析并验证模型输出,处理异常情况(格式错误、字段不全等) 加入重试或降级机制
2. 后端逻辑 2.1 将模型输出转换为内部数据模型(TableSchema 对象集合) 定义清晰的 Java/Python 实体类
2.2 自动生成物理 DDL(含外键约束) 支持主流数据库(MySQL、PostgreSQL)
2.3 将表结构元数据存入平台元数据库(用于后续代码生成、UI渲染) 包括表名、字段、关系、索引、备注等
2.4 提供 API:接收文字,返回生成的表结构预览数据 GET/POST 接口
2.5 提供 API:用户确认后,执行建表并保存元数据 事务性操作,确保元数据与物理表一致
3. 前端交互 3.1 输入区域:多行文本框,支持示例填充 类似 ChatGPT 的输入框
3.2 生成结果展示:以表格列表形式展示所有表及字段 可折叠展开,支持字段级编辑
3.3 关系可视化:用简易 ER 图或列表展示外键关系 辅助用户理解
3.4 编辑功能:允许用户增删改表、字段、关系 提供“添加字段”、“删除表”、“设置外键”等操作
3.5 确认/取消按钮:用户调整满意后,一键应用 触发后端建表
4. 扩展与优化 4.1 支持自定义数据类型映射(如“日期”映射为 date 或 datetime) 根据配置决定
4.2 支持生成样例数据(可选) 用于快速演示
4.3 记录生成历史,支持回溯 方便用户对比不同版本

2. 大模型提示词设计

为了让大模型稳定输出结构化的多表信息,我们需要精心设计提示词,明确输出格式。以下是一个示例提示词模板(适用于 GPT 系列):

你是一个数据库设计专家。请根据用户的需求,设计一套关系型数据库的表结构,并以严格的 JSON 格式输出。
需求描述:{user_input}

要求:
1. 输出必须是一个 JSON 对象,包含一个 "tables" 数组。
2. 每个表对象包含:
– "name": 表名(英文小写,下划线分隔)
– "comment": 表注释
– "columns": 字段数组,每个字段包含:
– "name": 字段名(英文小写)
– "type": 数据类型(如 int, varchar(255), date, decimal(10,2), text 等)
– "nullable": 是否可为空,true/false
– "primary": 是否主键,true/false
– "default": 默认值(可选)
– "comment": 字段注释
– "indexes": 索引数组(可选),每个索引包含:
– "name": 索引名
– "columns": 字段名数组
– "unique": 是否唯一
3. 表之间的关系用外键表示,可以在字段中通过 "foreignKey" 属性描述:
– "foreignKey": { "table": "关联表名", "column": "关联字段" }
或者单独用一个 "relations" 数组来描述,但更推荐在字段中直接标注外键。
4. 请确保表名、字段名符合命名规范,并包含必要的注释。
5. 如果需求中有明显的多对多关系,请创建中间表。

请直接输出 JSON,不要包含其他解释文字。

示例输出(基于“OA系统含员工、部门、请假申请”):

json

{
"tables": [
{
"name": "department",
"comment": "部门表",
"columns": [
{ "name": "id", "type": "int", "nullable": false, "primary": true, "comment": "部门ID" },
{ "name": "name", "type": "varchar(100)", "nullable": false, "comment": "部门名称" },
{ "name": "parent_id", "type": "int", "nullable": true, "comment": "上级部门ID", "foreignKey": { "table": "department", "column": "id" } }
],
"indexes": []
},
{
"name": "employee",
"comment": "员工表",
"columns": [
{ "name": "id", "type": "int", "nullable": false, "primary": true, "comment": "员工ID" },
{ "name": "name", "type": "varchar(50)", "nullable": false, "comment": "姓名" },
{ "name": "department_id", "type": "int", "nullable": true, "comment": "所属部门", "foreignKey": { "table": "department", "column": "id" } },
{ "name": "hire_date", "type": "date", "nullable": true, "comment": "入职日期" }
],
"indexes": []
},
{
"name": "leave_application",
"comment": "请假申请表",
"columns": [
{ "name": "id", "type": "int", "nullable": false, "primary": true, "comment": "申请ID" },
{ "name": "employee_id", "type": "int", "nullable": false, "comment": "申请人", "foreignKey": { "table": "employee", "column": "id" } },
{ "name": "start_date", "type": "date", "nullable": false, "comment": "开始日期" },
{ "name": "end_date", "type": "date", "nullable": false, "comment": "结束日期" },
{ "name": "reason", "type": "text", "nullable": true, "comment": "事由" },
{ "name": "status", "type": "varchar(20)", "nullable": false, "default": "'pending'", "comment": "状态" }
],
"indexes": [
{ "name": "idx_employee_id", "columns": ["employee_id"], "unique": false }
]
}
]
}


3. 后端详细设计

3.1 技术栈假设
  • 后端语言:Java(Spring Boot)或 Python(FastAPI)

  • 数据库:MySQL 8.0+ / PostgreSQL

  • 大模型调用:HTTP 请求(现有接口)

  • 元数据存储:MySQL 表(如 table_meta, column_meta, relation_meta)

3.2 核心数据模型

定义内部实体类(以 Java 为例):

java

// TableSchema.java
public class TableSchema {
private String name;
private String comment;
private List<ColumnSchema> columns;
private List<IndexSchema> indexes;
// getters/setters
}

public class ColumnSchema {
private String name;
private String type; // 例如 "varchar(255)"
private boolean nullable;
private boolean primary;
private String defaultValue;
private String comment;
private ForeignKey foreignKey; // 外键信息,可为空
// getters/setters
}

public class ForeignKey {
private String table; // 关联表名
private String column; // 关联字段
// getters/setters
}

public class IndexSchema {
private String name;
private List<String> columns;
private boolean unique;
// getters/setters
}

3.3 核心流程
  • 接收请求:POST /api/schema/generate 带参数 { "prompt": "…" }

  • 调用大模型:将用户提示词与预设模板组合,请求现有 LLM 接口,获取响应文本。

  • 解析 JSON:

    • 尝试解析为 TablesSchema 对象(包含 tables 数组)。

    • 验证必填字段,检查数据类型合法性(如 type 是否符合 SQL 规范)。

    • 若解析失败,返回友好错误提示,或尝试让模型重新生成(重试机制)。

  • 构建预览响应:将解析后的结构返回前端,同时生成 DDL 预览(但不实际执行)。

  • 用户确认后:调用 POST /api/schema/apply,传入前端可能修改后的最终 JSON。

    • 在事务中:先根据 JSON 生成物理表(执行 CREATE TABLE 语句),同时将元数据插入元数据库。

    • 若已有同名表,可提示冲突,或提供“覆盖/新建”选项(需谨慎)。

    • 记录操作日志。

  • 3.4 生成 DDL

    根据 TableSchema 生成 SQL 语句(以 MySQL 为例):

    java

    public String generateCreateTableSQL(TableSchema table) {
    StringBuilder ddl = new StringBuilder("CREATE TABLE `")
    .append(table.getName()).append("` (\\n");
    List<String> columnDefs = new ArrayList<>();
    List<String> primaryKeys = new ArrayList<>();

    for (ColumnSchema col : table.getColumns()) {
    StringBuilder colDef = new StringBuilder(" `")
    .append(col.getName()).append("` ").append(col.getType());
    if (!col.isNullable()) {
    colDef.append(" NOT NULL");
    }
    if (col.getDefaultValue() != null) {
    colDef.append(" DEFAULT ").append(col.getDefaultValue());
    }
    if (col.isPrimary()) {
    primaryKeys.add("`" + col.getName() + "`");
    }
    if (col.getComment() != null && !col.getComment().isEmpty()) {
    colDef.append(" COMMENT '").append(col.getComment()).append("'");
    }
    columnDefs.add(colDef.toString());
    }

    // 主键约束
    if (!primaryKeys.isEmpty()) {
    columnDefs.add(" PRIMARY KEY (" + String.join(", ", primaryKeys) + ")");
    }

    // 外键约束(在建表语句后添加,或使用单独的 ALTER 语句,这里选择后加)
    ddl.append(String.join(",\\n", columnDefs));
    ddl.append("\\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='")
    .append(table.getComment()).append("';");

    // 添加外键约束(ALTER TABLE)
    StringBuilder fkSQL = new StringBuilder();
    for (ColumnSchema col : table.getColumns()) {
    if (col.getForeignKey() != null) {
    fkSQL.append("ALTER TABLE `").append(table.getName())
    .append("` ADD FOREIGN KEY (`").append(col.getName())
    .append("`) REFERENCES `").append(col.getForeignKey().getTable())
    .append("` (`").append(col.getForeignKey().getColumn())
    .append("`);\\n");
    }
    }

    // 索引
    StringBuilder indexSQL = new StringBuilder();
    if (table.getIndexes() != null) {
    for (IndexSchema idx : table.getIndexes()) {
    indexSQL.append("CREATE ");
    if (idx.isUnique()) indexSQL.append("UNIQUE ");
    indexSQL.append("INDEX `").append(idx.getName())
    .append("` ON `").append(table.getName())
    .append("` (").append(
    idx.getColumns().stream().map(c -> "`" + c + "`").collect(Collectors.joining(", "))
    ).append(");\\n");
    }
    }

    return ddl.toString() + "\\n" + fkSQL.toString() + "\\n" + indexSQL.toString();
    }

    3.5 元数据存储设计

    在平台的元数据库中创建以下表:

    sql

    CREATE TABLE `table_meta` (
    `id` int PRIMARY KEY AUTO_INCREMENT,
    `name` varchar(100) NOT NULL COMMENT '物理表名',
    `display_name` varchar(100) COMMENT '显示名称',
    `comment` text,
    `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uniq_name` (`name`)
    );

    CREATE TABLE `column_meta` (
    `id` int PRIMARY KEY AUTO_INCREMENT,
    `table_id` int NOT NULL,
    `name` varchar(100) NOT NULL,
    `type` varchar(50) NOT NULL,
    `nullable` tinyint(1) DEFAULT 0,
    `primary` tinyint(1) DEFAULT 0,
    `default_value` varchar(255),
    `comment` text,
    `foreign_key_table` varchar(100) COMMENT '关联表名',
    `foreign_key_column` varchar(100) COMMENT '关联字段名',
    FOREIGN KEY (`table_id`) REFERENCES `table_meta`(`id`) ON DELETE CASCADE
    );

    CREATE TABLE `index_meta` (
    `id` int PRIMARY KEY AUTO_INCREMENT,
    `table_id` int NOT NULL,
    `name` varchar(100),
    `columns` text NOT NULL COMMENT '逗号分隔的字段名',
    `unique` tinyint(1) DEFAULT 0,
    FOREIGN KEY (`table_id`) REFERENCES `table_meta`(`id`) ON DELETE CASCADE
    );


    4. 前端详细设计

    4.1 界面布局

    采用左右结构或上下结构。这里建议上下布局:

    • 顶部:输入区域 + “生成”按钮 + 示例下拉

    • 中部:生成结果展示(可切换“表格视图”和“ER图预览”)

    • 底部:操作按钮(确认应用、取消、导出SQL等)

    4.2 核心组件
    • PromptInput:文本域,支持 placeholder 提示。

    • TableList:展示所有表,每个表可展开显示字段列表。支持:

      • 添加新表按钮(弹窗输入表名、注释)

      • 每个表右侧的编辑/删除图标

      • 每个字段的编辑/删除,以及添加字段按钮

    • ForeignKeyEditor:当编辑字段时,如果字段类型适合作为外键(如 int),显示“设置为外键”复选框,并选择目标表和字段。

    • ERDiagram(可选):用简单的 SVG 或 Canvas 绘制表框和连线,根据外键信息绘制。

    4.3 状态管理
    • 使用 Vue3 或 React 的响应式数据存储当前生成的 schema。

    • 当用户编辑时,实时更新本地状态,但不会自动触发后端。

    • 确认应用时,将当前 schema 发送到后端。

    4.4 与后端交互
    • 调用生成接口:POST /api/schema/generate,传递 prompt,返回 schema JSON。

    • 调用应用接口:POST /api/schema/apply,传递最终的 schema JSON。

    4.5 关键代码示例(Vue3 + Element Plus)

    vue

    <template>
    <div class="container">
    <el-input
    v-model="prompt"
    type="textarea"
    :rows="4"
    placeholder="请输入系统需求,例如:设计一个简单的OA系统,包含员工、部门、请假申请…"
    />
    <el-button type="primary" @click="generate" :loading="generating">生成</el-button>

    <div v-if="schema" class="schema-preview">
    <el-tabs>
    <el-tab-pane label="表结构">
    <div v-for="table in schema.tables" :key="table.name" class="table-card">
    <el-card>
    <template #header>
    <span>{{ table.name }} ({{ table.comment }})</span>
    <el-button type="text" @click="editTable(table)">编辑</el-button>
    <el-button type="text" @click="deleteTable(table)">删除</el-button>
    </template>
    <el-table :data="table.columns" style="width: 100%">
    <el-table-column prop="name" label="字段名" />
    <el-table-column prop="type" label="类型" />
    <el-table-column prop="nullable" label="可空">
    <template #default="{ row }">{{ row.nullable ? '是' : '否' }}</template>
    </el-table-column>
    <el-table-column prop="primary" label="主键">
    <template #default="{ row }">{{ row.primary ? '是' : '否' }}</template>
    </el-table-column>
    <el-table-column prop="comment" label="注释" />
    <el-table-column label="外键" width="120">
    <template #default="{ row }">
    <span v-if="row.foreignKey">{{ row.foreignKey.table }}.{{ row.foreignKey.column }}</span>
    </template>
    </el-table-column>
    <el-table-column label="操作" width="120">
    <template #default="{ row }">
    <el-button type="text" @click="editColumn(table, row)">编辑</el-button>
    <el-button type="text" @click="deleteColumn(table, row)">删除</el-button>
    </template>
    </el-table-column>
    </el-table>
    <el-button type="primary" size="small" @click="addColumn(table)">添加字段</el-button>
    </el-card>
    </div>
    <el-button type="success" @click="addTable">添加表</el-button>
    </el-tab-pane>
    <el-tab-pane label="ER图">简易ER图占位</el-tab-pane>
    </el-tabs>
    </div>

    <div class="actions" v-if="schema">
    <el-button type="primary" @click="applySchema">确认应用</el-button>
    <el-button @click="cancel">取消</el-button>
    </div>
    </div>
    </template>

    <script setup>
    import { ref } from 'vue'
    import axios from 'axios'

    const prompt = ref('')
    const generating = ref(false)
    const schema = ref(null)

    const generate = async () => {
    generating.value = true
    try {
    const res = await axios.post('/api/schema/generate', { prompt: prompt.value })
    schema.value = res.data
    } catch (e) {
    ElMessage.error('生成失败:' + e.message)
    } finally {
    generating.value = false
    }
    }

    const applySchema = async () => {
    try {
    await axios.post('/api/schema/apply', schema.value)
    ElMessage.success('应用成功')
    } catch (e) {
    ElMessage.error('应用失败:' + e.message)
    }
    }

    // 其他编辑方法略…
    </script>


    5. 关系处理与注意事项

    5.1 多对多关系自动识别
    • 在提示词中引导模型:遇到多对多(如“学生和课程”),应创建中间表,并在中间表中设置两个外键。

    • 若模型未自动创建,前端可提供“添加中间表”的快捷操作。

    5.2 数据类型映射
    • 可配置一个映射表,将常见中文描述(如“整数”、“字符串”、“日期”)映射到具体 SQL 类型。

    • 例如模型输出 "type": "int" 直接可用,但若输出 "type": "整数",则需要后处理转换。

    5.3 字段默认值处理
    • 注意 SQL 语法中默认值的引号问题:字符串需加单引号,数字和布尔无需。

    • 解析时可根据类型自动处理。

    5.4 表名冲突
    • 如果元数据库中已存在同名表,应在应用前提示用户选择:覆盖、重命名或跳过。

    • 覆盖可能导致数据丢失,需谨慎,通常建议仅用于开发环境。

    5.5 事务性保证
    • 应用接口应在数据库事务中执行:先插入元数据,再执行 DDL。若 DDL 失败,回滚元数据插入。

    • 注意:DDL 是隐式提交的,在 MySQL 中无法回滚,所以更好的顺序是:先创建物理表,成功后再插入元数据。如果元数据插入失败,需手动删除已创建的表(或记录日志由管理员处理)。但为了简化,可先插入元数据(设置状态为“创建中”),然后创建表,成功后更新状态。

    5.6 大模型输出质量提升
    • 可通过 few-shot 示例强化模型对 JSON 格式的遵循。

    • 增加后处理校验,如检查主键是否存在、外键引用是否存在等。

    • 若模型输出不符合要求,可尝试重新生成或提示用户手动修正。


    6. 扩展思考

    6.1 生成初始数据
    • 可在生成表结构后,让大模型再生成一批样例数据(INSERT 语句),用于快速演示。

    6.2 生成 API 与 UI
    • 结合低代码平台能力,根据生成的表结构自动生成 CRUD 页面和 API。

    6.3 迭代优化
    • 记录用户对生成结果的修改,形成反馈数据,用于微调提示词或模型。

    6.4 多轮对话
    • 支持用户通过对话逐步调整需求(例如“再增加一个角色表”),后端维护上下文状态。


    7. 总结

    通过以上需求拆分与详细设计,我们成功将单表生成扩展为多表系统生成。核心在于:定义标准化的 JSON 交换格式、健壮的解析与验证、灵活的编辑交互、可靠的元数据与物理表同步。这一功能将极大提升低代码平台的建模效率,使用户能够用自然语言快速搭建业务原型。

    接下来,团队可以按照模块逐步开发,并持续根据用户反馈优化模型提示词与编辑体验。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 多表智能生成需求分析与实现方案
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!