# 数据库设计规范

<cite>
**本文引用的文件**
- [README.md](file://README.md)
- [thinkcmf.sql](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本规范面向 ThinkCMF 的数据库设计与使用，结合安装脚本中的真实表结构，总结出一套适用于 ThinkCMF 的数据库设计原则、字段命名约定、数据类型选择、索引策略、迁移与版本管理建议，并给出基于 ThinkORM 的模型设计方法与常见关联关系实现思路。目标是帮助开发者在 ThinkCMF 生态中构建清晰、可维护、高性能的数据库方案。

## 项目结构
- ThinkCMF 通过安装脚本提供初始数据库结构，涵盖后台菜单、权限、钩子、导航、幻灯片、评论、插件、角色与用户等核心业务表。
- README 提及 ThinkPHP 版本、数据库迁移能力与 Swagger 支持，表明系统具备命令行迁移与 API 文档能力，便于后续版本演进与团队协作。

```mermaid
graph TB
A["安装脚本<br/>thinkcmf.sql"] --> B["后台菜单表<br/>cmf_admin_menu"]
A --> C["权限规则表<br/>cmf_auth_rule"]
A --> D["权限授权表<br/>cmf_auth_access"]
A --> E["钩子表<br/>cmf_hook"]
A --> F["钩子插件表<br/>cmf_hook_plugin"]
A --> G["导航位置表<br/>cmf_nav"]
A --> H["导航菜单表<br/>cmf_nav_menu"]
A --> I["幻灯片表<br/>cmf_slide"]
A --> J["幻灯片子项表<br/>cmf_slide_item"]
A --> K["评论表<br/>cmf_comment"]
A --> L["插件表<br/>cmf_plugin"]
A --> M["角色表<br/>cmf_role"]
A --> N["角色-用户关联表<br/>cmf_role_user"]
A --> O["第三方用户表<br/>cmf_third_party_user"]
A --> P["资源表<br/>cmf_asset"]
A --> Q["全站配置表<br/>cmf_option"]
A --> R["URL 路由表<br/>cmf_route"]
A --> S["回收站表<br/>cmf_recycle_bin"]
```

图表来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

章节来源
- [README.md:1-362](file://README.md#L1-L362)
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

## 核心组件
- 后台菜单与权限：通过菜单表与权限规则/授权表配合，实现后台菜单树与细粒度权限控制。
- 钩子与插件：钩子表定义系统/应用/模板钩子，钩子插件表将插件挂接到具体钩子，形成可扩展的插件生态。
- 导航与展示：导航位置与菜单表支撑前台导航树，配合幻灯片与页面内容实现站点展示。
- 用户与第三方登录：用户表与第三方用户表分离管理，角色与授权表支撑 RBAC 权限体系。
- 内容与评论：评论表支持多内容类型的通用评论，配合层级关系字段实现回复树。
- 配置与路由：全站配置表与 URL 路由表分别负责全局配置与 URL 美化。

章节来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

## 架构总览
以下图展示 ThinkCMF 数据层关键实体及其关系，体现典型的后台权限、钩子扩展、导航与内容评论等模块间的耦合与职责边界。

```mermaid
erDiagram
CMF_ADMIN_MENU {
int id PK
int parent_id
tinyint type
tinyint status
float list_order
varchar app
varchar controller
varchar action
varchar param
varchar name
varchar icon
varchar remark
}
CMF_AUTH_RULE {
int id PK
tinyint status
varchar app
varchar type
varchar name UK
varchar param
varchar title
varchar condition
}
CMF_AUTH_ACCESS {
bigint id PK
int role_id
varchar rule_name
varchar type
}
CMF_HOOK {
int id PK
tinyint type
tinyint once
varchar name
varchar hook
varchar app
varchar description
}
CMF_HOOK_PLUGIN {
int id PK
float list_order
tinyint status
varchar hook
varchar plugin
}
CMF_NAV {
int id PK
tinyint is_main
varchar name
varchar remark
}
CMF_NAV_MENU {
int id PK
int nav_id
int parent_id
tinyint status
float list_order
varchar name
varchar target
varchar href
varchar icon
varchar path
}
CMF_SLIDE {
int id PK
tinyint status
int delete_time
varchar name
varchar remark
}
CMF_SLIDE_ITEM {
int id PK
int slide_id
tinyint status
float list_order
varchar title
varchar image
varchar url
varchar target
varchar description
text content
text more
}
CMF_COMMENT {
bigint id PK
bigint parent_id
int user_id
int to_user_id
int object_id
int like_count
int dislike_count
int floor
int create_time
int delete_time
tinyint status
tinyint type
varchar table_name
varchar full_name
varchar email
varchar path
text url
text content
text more
}
CMF_PLUGIN {
int id PK
tinyint type
tinyint has_admin
tinyint status
int create_time
varchar name
varchar title
varchar demo_url
varchar hooks
varchar author
varchar author_url
varchar version
varchar description
text config
}
CMF_ROLE {
int id PK
int parent_id
tinyint status
int create_time
int update_time
float list_order
varchar name
varchar remark
}
CMF_ROLE_USER {
bigint id PK
int role_id
bigint user_id
}
CMF_THIRD_PARTY_USER {
bigint id PK
bigint user_id
int last_login_time
int expire_time
int create_time
int login_times
tinyint status
varchar nickname
varchar third_party
varchar app_id
varchar last_login_ip
varchar access_token
varchar openid
varchar union_id
text more
}
CMF_ASSET {
bigint id PK
bigint user_id
bigint file_size
int create_time
tinyint status
int download_times
varchar file_key
varchar filename
varchar file_path
varchar file_md5
varchar file_sha1
varchar suffix
text more
}
CMF_OPTION {
bigint id PK
tinyint autoload
varchar option_name UK
longtext option_value
}
CMF_ROUTE {
int id PK
float list_order
tinyint status
tinyint type
varchar full_url
varchar url
}
CMF_RECYCLE_BIN {
bigint id PK
int object_id
int create_time
varchar table_name
varchar name
bigint user_id
}
CMF_ADMIN_MENU ||--o{ CMF_ADMIN_MENU : "父子菜单"
CMF_NAV ||--o{ CMF_NAV_MENU : "包含"
CMF_SLIDE ||--o{ CMF_SLIDE_ITEM : "包含"
CMF_ROLE ||--o{ CMF_ROLE_USER : "拥有"
CMF_HOOK ||--o{ CMF_HOOK_PLUGIN : "触发"
CMF_AUTH_RULE ||--o{ CMF_AUTH_ACCESS : "授权"
```

图表来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

## 详细组件分析

### 表结构设计规范
- 字段命名
  - 使用全小写下划线命名法，如 user_id、create_time、list_order。
  - 保持语义明确，避免缩写，必要时使用常见缩写（如 id、ip、url）。
- 数据类型选择
  - 主键优先使用自增整型，确保高并发下的插入性能与索引效率。
  - 时间戳统一使用无符号整型，便于范围查询与排序。
  - 状态字段使用 tinyint 或 smallint，枚举值集中定义，便于前端与接口统一处理。
  - 文本字段根据长度选择 varchar 或 text，长文本优先 text，避免占用过多行存储。
  - JSON 扩展字段使用 text 存储，配合 JSON 函数进行查询（需数据库版本支持）。
- 字符集与排序规则
  - 中文场景优先 utf8mb4，保证 emoji 与四字节字符兼容。
  - 排序规则采用不区分大小写的统一规则，减少排序差异带来的问题。
- 约束与默认值
  - 明确主键、唯一键与外键约束，确保数据一致性。
  - 为常用筛选字段设置默认值，避免 NULL 值参与比较导致的索引失效。
- 可扩展性
  - 为未来字段扩展预留 more/text 字段，或采用 JSON 结构存储动态配置。

章节来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

### 字段命名约定与数据类型示例
- 用户相关：user_id（bigint）、user_type（tinyint）、last_login_time（int）、balance（decimal）。
- 时间相关：create_time、update_time、expire_time（int）。
- 状态相关：status（tinyint）、type（tinyint）、is_main（tinyint）。
- 文本相关：name、title、description、content（varchar/text），url（varchar），more（text）。
- 资源相关：file_size（bigint）、file_key、filename、file_path、file_md5、file_sha1、suffix（varchar）。

章节来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

### 索引策略
- 主键索引
  - 所有表均设置自增主键，确保唯一性与高效定位。
- 唯一索引
  - 全站配置表的 option_name 设置唯一索引，保证配置键唯一。
  - 权限规则表的 name 设置唯一索引，保证规则标识唯一。
- 普通索引
  - 后台菜单表对 parent_id、status、controller 建立索引，支撑菜单树与状态筛选。
  - 评论表对 table_name、object_id、status 建立联合索引，加速按内容类型与状态查询。
  - 幻灯片子项表对 slide_id 建立索引，支撑按分类检索。
  - 权限授权表对 role_id、rule_name 建立索引，支撑授权查询。
  - 角色表对 parent_id、status 建立索引，支撑角色树与状态筛选。
- 复合索引
  - 评论表对 table_name、object_id、status 建立联合索引，覆盖典型查询模式。
  - 导航菜单表对 nav_id、status 建立联合索引，支撑按导航位与状态查询。
- 索引维护
  - 定期评估热点查询与慢查询，调整索引组合，避免冗余索引造成写入成本上升。

章节来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

### ThinkORM 模型设计方法
- 模型定义
  - 基于 ThinkORM 的模型类映射到具体表，遵循 ThinkCMF 的命名规范与字段类型。
  - 在模型中声明主键、表名、字段映射与类型转换，确保 ORM 查询与原生 SQL 的一致性。
- 字段映射
  - 将数据库字段映射为模型属性，必要时使用访问器/修改器处理复杂字段（如 JSON、时间戳）。
- 数据验证规则
  - 在模型中定义验证规则，结合字段类型与业务约束，确保入库数据的合法性。
  - 对状态、类型等枚举字段，使用白名单校验，避免非法值进入数据库。
- 关联关系
  - 使用 ThinkORM 的关联方法定义一对一、一对多、多对多关系，提升查询可读性与性能。
  - 对于评论树、导航菜单树等层次结构，使用父子关联与递归查询，避免 N+1 查询问题。

章节来源
- [README.md:1-362](file://README.md#L1-L362)

### 数据库表之间的关联关系设计
- 一对一
  - 第三方用户与本地用户：第三方用户表通过 user_id 关联用户表，实现第三方账号与本地账号的绑定。
- 一对多
  - 幻灯片与幻灯片子项：幻灯片表与子项表通过 slide_id 建立一对多关系，支撑多页面轮播。
  - 角色与角色-用户：角色表与角色-用户表通过 role_id 建立一对多关系，支撑多用户多角色。
  - 导航位置与导航菜单：导航位置表与导航菜单表通过 nav_id 建立一对多关系，支撑多级菜单。
- 多对多
  - 权限规则与角色：权限规则表与角色-用户表共同构成多对多关系，支撑细粒度授权。
- 层次结构
  - 后台菜单与导航菜单：均通过 parent_id 实现父子关系，形成树形结构，便于权限与导航的层级管理。

```mermaid
classDiagram
class CmfAdminMenu {
+int id
+int parent_id
+tinyint type
+tinyint status
+float list_order
+string app
+string controller
+string action
+string param
+string name
+string icon
+string remark
}
class CmfNavMenu {
+int id
+int nav_id
+int parent_id
+tinyint status
+float list_order
+string name
+string target
+string href
+string icon
+string path
}
class CmfSlideItem {
+int id
+int slide_id
+tinyint status
+float list_order
+string title
+string image
+string url
+string target
+string description
+text content
+text more
}
class CmfRoleUser {
+bigint id
+int role_id
+bigint user_id
}
class CmfAuthAccess {
+bigint id
+int role_id
+string rule_name
+string type
}
CmfAdminMenu <|-- CmfAdminMenu : "父子菜单"
CmfNavMenu <|-- CmfNavMenu : "父子菜单"
CmfSlideItem ..> CmfSlide : "一对多"
CmfRoleUser ..> CmfRole : "多对多"
CmfAuthAccess ..> CmfAuthRule : "多对多"
```

图表来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

章节来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

### 数据库版本管理规范
- 迁移文件命名
  - 建议采用“YYYYMMDD_HHMMSS_动作_描述”的命名方式，例如 20250401_100000_create_user_table.php。
- 迁移策略
  - 新增表：使用 create_table 迁移，包含主键、索引与注释。
  - 修改表：使用 update_table 迁移，仅变更必要字段，保留历史索引。
  - 删除表：使用 drop_table 迁移，注意备份与回滚策略。
  - 数据迁移：拆分为结构迁移与数据迁移两个阶段，确保幂等性。
- 版本控制
  - 迁移文件纳入版本控制，记录每次变更的意图与影响范围。
  - 在生产环境执行迁移前，先在测试环境验证，再灰度发布。
- 与 ThinkCMF 的契合
  - ThinkCMF 已具备数据库迁移能力，建议在应用/插件层面遵循统一的迁移规范，确保升级与回滚可控。

章节来源
- [README.md:1-362](file://README.md#L1-L362)

### 实际设计示例与常见模式
- 通用评论模型
  - 通过 table_name + object_id + status 的组合，实现对任意内容类型的评论聚合查询。
  - 使用 parent_id 与 path 字段支持评论树与楼层统计。
- 导航树模型
  - 通过 parent_id 与 path 字段维护导航层级，配合 nav_id 限定导航位。
- 权限授权模型
  - 通过权限规则表与授权表建立多对多关系，结合角色表实现 RBAC。
- 资源管理模型
  - 通过 file_key、file_md5、file_sha1 等字段实现资源去重与唯一性校验。

章节来源
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

## 依赖分析
- ThinkCMF 依赖 ThinkPHP 的 ORM 能力与迁移机制，README 明确支持数据库迁移。
- 安装脚本提供初始表结构，涵盖权限、钩子、导航、评论、插件、角色与用户等模块，形成完整的后台与前台基础数据层。

```mermaid
graph TB
TP["ThinkPHP ORM"] --> CMF["ThinkCMF 应用"]
CMF --> MIG["数据库迁移"]
CMF --> DB["MySQL 数据库"]
CMF --> INSTALL["安装脚本<br/>thinkcmf.sql"]
```

图表来源
- [README.md:1-362](file://README.md#L1-L362)
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

章节来源
- [README.md:1-362](file://README.md#L1-L362)
- [thinkcmf.sql:1-989](file://vendor/thinkcmf/cmf-install/src/install/data/thinkcmf.sql#L1-L989)

## 性能考虑
- 索引优化
  - 为高频查询字段建立合适索引，避免全表扫描；定期分析慢查询日志，调整索引组合。
- 分页与排序
  - 对大表分页时，尽量使用覆盖索引与延迟关联，减少回表与排序成本。
- 写入优化
  - 批量写入时使用事务，减少锁竞争；避免在热键上进行频繁更新。
- 缓存策略
  - 对热点配置与菜单数据使用缓存，降低数据库压力；注意缓存与数据库的一致性。
- 查询设计
  - 避免 SELECT *，仅取必要字段；对复杂查询使用 EXPLAIN 分析执行计划。

## 故障排查指南
- 常见问题
  - 索引失效：检查 WHERE 条件是否与索引列匹配，避免在索引列上使用函数或隐式转换。
  - 死锁与锁等待：减少长事务，避免在事务中进行复杂计算；合理安排更新顺序。
  - 编码问题：确认表与连接字符集一致，避免中文乱码或排序异常。
  - 权限不足：核对迁移与建表权限，确保具备 CREATE/ALTER/INDEX 权限。
- 诊断步骤
  - 使用 EXPLAIN 分析慢查询；检查是否存在全表扫描或回表。
  - 查看慢查询日志与错误日志，定位热点表与热点 SQL。
  - 对热点表进行分区或读写分离，缓解单机压力。

## 结论
本规范基于 ThinkCMF 安装脚本的真实表结构，总结了 ThinkCMF 场景下的数据库设计原则、索引策略与模型设计方法，并给出了迁移与版本管理建议。遵循这些规范有助于在 ThinkCMF 生态中构建稳定、可扩展且高性能的数据层。

## 附录
- 快速参考
  - 字段命名：全小写下划线，语义明确。
  - 数据类型：主键自增整型；时间戳无符号整型；状态 tinyint；文本 varchar/text；JSON text。
  - 索引：主键唯一；常用筛选字段建立普通索引；热点组合建立复合索引。
  - 迁移：按日期时间命名，结构与数据分离，版本可控。