# 第 2 章：数据建模 — 两张表搞定工单系统

上一章我们装好了 NocoBase 并认识了界面。现在，我们要给工单系统搭骨架——定义**数据模型**。

本章将创建工单和分类两张[数据表](/data-sources/data-modeling/collection)，配置[字段类型](/data-sources/data-modeling/collection-fields)（单行文本、下拉选择、[多对一](/data-sources/data-modeling/collection-fields/associations/m2o)关联等），并建立表间关联关系。数据模型是系统的地基：先想清楚要存哪些数据、数据之间有什么关系，后面搭界面、配权限才能水到渠成。


## 2.1 什么是数据表和字段

如果你用过 Excel，理解数据表就很容易：

| Excel 概念 | NocoBase 概念 | 说明 |
|------------|--------------|------|
| 工作表 | 数据表（Collection） | 一类数据的容器 |
| 列标题 | 字段（Field） | 描述数据的属性 |
| 每一行 | 记录（Record） | 一条具体的数据 |

![02-data-modeling-2026-03-11-08-32-41](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-32-41.png)

比如我们要做的"工单表"，就像一张 Excel 表格——每一列是一个字段（标题、状态、优先级……），每一行是一条工单记录。

不过，NocoBase 比 Excel 强大得多。它支持多种**数据表类型**，不同类型自带不同的能力：

| 表类型 | 适合场景 | 举例 |
|--------|---------|------|
| **普通表** | 大多数业务数据 | 工单、订单、客户 |
| **树表** | 有层级关系的数据 | 分类目录、部门组织架构 |
| 日历表 | 日期事件 | 会议、排班 |
| 文件表 | 附件管理 | 文档、图片 |

今天我们会用到**普通表**和**树表**，其他类型以后用到再学。

**进入数据源管理**：点击左下角 **「数据源管理」** 图标（齿轮旁边的数据库图标），你会看到「[主数据源](/data-sources)」——我们所有的表都建在这里。

![02-data-modeling-2026-03-11-08-35-08](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-35-08.png)


## 2.2 创建核心表：工单

我们直奔主题，先创建系统的核心——工单表。

### 创建表

1. 在数据源管理页面，点击 **主数据源** 进入

![02-data-modeling-2026-03-11-08-36-06](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-36-06.png)

2. 点击 **「创建数据表」**，选择 **「普通表」**

![02-data-modeling-2026-03-11-08-38-52](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-38-52.png)

3. 数据表名称：`tickets`，数据表标题：`工单`

![02-data-modeling-2026-03-11-08-40-34](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-40-34.png)

创建表时，系统会默认勾选一组**系统字段**，它们会自动记录每条数据的元信息：

| 字段 | 说明 |
|------|------|
| ID | 主键，分布式唯一标识 |
| 创建日期 | 记录的创建时间 |
| 创建人 | 谁创建了这条记录 |
| 最后修改日期 | 最后一次更新时间 |
| 最后修改人 | 最后一次更新的用户 |

这些系统字段保持默认即可，不需要手动管理。如果某些场景不需要，也可以取消勾选。

### 添加基础字段

表创建好了，接下来添加字段。点击工单表的 **「配置字段（Configure fields）」**，你会看到刚才默认的系统字段已经在列表中了。

![02-data-modeling-2026-03-11-08-58-48](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-58-48.png)

![02-data-modeling-2026-03-11-08-59-47](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-08-59-47.png)

点击右上角的 **「添加字段（Add field）」** 按钮，会展开一个下拉字段类型列表——从中选择你要添加的字段类型。

![02-data-modeling-2026-03-11-09-00-22](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-00-22.png)

我们先添加工单自身的字段，关联字段稍后再加。

**1. 标题（单行文本）**

每条工单都需要一个简短的标题来概括问题。点击 **「添加字段」** → 选择 **[「单行文本」](/data-sources/data-modeling/collection-fields/basic/input)**：

![02-data-modeling-2026-03-11-09-01-00](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-01-00.png)

- 字段名称：`title`，字段标题：`标题`
- 点击 **「设置验证规则」**，添加一条 **「必填」** 规则

![02-data-modeling-2026-03-11-09-02-40](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-02-40.png)

**2. 描述（Markdown(Vditor)）**

用来详细描述问题，支持格式排版，方便贴图、贴代码。在「添加字段」→「Media」分类下有三种可选：

| 字段类型 | 特点 |
|---------|------|
| Markdown | 基本 Markdown，简单样式 |
| Rich Text | 富文本，简单样式 + 附件上传 |
| **Markdown(Vditor)** | 功能最丰富，支持所见即所得、即时渲染、源码编辑三种模式 |

我们选 **Markdown(Vditor)**。

![02-data-modeling-2026-03-11-09-09-58](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-09-58.png)

- 字段名称：`description`，字段标题：`描述`

![02-data-modeling-2026-03-11-09-10-50](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-10-50.png)

**3. 状态（下拉菜单 - 单选）**

![02-data-modeling-2026-03-11-09-12-00](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-12-00.png)
工单从提交到完成，需要一个状态来跟踪进度。

- 字段名称：`status`，字段标题：`状态`
- 添加选项值（每个选项需要填写「选项值」和「选项标签」，颜色可选）：

| 选项值 | 选项标签 | 颜色 |
|--------|---------|------|
| pending | 待处理 | Orange（日暮） |
| in_progress | 处理中 | Blue（拂晓蓝） |
| completed | 已完成 | Green（极光绿） |

![02-data-modeling-2026-03-11-09-17-44](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-17-44.png)

先填好选项并保存。然后再次点击该字段的 **「编辑（Edit）」**，这时就能在「默认值」里选择 **「待处理」** 了。

![02-data-modeling-2026-03-11-09-20-28](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-20-28.png)

![02-data-modeling-2026-03-11-09-22-34](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-22-34.png)

> 首次创建时还没有选项数据，所以默认值选不了——需要保存后再回来设置。

> 为什么用下拉单选？因为状态是固定的几个值，[下拉菜单](/data-sources/data-modeling/collection-fields/choices/select)可以防止用户随意填写，保证数据规范。

**4. 优先级（下拉菜单 - 单选）**

区分工单的紧急程度，方便处理人员按优先级排序。

- 字段名称：`priority`，字段标题：`优先级`
- 添加选项值：

| 选项值 | 选项标签 | 颜色 |
|--------|---------|------|
| low | 低 | |
| medium | 中 | |
| high | 高 | Orange（日暮） |
| urgent | 紧急 | Red（薄暮） |

到这里，工单表有了 4 个基础字段。但是——工单应该有个"分类"吧？比如"网络问题""软件故障"？

如果把分类做成下拉菜单，当然也行。但你很快会发现：分类可能有子分类（"硬件问题"下面还有"显示器""键盘""打印机"），下拉菜单就不够用了。

我们需要**另一张表**来专门管理分类。而且这张表，用 NocoBase 的**树表**来建最合适。


## 2.3 创建分类树表：让分类有层级

### 什么是树表

树表是一种特殊的数据表，它自带**父子关系**——每条记录可以有一个"父节点"。这天然适合有层级结构的数据：

```
硬件问题          ← 一级分类
├── 显示器        ← 二级分类
├── 键盘鼠标
└── 打印机
软件故障
├── 办公软件
└── 系统问题
网络问题
账号权限
```

如果用普通表，你需要自己手动建一个"父分类"字段来实现这种关系。而**树表会自动帮你处理好**，还支持树形展示、添加子记录等操作，省心很多。

### 创建表

1. 回到数据源管理，点击 **「创建数据表」**
2. 这次选择 **「树表」**（不是普通表！）
![02-data-modeling-2026-03-11-09-26-07](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-26-07.png)

3. 数据表名称：`categories`，数据表标题：`工单分类`

![02-data-modeling-2026-03-11-09-26-55](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-26-55.png)

> 注意创建后，表里除了系统字段外，还会自动出现 **「Parent」** 和 **「Children」** 两个关系字段——这就是树表的特殊能力。通过 Parent 可以访问父节点，通过 Children 可以访问所有子节点，不需要你手动添加。

![02-data-modeling-2026-03-11-09-27-40](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-27-40.png)

### 添加字段

点击 **「配置字段」** 进入字段列表，可以看到系统字段和自动生成的 Parent、Children 字段。
点击右上角 **「添加字段」**：

**字段一：分类名称**

1. 选择 **「单行文本」**
2. 字段名称：`name`，字段标题：`分类名称`
3. 点击 **「设置验证规则」**，添加 **「必填」** 规则

**字段二：颜色**

1. 选择 **「颜色」**
2. 字段名称：`color`，字段标题：`颜色`

![02-data-modeling-2026-03-11-09-28-59](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-28-59.png)

颜色字段可以让每个分类有自己的标识色，后面在界面上展示时会更直观。

![02-data-modeling-2026-03-11-09-29-23](https://static-docs.nocobase.com/02-data-modeling-2026-03-11-09-29-23.png)

到这里，两张数据表的基础字段就配好了。接下来我们把它们关联起来。


## 2.4 回到工单表：添加关联字段

> **关系字段初次接触可能有点抽象。** 如果你觉得不太好理解，可以先跳到 [第 3 章：搭建页面](./03-building-pages)，在实际的页面操作中感受一下数据是怎么展示的，再回来补上关联字段。

工单需要关联到分类、提交人和处理人。这类字段叫做**关系字段**——它不像"标题"那样直接存一段文字，而是存了另一张表里某条记录的 ID，通过这个 ID 找到对应的记录。

用一条具体的工单来看——左边是工单的各个属性，其中"分类"和"提交人"存的不是文字，而是一个 ID。系统通过这个 ID，从右边的表里精准找到对应的记录：


![02-data-modeling-2026-03-12-00-50-10](https://static-docs.nocobase.com/02-data-modeling-2026-03-12-00-50-10.png)

你在界面上看到的是名称（"网络问题""张三"），背后就是通过 ID 关联的。**多条工单可以指向同一个分类或同一个用户**——这种关系叫做[**多对一**](/data-sources/data-modeling/collection-fields/associations/m2o)。

### 添加关系字段

回到工单表的「配置字段」→「添加字段」，选择 **「多对一」**。
![02-data-modeling-2026-03-12-00-52-39](https://static-docs.nocobase.com/02-data-modeling-2026-03-12-00-52-39.png)

创建时你会看到这些配置项：

| 配置项 | 说明 | 怎么填 |
|--------|------|--------|
| 源数据表 | 当前表（自动填好） | 不用改 |
| **目标数据表** | 要关联到哪张表 | 选择对应的表 |
| **外键** | 存在当前表里的关联列名 | 填一个有意义的名字 |
| 目标数据表标识字段 | 默认 `id` | 保持默认即可 |
| ON DELETE | 目标记录被删除时的处理方式 | 保持默认即可 |

![02-data-modeling-2026-03-12-00-58-38](https://static-docs.nocobase.com/02-data-modeling-2026-03-12-00-58-38.png)

> 外键默认会自动生成一个随机名（如 `f_xxxxx`），建议改成有意义的名字，方便日后维护。命名用小写字母加下划线（如 `category_id`），不用大小写混合。

按这个方式依次添加三个字段：

**5. 分类 → 工单分类表**

- 字段标题：`分类`
- 目标数据表：选择 **「工单分类」**（如果列表中没有，直接输入表名会自动创建）
- 外键：`category_id`

**6. 提交人 → 用户表**

记录是谁提交了这条工单。NocoBase 内置了用户表，直接关联即可。

- 字段标题：`提交人`
- 目标数据表：选择 **「用户」**
- 外键：`submitter_id`
![02-data-modeling-2026-03-12-01-00-09](https://static-docs.nocobase.com/02-data-modeling-2026-03-12-01-00-09.png)

**7. 处理人 → 用户表**

记录谁在负责处理这条工单。

- 字段标题：`处理人`
- 目标数据表：选择 **「用户」**
- 外键：`assignee_id`

![02-data-modeling-2026-03-12-01-00-22](https://static-docs.nocobase.com/02-data-modeling-2026-03-12-01-00-22.png)


## 2.5 数据模型全貌

回顾一下我们搭建的完整数据模型：

![02-data-modeling-2026-03-16-00-30-35](https://static-docs.nocobase.com/02-data-modeling-2026-03-16-00-30-35.png)

`}o--||` 表示多对一关系：左边"多"，右边"一"。


## 小结

这一章我们完成了数据建模——整个工单系统的骨架：

1. **工单表**（tickets）：4 个基础字段 + 3 个关联字段，用**普通表**创建
2. **工单分类表**（categories）：2 个自定义字段 + 自动的 Parent/Children 字段，用**树表**创建，天然支持层级分类

我们学到了几个重要概念：

- **数据表（Collection）** = 一类数据的容器
- **数据表类型** = 不同场景选不同类型（普通表、树表……）
- **字段（Field）** = 数据的属性，通过「配置字段」→「添加字段」来创建
- **系统字段** = ID、创建日期、创建人等，建表时自动勾选
- **关系字段（多对一）** = 指向另一张表的记录，建立表与表之间的关联

> 你可能注意到，后续的截图中已经有数据了——这些测试数据是我们为了演示效果提前录入的，别着急。在 NocoBase 中，数据的增删改查都是通过前端页面完成的。第 3 章我们会搭建表格来展示数据，第 4 章会搭建表单来录入数据，一步步揭晓。


## 下一章预告

骨架搭好了，但现在只有空表。下一章，我们要搭建页面，让数据真正能展示出来。

我们下章见！

## 相关资源

- [数据源概述](/data-sources) — NocoBase 数据建模核心概念
- [数据表字段](/data-sources/data-modeling/collection-fields) — 所有字段类型详解
- [多对一关联](/data-sources/data-modeling/collection-fields/associations/m2o) — 关联关系配置说明
