简介
本设计文档聚焦于 DouPHP 内容管理模块的数据库表结构与业务实现,覆盖文章与案例两大内容类型及其分类。文档围绕以下目标展开:
- 明确 dou_article、dou_article_category、dou_cases、dou_case_category 等表的字段设计与用途
- 说明内容发布流程、分类层级关系、SEO 优化字段设计
- 记录内容状态管理、排序机制、点击统计的实现方式
- 提供内容模块的表关系设计与查询优化策略
- 面向内容管理系统开发者与运维人员提供完整表结构参考
更新 本次更新重点反映了内容管理系统的重大升级,包括增强的文章、产品和帮助系统,改进了SEO字段、基于slug的URL、内容版本控制和更好的分类管理。
项目结构
内容管理模块在项目中以"模块"形式组织,包含后台管理、前台展示、API 接口、模型与服务等层次。与本文相关的核心路径包括:
- 模块 SQL 备份:用于初始化或迁移表结构
- 后台控制器与服务:负责内容的增删改查、分类管理、排序与状态控制
- 前台模型与服务:负责内容列表、详情、点击统计、分类树构建等
- 系统表结构文档:作为历史/对照参考
graph TB
subgraph "后台管理"
A["后台控制器<br/>Article/Cases"] --> B["后台服务<br/>ArticleService/CasesService"]
B --> C["数据模型<br/>dou_article / dou_cases"]
end
subgraph "前台展示"
D["前台控制器<br/>Article/Cases"] --> E["前台模型<br/>Article/Cases"]
E --> F["分类模型<br/>ArticleCategory/CasesCategory"]
end
subgraph "数据库"
G["dou_article"]
H["dou_article_category"]
I["dou_cases"]
J["dou_cases_category"]
end
C --> G
B --> H
E --> I
F --> J
图表来源
- article.sql:7-27
- cases.sql:7-27
- Article.php(前台模型)
- Cases.php(前台模型)
章节来源
- article.sql:7-27
- cases.sql:7-27
核心组件
- 文章表(dou_article):存储文章内容、缩略图、附件、SEO 信息、点击数、排序与状态等
- 文章分类表(dou_article_category):支持父级分类、导航同步、SEO 信息与排序
- 案例表(dou_cases):结构与文章表高度一致,用于案例展示
- 案例分类表(dou_cases_category):结构与文章分类表一致,用于案例分类
关键要点
- 统一使用 slug 作为 URL 标识,便于 SEO 友好链接
- 使用 operator_type/operator_id 区分创建者类型与 ID,便于多角色内容管理
- 使用 sort/status 控制显示顺序与可见性
- 使用 click 字段进行点击计数,配合前台逻辑进行自增更新
更新 新增的operator_type和operator_id字段支持管理员和工作端两种类型的创建者,提升了内容管理的灵活性和安全性。
章节来源
- article.sql:7-27
- cases.sql:7-27
- 系统表结构.sql:256-287
架构总览
内容管理模块采用分层架构:
- 表现层:后台/前台控制器接收请求并返回视图或 JSON
- 服务层:封装业务逻辑(如内容发布、分类树构建、点击统计)
- 模型层:ORM 操作数据库表
- 数据层:MySQL 表结构定义索引与约束
sequenceDiagram
participant Admin as "后台管理员"
participant AC as "后台控制器"
participant ASvc as "后台服务"
participant Model as "数据模型"
participant DB as "数据库"
Admin->>AC : "提交新增/编辑表单"
AC->>ASvc : "调用保存方法"
ASvc->>Model : "写入/更新记录"
Model->>DB : "INSERT/UPDATE"
DB-->>Model : "返回结果"
Model-->>ASvc : "成功/失败"
ASvc-->>AC : "返回处理结果"
AC-->>Admin : "提示并跳转"
图表来源
- ArticleService.php(后台服务)
- CasesService.php(后台服务)
- Article.php(前台模型)
详细组件分析
文章表(dou_article)设计
- 主键与索引
- id:自增主键
- idx_slug:对 slug 建立索引,提升按 URL 标识查询效率
- idx_operator:复合索引(operator_type, operator_id),便于按创建者筛选
- 字段语义
- category_id:关联分类
- operator_type/operator_id:创建者类型与 ID,支持admin和work两种类型
- title/slug:标题与 URL 标识,slug用于生成友好的URL
- defined:自定义字段(序列化数组),扩展性强
- content/image/file:正文、缩略图、附件
- click:点击数,用于统计热度
- keywords/description:SEO 关键词与描述
- sort/status:排序与启用禁用状态
- created_at:创建时间
classDiagram
class Article {
+id
+category_id
+operator_type
+operator_id
+title
+slug
+defined
+content
+image
+file
+click
+keywords
+description
+sort
+status
+created_at
}
图表来源
- article.sql:7-27
章节来源
- article.sql:7-27
文章分类表(dou_article_category)设计
- 字段语义
- slug/name/icon:分类 URL 标识、名称、图标
- keywords/description:分类级 SEO 信息
- parent_id:父级分类 ID,支持多级分类
- sync_to_nav:是否同步到导航菜单
- sort:分类排序
flowchart TD
Start(["加载分类"]) --> LoadRoot["查询根分类(parent_id=0)"]
LoadRoot --> ForEach{"遍历每个分类"}
ForEach --> |是| LoadChildren["查询子分类(parent_id=当前ID)"]
LoadChildren --> BuildTree["构建树形结构"]
BuildTree --> Next{"还有分类?"}
Next --> |是| ForEach
Next --> |否| End(["完成"])
图表来源
- ArticleCategory.php(前台模型)
章节来源
- article.sql:31-42
案例表(dou_cases)设计
- 结构与文章表一致,适用于案例展示
- 同样具备 slug、SEO、点击数、排序与状态字段
- 通过 category_id 关联案例分类
classDiagram
class Cases {
+id
+category_id
+operator_type
+operator_id
+title
+slug
+defined
+content
+image
+file
+click
+keywords
+description
+sort
+status
+created_at
}
图表来源
- cases.sql:7-27
章节来源
- cases.sql:7-27
案例分类表(dou_cases_category)设计
- 与文章分类表结构一致,支持多级分类与导航同步
- 用于案例的分类组织与展示
classDiagram
class CasesCategory {
+id
+slug
+name
+icon
+keywords
+description
+parent_id
+sync_to_nav
+sort
}
图表来源
- cases.sql:31-42
章节来源
- cases.sql:31-42
内容发布流程(后台)
- 管理员在后台提交新增/编辑表单
- 控制器校验参数后调用服务层
- 服务层执行数据持久化,必要时生成 slug、设置默认值
- 返回处理结果并记录操作日志
sequenceDiagram
participant Admin as "后台管理员"
participant Ctrl as "后台控制器"
participant Svc as "后台服务"
participant Model as "数据模型"
participant DB as "数据库"
Admin->>Ctrl : "提交表单"
Ctrl->>Svc : "save(data)"
Svc->>Model : "create/update"
Model->>DB : "写入数据"
DB-->>Model : "返回影响行数"
Model-->>Svc : "成功/失败"
Svc-->>Ctrl : "返回结果"
Ctrl-->>Admin : "提示并跳转"
图表来源
- ArticleService.php(后台服务)
- CasesService.php(后台服务)
章节来源
- ArticleService.php(后台服务)
- CasesService.php(后台服务)
分类层级关系与导航同步
- 分类通过 parent_id 形成树形结构
- sync_to_nav 控制是否将分类同步至导航菜单
- 前台模型负责构建树形结构并渲染
flowchart TD
A["读取分类"] --> B{"是否有父级?"}
B --> |否| C["加入根节点"]
B --> |是| D["加入父节点子列表"]
C --> E["递归处理子分类"]
D --> E
E --> F["输出树形结构"]
图表来源
- ArticleCategory.php(前台模型)
- CasesCategory.php(前台模型)
章节来源
- ArticleCategory.php(前台模型)
- CasesCategory.php(前台模型)
SEO 优化字段设计
- 内容与分类均提供 keywords 与 description 字段,便于搜索引擎抓取
- slug 字段用于生成友好的 URL,提升 SEO 效果
- 建议在前台模板中正确输出 meta 标签与 canonical 链接
更新 新的SEO字段设计更加完善,支持更丰富的元数据配置,同时slug字段长度增加到191字符,支持更复杂的URL结构。
章节来源
- article.sql:7-27
- cases.sql:7-27
- article.sql:31-42
- cases.sql:31-42
内容状态管理与排序机制
- status:控制内容是否启用(1 启用,0 禁用)
- sort:控制内容或分类的显示顺序
- 建议在列表查询时按 sort 升序、status=1 过滤
更新 状态管理更加灵活,支持多种状态组合,排序机制也进行了优化,支持更精细的排序控制。
章节来源
- article.sql:7-27
- cases.sql:7-27
- article.sql:31-42
- cases.sql:31-42
点击统计实现
- 使用 click 字段记录点击次数
- 前台详情页在访问时进行自增更新
- 可结合缓存减少数据库压力
flowchart TD
Start(["访问详情"]) --> CheckCache["检查缓存"]
CheckCache --> CacheHit{"缓存命中?"}
CacheHit --> |是| Render["渲染页面"]
CacheHit --> |否| IncClick["click = click + 1"]
IncClick --> UpdateCache["更新缓存"]
UpdateCache --> Render
Render --> End(["结束"])
图表来源
- Article.php(前台模型)
- Cases.php(前台模型)
章节来源
- Article.php(前台模型)
- Cases.php(前台模型)
URL生成机制
- 基于slug的URL生成,支持友好的URL结构
- 支持短地址模式,可省略模块名段
- 自动处理分类层级和别名映射
更新 URL生成机制得到了显著增强,支持更灵活的URL结构和更好的SEO优化。
章节来源
- UrlBuilder.php:290-324
依赖关系分析
- 控制器依赖服务层,服务层依赖模型层,模型层直接操作数据库
- 分类模型与内容模型通过 category_id 建立关联
- 导航同步由分类模型的 sync_to_nav 控制
graph LR
ACtrl["后台控制器"] --> ASvc["后台服务"]
ASvc --> AMdl["文章/案例模型"]
FCtrl["前台控制器"] --> FMdl["前台模型"]
FMdl --> CatMdl["分类模型"]
AMdl --> DB1["dou_article / dou_cases"]
CatMdl --> DB2["dou_article_category / dou_cases_category"]
图表来源
- ArticleService.php(后台服务)
- CasesService.php(后台服务)
- Article.php(前台模型)
- ArticleCategory.php(前台模型)
章节来源
- ArticleService.php(后台服务)
- CasesService.php(后台服务)
- Article.php(前台模型)
- ArticleCategory.php(前台模型)
性能考虑
- 索引优化
- 对 slug 建立唯一或普通索引,提升按 URL 查询效率
- 对 operator_type/operator_id 建立复合索引,便于按创建者筛选
- 查询优化
- 列表查询时仅选择必要字段,避免 SELECT *
- 使用分页与条件过滤(status、category_id)减少数据量
- 缓存策略
- 对分类树、热门内容列表进行缓存,降低数据库压力
- 点击统计可采用异步队列或批量更新,避免每次访问都写库
- 存储优化
- 大文本字段(content、description)建议使用合适的字符集与压缩策略
- 图片与附件走独立存储(对象存储),数据库仅保留路径
更新 性能优化方面,新增了针对operator_type和operator_id的复合索引,以及优化的slug查询索引,提升了整体查询性能。
故障排查指南
- 常见问题
- slug 重复导致唯一约束冲突:确保生成规则唯一或去重
- 分类树未正确显示:检查 parent_id 是否正确设置
- 点击数未增加:确认前台逻辑是否执行自增,是否存在缓存拦截
- 内容不显示:检查 status 是否为启用,sort 是否合理
- operator_type/operator_id 问题:确认创建者类型和ID是否正确设置
- 排查步骤
- 查看后台日志与数据库错误日志
- 验证索引是否存在且有效
- 使用慢查询日志定位性能瓶颈
- 核对模型与服务中的业务逻辑是否与需求一致
更新 新增了针对operator_type和operator_id字段的故障排查指导,帮助用户解决多角色内容管理相关的问题。
章节来源
- ArticleService.php(后台服务)
- CasesService.php(后台服务)
- Article.php(前台模型)
结论
DouPHP 内容管理模块通过统一的表结构设计,实现了文章与案例的高效管理与展示。其特点包括:
- 清晰的分类层级与导航同步机制
- 完善的 SEO 字段支持与 URL 标识
- 灵活的状态与排序控制
- 可扩展的自定义字段设计
- 合理的索引与查询优化策略
- 支持多角色内容管理(管理员和工作端)
更新 本次升级显著增强了内容管理系统的功能,特别是在SEO优化、URL生成、多角色支持和分类管理方面都有重要改进。
建议在实际使用中结合缓存与异步任务进一步提升性能,并严格遵循命名与索引规范以保证系统的可维护性与扩展性。
附录
- 表关系概览
- 文章/案例与分类通过 category_id 关联
- 分类通过 parent_id 形成树形结构
- 导航同步由 sync_to_nav 控制
- 内容创建者通过 operator_type/operator_id 标识
erDiagram
DOU_ARTICLE_CATEGORY {
int id PK
varchar slug
varchar name
varchar icon
varchar keywords
text description
int parent_id FK
tinyint sync_to_nav
tinyint sort
}
DOU_CASES_CATEGORY {
int id PK
varchar slug
varchar name
varchar icon
varchar keywords
text description
int parent_id FK
tinyint sync_to_nav
tinyint sort
}
DOU_ARTICLE {
int id PK
int category_id FK
enum operator_type
int operator_id
varchar title
varchar slug
text defined
longtext content
varchar image
varchar file
smallint click
varchar keywords
text description
smallint sort
tinyint status
datetime created_at
}
DOU_CASES {
int id PK
int category_id FK
enum operator_type
int operator_id
varchar title
varchar slug
text defined
longtext content
varchar image
varchar file
smallint click
varchar keywords
text description
smallint sort
tinyint status
datetime created_at
}
DOU_ARTICLE_CATEGORY ||--o{ DOU_ARTICLE : "包含"
DOU_CASES_CATEGORY ||--o{ DOU_CASES : "包含"
图表来源
- article.sql:7-27
- article.sql:31-42
- cases.sql:7-27
- cases.sql:31-42