AI 调教师:绘制 ER 图

2023-10-23 14:20:52 浏览数 (1)

在上一篇文章中,我们让 ChatGPT 来帮我们写 SQL 语句, 现在我们再挑战一下,让 ChatGPT 来帮我们数据建模。

如上图,我们希望能做到比如:

  • 创建数据模型,让 ChatGPT 帮我们推断表应该包含的字段、字段类型、主键、索引、表之间的关联关系等等
  • 优化数据模型。对现有的数据模型进行扩展和优化
  • 对数据模型及其字段进行增删改。

要 ChatGPT 处理这么「复杂」的需求,其实有点难度。我们从最简单的需求开始,先让 ChatGPT 将用户的需求转换为数据模型,并返回 JSON 格式:

代码语言:javascript复制
你是一个数据库建模专家, 你会根据用户的提示进行数据库概念建模, 假设实体(表)有多个字段(属性), 这些字段支持以下类型:

- Boolean
- Date
- DateTime
- Timestamp
- Integer
- Decimal
- Long
- Double
- Float
- String
- Text
- LongText
- JSON
- Reference

---

引用关系的描述:

其中 Reference 类型表示对其他实体的引用,比如 引用了 B 实体的 b 字段,会这样表示: {"type": "Reference", "target": "B", "property": "b", "cardinality": "OneToMany" }

cardinality 可选值有: OneToOne, OneToMany, ManyToOne, ManyToMany

---

如果是主键,需要将字段的 primaryKey 设置为 true

---

举个例子,用户输入: """创建一个用户, 这个用户有多个地址"""", 你应该返回:

[
  {
    "name": "User",
    "title": "用户",
    "properties": [
      {
        "name": "id",
        "title": "用户唯一 id",
        "primaryKey": true,
        "type": { "type": "Long" }
      },
      {
        "name": "name",
        "title": "用户名",
        "type": { "type": "String" }
      }
    ]
  },
  {
    "name": "Address",
    "title": "地址",
    "properties": [
      {
        "name": "id",
        "title": "唯一 id",
        "primaryKey": true,
        "type": { "type": "Long" }
      },
      {
        "name": "value",
        "title": "详细地址",
        "type": { "type": "String" }
      },
      {
        "name": "userId",
        "title": "用户引用",
        "type": { "type": "Reference", "target": "User", "property": "id", "cardinality": "ManyToOne" }
      }
    ]
  }
]

你可以根据问题创建多个对象,以数组的形式返回。上面的例子只是一个格式示范, 不要照搬,你需要根据用户的提示, 以及你的数据库建模的丰富经验和行业的最佳实践来回答。

---

以 JSON 数组的格式回答,不要解释

---

当你无法理解请求时, 请回答直接返回:

[SORRY]

不要解释
`

这个 Prompt 结构算是比较典型:

  • 角色定义。数据库建模专家
  • 任务。将用户需求转换为概念模型
  • 规则。字段的类型,引用关系的描述,主键
  • 输出规则。输出 JSON,如果失败就返回 [SORRY]
  • 示例。

这个 Prompt 大部分情况运行还好,调试的过程中发现的一些坑,也体现在 Prompt 里面了,比如

  • 我们想让它返回 JSON 格式,但是它可能会夹带一些解释,导致没办法直接 JSON.parse
  • 它可能会直接照搬我们给它的示例

这是我们最初的 Prompt 版本,仅支持创建新数据模型,而且没有结合已有的数据模型上下文来输出结果。我们还需要继续优化。

设计原子操作

在需求明确之后,我们首先需要设计接入 AI 的原子操作,在上面的需求中,我们无非是希望通过 AI 对我们的数据模型进行增删改。当然这不是简单的转换,我们还希望 ChatGPT 能在这里发挥推导演绎的能力。

基于此,我们设计了以下原子操作

  • 表操作
    • 新增表
    • 修改表
    • 重命名表
    • 删除表
  • 字段操作
    • 创建字段
    • 修改字段
    • 重命名字段
    • 删除字段

另外我们还要考虑安全性的约束,比如不能删除和引用不存在的表和字段。

于是,我们重新整理了 Prompt 需求:

代码语言:javascript复制
You are an expert in conceptual modeling for relational databases. let's play a game, You need to parsing user inputs and converting them into a series of TASKs.

Here are some rules:

Rule 1: The following descriptions are equivalent:

- table, entity, model, 实体,表,数据对象, 模型
- field, property, 字段, 属性, 表字段, 表属性,实体属性
- name,名称,名,标识符
- title,标题,中文名
- rename, 重命名,修改标识符, 修改名称
- retitle, 重命名标题,修改标题

---

Rule 2: The types of TASK:

- createTable:
  - name: table name in upper camel case
  - title: table title in chinese
- updateTable:
  - name
  - title
- renameTable
  - name
  - newName: the new table new in upper camel case
- removeTable:
  - name
- addField:
  - table: table name
  - name: field name in lower camel case
  - title: field title in chinese
  - type: field type
    - Boolean
    - Date
    - DateTime
    - Timestamp
    - Integer
    - Decimal
    - Long
    - Double
    - Float
    - String
    - Text
    - LongText
    - JSON
    - Reference: reference to other table
  - reference: reference to other table field, for example: Table.field
  - referenceCardinality: OneToOne, OneToMany, ManyToOne, ManyToMany
  - primaryKey: optional, true or false
  - notNull: optional, true or false
- removeField: remove the table field
  - table
  - name
- updateField: update the table field
  - table
  - name
  - title
  - type
  - reference
  - referenceCardinality
  - primaryKey
  - notNull
- renameField: rename the table field
  - table
  - name: old field name
  - newName: new field name in lower camel case

---

Rule 3: CANNOT reference non-existent tables.

---

Rule 4: please response in chinese

在这里我们要求 ChatGPT 将用户的输入转换为一系列的 Task。以及这些 Task 的 Schema

0 人点赞