文档目录
数据库架构设计

简介

本文件面向数据库管理员与后端开发者,系统化梳理 DouPHP 的数据库架构设计与实践。内容覆盖数据库选型、字符集与存储引擎策略、连接与事务管理、安全策略、性能优化、监控与备份恢复等关键主题。文档基于仓库中的实际代码实现进行归纳与说明,确保可落地、可操作。

重要更新:本项目已完成从 dou_ 前缀到 dk_ 前缀的全面数据库迁移,所有表结构已统一采用新的命名规范,提升了系统的品牌一致性和部署灵活性。

项目结构

DouPHP 将数据库访问抽象为"基础设施层"和"ORM 层",并通过配置集中管理数据库连接参数:

  • 配置层:应用级数据库连接信息(主机、库名、用户名、密码、表前缀、字符集)集中在配置文件。
  • 基础设施层:提供底层连接、SQL 构建、事务控制、导入导出等能力。
  • ORM 层:提供轻量 ActiveRecord 模型、查询构造器、预加载与数据水合等高级能力。
  • 业务层:通过 ORM/DB 门面或 Service 完成具体业务的数据读写。
graph TB
A["应用配置<br/>config/config.php"] --> B["数据库连接<br/>core/infra/database/Connection.php"]
B --> C["ORM 基础模型<br/>core/orm/Model.php"]
C --> D["ORM 查询构造器<br/>core/orm/Builder.php"]
D --> E["业务服务/控制器<br/>如 order/aftersale 等"]
E --> F["数据库表<br/>dk_* 表结构"]

图表来源

  • config.php:15-31
  • Connection.php:102-200
  • Model.php:35-51
  • Builder.php:25-31

章节来源

  • config.php:15-31
  • Connection.php:102-200
  • Model.php:35-51
  • Builder.php:25-31

核心组件

  • 数据库连接与初始化
    • 使用 MySQLi 扩展建立连接,支持 IPv6 与端口解析;自动设置字符集并兼容降级;设置严格 SQL 模式;选择目标数据库。
    • 提供表名前缀注入、字段存在性检查、自增值读取、版本获取、结果集处理等基础能力。
  • ORM 模型与查询构造器
    • Model 提供属性映射、类型转换、时间戳、全局作用域、事件、关系预加载等能力。
    • Builder 在 Connection 之上封装链式查询,支持 with 预加载、聚合方法白名单、分页、水合后回调等。
  • 事务管理
    • 支持嵌套事务(SAVEPOINT),外层提交/回滚,内层保存点回滚,避免重复提交与状态不一致。
  • 数据导入与迁移
    • 导入时统一替换存储引擎与字符集,强制 utf8mb4 与 InnoDB,关闭外键约束后再执行,最后恢复约束。

章节来源

  • Connection.php:102-200
  • Connection.php:418-496
  • Connection.php:632-700
  • Model.php:35-51
  • Builder.php:25-31

架构总览

下图展示从配置到 ORM 再到业务的整体数据流与控制流。

sequenceDiagram
participant CFG as "配置<br/>config/config.php"
participant CONN as "连接层<br/>Connection.php"
participant ORM as "ORM层<br/>Model.php / Builder.php"
participant SVC as "业务服务<br/>OrderService.php / AftersaleService.php"
participant DB as "数据库<br/>dk_* 表结构"
CFG->>CONN : 初始化连接(主机/库/用户/密码/前缀/字符集)
CONN-->>CFG : 连接成功/失败
ORM->>CONN : table()/where()/select() 等链式调用
ORM->>SVC : 返回水合后的模型/集合
SVC->>CONN : beginTransaction()/commit()/rollback()
CONN->>DB : 执行SQL语句
DB-->>CONN : 返回结果
CONN-->>SVC : 事务结果

图表来源

  • config.php:15-31
  • Connection.php:102-200
  • Model.php:35-51
  • Builder.php:25-31
  • OrderService.php:628-677

详细组件分析

数据库连接与字符集策略

  • 连接建立
    • 使用 MySQLi 扩展;支持 IPv6 地址与端口解析;连接失败时记录错误并退出(调试模式下输出详细信息)。
  • 字符集
    • 默认将 utf-8/utf8 规范化为 utf8mb4;若环境不支持则降级为 utf8,并记录警告日志。
  • SQL 模式
    • 启用 STRICT_TRANS_TABLES 与 NO_ENGINE_SUBSTITUTION,避免静默截断与非法引擎替换;未开启零日期限制以兼容历史数据。
  • 表名前缀
    • 所有表名通过前缀注入,便于多租户/隔离部署。已全面迁移至 dk_ 前缀。
flowchart TD
Start(["连接初始化"]) --> CheckExt["检查MySQLi扩展"]
CheckExt --> |可用| ParseHost["解析主机/端口(含IPv6)"]
ParseHost --> Connect["mysqli_connect 建立连接"]
Connect --> SetCharset{"字符集=utf8mb4?"}
SetCharset --> |是| TryUtf8mb4["尝试设置utf8mb4"]
TryUtf8mb4 --> |失败| Fallback["降级为utf8"]
SetCharset --> |否| SetOther["设置其他字符集"]
Fallback --> Mode["设置SQL模式"]
SetOther --> Mode
Mode --> SelectDB["选择数据库"]
SelectDB --> End(["连接就绪"])

图表来源

  • Connection.php:102-200

章节来源

  • Connection.php:102-200

ORM 模型与查询构造器

  • 模型基类
    • 提供表名、主键、批量写入白名单、字段类型转换、多语言字段、时间戳、全局作用域、事件监听等能力。
    • 支持通过静态入口与实例化两种方式访问查询构造器。
  • 查询构造器
    • 在底层 Connection 之上提供链式 API;终结方法 get/first/find/paginate 会进行数据水合、预加载与 prefetch。
    • 聚合方法(count/sum/avg/max/min/value/exists/column)受全局作用域保护,保证一致性。
    • 支持 with 预加载嵌套关系与约束闭包。
classDiagram
class Model {
+string $table
+string $primary
+array $fillable
+array $casts
+array $with
+newQuery()
+create(attributes)
+destroy(id)
+getConnection()
}
class Builder {
-Model $model
-Connection $query
-array $eagerLoad
+with(relations)
+get()
+first(field)
+find(id, field)
+paginate(...)
}
Model --> Builder : "创建查询构造器"

图表来源

  • Model.php:35-51
  • Builder.php:25-31

章节来源

  • Model.php:35-51
  • Builder.php:25-31

事务管理与并发控制

  • 嵌套事务
    • 最外层 beginTransaction 关闭 autocommit;内层使用 SAVEPOINT;commit/rollback 在最外层生效,内层仅释放/回滚到保存点。
  • 业务示例
    • 订单取消流程中,先开启事务,批量更新订单及明细状态,成功后提交;异常时回滚并记录日志。
sequenceDiagram
participant SVC as "OrderService"
participant DB as "Connection"
SVC->>DB : beginTransaction()
loop 遍历待取消订单
SVC->>DB : update(order)
SVC->>DB : update(order_item)
end
alt 全部成功
SVC->>DB : commit()
else 发生异常
SVC->>DB : rollback()
SVC->>SVC : 记录错误日志
end

图表来源

  • Connection.php:418-496
  • OrderService.php:628-677

章节来源

  • Connection.php:418-496
  • OrderService.php:628-677

数据导入与存储引擎/字符集策略

  • 导入脚本
    • 统一将建表语句中的 ENGINE/TABLESPACE/CHARSET/COLLATE 替换为 InnoDB 与 utf8mb4/utf8mb4_unicode_ci。
    • 导入前关闭外键约束,导入完成后恢复,确保大批量导入效率与一致性。
  • 建议
    • 生产环境应确保数据库实例默认字符集与排序规则与导入一致,避免运行时降级。

章节来源

  • Connection.php:632-700

表前缀迁移与兼容性策略

新增 本项目已完成从 dou_ 到 dk_ 的前缀迁移,以下是迁移详情:

  • 配置变更

    • 配置文件中的 $prefix 从 'dou_' 更新为 'dk_'
    • 数据库名称保持为 douphp_dou,但所有表名现在使用 dk_ 前缀
  • 表结构对比

    • 旧表结构:dou_admin, dou_article, dou_user 等
    • 新表结构:dk_admin, dk_article, dk_user 等
    • 所有表的存储引擎从 MyISAM 升级到 InnoDB
    • 字符集从 utf8 升级到 utf8mb4
    • 字段类型和索引进行了优化
  • 兼容性处理

    • 连接层的 tableName() 方法动态生成带前缀的表名
    • ORM 层通过 DB::tableName() 方法确保表名正确拼接
    • 迁移脚本支持增量升级,不影响现有功能
flowchart LR
OldPrefix["旧前缀 dou_"] --> Migration["迁移过程"]
NewPrefix["新前缀 dk_"] --> Migration
Migration --> Compatibility["兼容性检查"]
Compatibility --> Success["迁移成功"]

章节来源

  • config.php:27-28
  • schema_new.sql:1-200
  • schema_old.sql:1-200

安全策略

  • SQL 注入防护
    • 连接层提供 escapeString 用于转义字符串;业务侧通过 ORM/Builder 的参数绑定与条件构造减少拼接风险。
    • 部分场景显式对入参做类型转换(如 intval)再拼入 IN 片段,降低注入面。
  • 权限与最小权限原则
    • 建议使用专用数据库账户,仅授予必要表的 SELECT/INSERT/UPDATE/DELETE 权限;避免使用 root 直连。
  • 敏感信息保护
    • 数据库凭据存放于配置文件,建议通过环境变量或密钥管理服务注入,避免硬编码。
  • 审计与日志
    • 业务变更(如订单取消)记录管理员操作日志,便于追溯。

章节来源

  • Connection.php:579-593
  • OrderService.php:628-677

性能优化策略

  • 索引设计原则
    • 高频查询条件列建立索引;复合索引遵循最左前缀原则;唯一约束用于强一致性字段(如单号)。
  • 查询优化技巧
    • 使用 ORM 的 with 预加载减少 N+1 查询;合理使用 limit/offset 分页;避免 select *,只取必要字段。
    • 聚合方法走白名单路径,确保全局作用域一致性与正确性。
  • 缓存策略
    • 读多写少的热点数据(如字典、配置)可使用应用缓存;注意缓存失效与一致性。
  • 事务粒度
    • 缩小事务范围,减少锁竞争;批量更新尽量合并为少次大事务。

章节来源

  • Builder.php:65-77
  • AftersaleService.php:35-50

监控与备份恢复

  • 监控指标
    • 连接数、慢查询、事务等待、锁冲突、磁盘 I/O、缓冲池命中率等。
    • 结合慢查询日志与性能_schema 视图定位瓶颈。
  • 备份策略
    • 全量备份(如 mysqldump)+ 增量备份(binlog);定期演练恢复流程。
    • 备份文件加密与异地容灾;保留策略符合合规要求。
  • 恢复方案
    • 按时间点恢复(PITR);验证数据一致性;灰度切换与回滚预案。

依赖关系分析

  • 配置到连接的依赖
    • 应用配置提供数据库连接参数;连接层负责建立连接、设置字符集与 SQL 模式。
  • ORM 对连接的依赖
    • Model/Builder 通过 Connection 进行表操作、查询构建与事务控制。
  • 业务对 ORM 的依赖
    • 业务服务通过 ORM/DB 门面完成数据读写,并在必要时使用事务保障一致性。
graph LR
CFG["配置"] --> CONN["连接层"]
CONN --> ORM["ORM 层"]
ORM --> SVC["业务服务"]
SVC --> TABLES["dk_* 表结构"]

图表来源

  • config.php:15-31
  • Connection.php:102-200
  • Model.php:35-51
  • Builder.php:25-31

章节来源

  • config.php:15-31
  • Connection.php:102-200
  • Model.php:35-51
  • Builder.php:25-31

性能考量

  • 连接与字符集
    • 确保 utf8mb4 支持;避免运行时降级导致额外开销。
  • 查询与索引
    • 优先使用索引列过滤;避免函数包裹索引列;合理设计复合索引。
  • 事务与锁
    • 缩短事务生命周期;避免长事务持有锁;批量操作分批提交。
  • 预加载与去重
    • 使用 with 预加载减少多次往返;利用 distinct/group by 优化聚合。
  • 导入与迁移
    • 导入时关闭外键约束提升速度;迁移前后校验数据完整性。

故障排查指南

  • 连接失败
    • 检查 MySQLi 扩展是否启用;确认主机、端口、用户名、密码;查看错误日志。
  • 字符集问题
    • 确认数据库实例与表/列字符集;若 utf8mb4 不可用,确认已降级至 utf8。
  • 事务异常
    • 检查嵌套事务是否正确提交/回滚;确认保存点命名与数量;捕获异常并记录上下文。
  • 导入失败
    • 确认外键约束已关闭/恢复;检查 SQL 语法与注释行处理;分段执行定位问题。
  • 表前缀问题
    • 确认配置中的 $prefix 设置为 'dk_';检查表名是否正确拼接;验证迁移脚本执行状态。

章节来源

  • Connection.php:102-200
  • Connection.php:418-496
  • Connection.php:632-700

结论

DouPHP 的数据库架构以"配置驱动 + 连接抽象 + ORM 增强"为核心,采用 MySQL 作为存储引擎,默认字符集 utf8mb4,导入阶段统一转换为 InnoDB 与 utf8mb4 排序规则。最新的前缀迁移从 dou_ 到 dk_ 进一步提升了系统的品牌一致性和部署灵活性。通过 ORM 的预加载、作用域与事件机制,以及连接层的严格 SQL 模式与事务支持,兼顾了开发体验与数据一致性。结合合理的索引设计、查询优化、缓存策略与完善的监控备份体系,可满足大多数企业级应用场景的性能与安全需求。

附录

  • 常用配置项
    • 数据库主机、库名、用户名、密码、表前缀(现为 dk_)、字符集。
  • 推荐实践
    • 使用专用数据库账户;最小权限原则;敏感配置外部化;定期备份与恢复演练;慢查询分析与索引优化。
  • 迁移注意事项
    • 前缀迁移需要停机维护;确保所有表结构完整迁移;验证业务功能正常;做好数据备份和回滚预案。
添加日期:2026-10-05