简介
本文件面向数据库管理员与后端开发者,系统化梳理 DouPHP v2.0 的数据库架构与数据模型。本次更新重点反映了从 dou* 到 dk* 表前缀系统的重大架构转换,以及增强的安全特性和现代化的数据类型。内容涵盖:
- 整体架构与模块划分
- 核心业务实体(用户、商品、订单、内容)的关系建模
- 表结构设计要点(字段、类型、约束、索引)
- 数据访问模式(ORM 使用、查询优化、事务处理)
- 迁移与版本管理方案
- 数据安全、备份恢复与性能调优建议
更新 本次更新重点介绍了 DouPHP v2.0 的重大架构转换,包括表前缀从 dou* 到 dk* 的迁移、多表用户架构的设计、增强的安全特性和现代化的数据格式。
项目结构
DouPHP v2.0 采用模块化组织,每个业务模块在 storage/backup 下提供独立的 SQL 建表脚本,便于安装、升级与回滚。核心 ORM 位于 core/orm,统一封装模型、关系与查询构建器;数据库连接与配置集中在 config/config.php。v2.0 引入了新的 API 层,使用 dk_ 作为默认表前缀。
graph TB
A["应用入口<br/>index.php"] --> B["路由与控制器<br/>admin/api/front"]
B --> C["服务层<br/>service/*"]
C --> D["模型层<br/>core/orm + module/*/model"]
D --> E["ORM 基类<br/>Model.php"]
E --> F["数据库连接<br/>DB/Connection"]
F --> G["MySQL 数据库<br/>douphp_dou"]
subgraph "模块SQL"
H["user.sql"]
I["product.sql"]
J["order.sql"]
K["schema_new.sql"]
end
G --- H
G --- I
G --- J
G --- K
核心组件
- 数据库配置与连接
- 主机、库名、用户名、密码、表前缀、字符集等集中定义,便于多环境切换与部署。
- v2.0 中 API 层默认使用 dk 表前缀,主应用保持 dou 前缀以支持向后兼容。
- ORM 基类与关系
- 提供 ActiveRecord 风格的数据访问:find/first/get/create/update/delete、with 预加载、HasOne/HasMany/BelongsTo 关系、全局 Scope、事件钩子、时间戳等。
- 模块化表结构
- 各模块以独立 SQL 脚本维护表结构,支持增量升级与回滚。
- 所有表使用 utf8mb4_unicode_ci 字符集,支持完整的 Unicode 字符集。
更新 v2.0 引入了新的 API 层,默认使用 dk 表前缀,同时保持了主应用的 dou 前缀兼容性。多表用户架构通过 dk_user、dk_user_contact、dk_user_wallet 等表分离不同关注点,提高了系统的可扩展性和维护性。
架构总览
下图展示从请求到数据落库的关键路径,以及 ORM 如何映射到具体表结构。v2.0 的架构支持双表前缀系统,确保向后兼容的同时引入新的现代化特性。
sequenceDiagram
participant Client as "客户端"
participant API as "API/控制器"
participant Service as "服务层"
participant Model as "ORM 模型"
participant DB as "数据库连接"
participant MySQL as "MySQL"
Client->>API : "发起请求"
API->>Service : "调用业务方法"
Service->>Model : "构造查询/保存数据"
Model->>DB : "执行SQL (dk_ 或 dou_ 前缀)"
DB->>MySQL : "读写操作"
MySQL-->>DB : "返回结果"
DB-->>Model : "结果集/影响行数"
Model-->>Service : "实体/集合"
Service-->>API : "业务结果"
API-->>Client : "响应数据"
详细组件分析
用户域数据模型
更新 采用多表架构设计,将用户相关数据分散到多个表中以提高可扩展性:
- 主要表
- dk_user:用户主表,包含唯一编号、联系方式、认证令牌、状态、登录统计等核心信息。
- dk_user_contact:收货联系人信息,支持多地址管理。
- dk_user_level / dk_user_level_log:会员等级及升级日志。
- dk_user_log:用户行为审计日志。
- dk_user_sns:第三方账号绑定。
- dk_user_tag:用户标签。
- dk_user_token:API 会话令牌存储。
- dk_user_wallet:钱包余额与积分账户。
- 关键约束与索引
- 唯一键:user_sn、email、mobile。
- 常用查询索引:user_id、action、ip、created_at、tag 等。
- 关系说明
- 用户与联系人、等级、标签、SNS、钱包为 1:N 或 1:1 关系。
- 订单、售后、支付、退款通过 user_id 关联。
erDiagram
DK_USER {
int id PK
varchar user_sn UK
varchar email UK
varchar mobile UK
varchar status
datetime created_at
}
DK_USER_CONTACT {
int id PK
int user_id FK
varchar phone
varchar address
tinyint is_default
}
DK_USER_LEVEL {
int id PK
varchar name
decimal upgrade_condition
}
DK_USER_LEVEL_LOG {
int id PK
int user_id FK
int old_level_id
int new_level_id
datetime created_at
}
DK_USER_TOKEN {
int id PK
int user_id FK
char token_hash UK
datetime expires_at
}
DK_USER_WALLET {
int id PK
decimal money_balance
decimal point_balance
decimal total_consumption
}
DK_USER ||--o{ DK_USER_CONTACT : "拥有多个联系人"
DK_USER ||--|| DK_USER_WALLET : "一对一钱包"
DK_USER ||--o{ DK_USER_LEVEL_LOG : "等级变更日志"
DK_USER ||--o{ DK_USER_TOKEN : "多会话令牌"
扩展模块数据模型
新增 系统提供了扩展模块功能,支持插件化开发:
- 主要表
- dk_extend:扩展模块主表,包含模块元数据、价格、版本信息等。
- dk_extend_category:扩展模块分类表。
- dk_history:扩展模块历史版本记录。
- 关键特性
- 支持多种价格策略(原价、促销价、VIP价、等级价)。
- 支持多平台适配(PC、平板、移动端)。
- 支持小程序版本兼容。
商品域数据模型
- 主要表
- dk_product:商品主表,含分类、品牌、价格、促销价、库存、销量、SEO 等。
- dk_product_category:商品分类树。
- 关键约束与索引
- 主键自增 id。
- 常用查询索引:slug、operator_type+operator_id。
- 关系说明
- 商品属于分类,可归属品牌;与订单明细通过 item_id 关联。
erDiagram
DK_PRODUCT {
int id PK
smallint category_id
enum operator_type
mediumint brand_id
decimal price
decimal promote_price
smallint stock
mediumint sales
varchar slug
datetime created_at
}
DK_PRODUCT_CATEGORY {
smallint id PK
varchar slug
varchar name
smallint parent_id
tinyint sort
}
DK_PRODUCT_CATEGORY ||--o{ DK_PRODUCT : "分类包含商品"
订单域数据模型
- 主要表
- dk_order:订单主表,含用户、推荐关系、支付方式、物流、金额、状态机字段、时间戳等。
- dk_order_address:订单收货地址快照。
- dk_order_cart:购物车临时记录。
- dk_order_coupon:订单使用的优惠券。
- dk_order_invoice:发票信息。
- dk_order_item:订单明细(商品快照、数量、价格、属性、售后/评价标记)。
- dk_order_payment:支付流水(网关、交易号、凭证、回调报文)。
- dk_order_refund:退款记录。
- dk_order_status_log:订单状态流转日志。
- 关键约束与索引
- 唯一键:order_sn、payment_sn、refund_sn、uniq_order(地址/发票与订单一一对应)。
- 复合索引:user_id+status、status+created_at、paid_at、pay_id+status+paid_at、order_id+gateway 等,覆盖高频查询与对账场景。
- 关系说明
- 订单与用户、地址、发票、优惠券、支付、退款、状态日志为 1:N 关系。
- 订单与商品明细为 1:N 关系。
erDiagram
DK_ORDER {
int id PK
varchar order_sn UK
mediumint user_id
varchar status
decimal order_amount
decimal wallet_paid
decimal gateway_paid
datetime paid_at
datetime shipped_at
datetime completed_at
}
DK_ORDER_ITEM {
int id PK
int order_id FK
smallint item_id
decimal sale_price
smallint item_number
varchar attribute
tinyint aftersale
tinyint comment
}
DK_ORDER_PAYMENT {
int id PK
int order_id FK
varchar payment_sn UK
varchar gateway
decimal amount
varchar transaction_id
datetime paid_at
}
DK_ORDER_REFUND {
int id PK
int order_id FK
varchar refund_sn UK
decimal amount
varchar status
}
DK_ORDER_ADDRESS {
int id PK
int order_id FK UK
varchar contact_name
varchar phone
}
DK_ORDER_INVOICE {
int id PK
int order_id FK UK
varchar title
tinyint is_issued
}
DK_ORDER_COUPON {
int id PK
int order_id FK
mediumint coupon_id
decimal amount
}
DK_ORDER_STATUS_LOG {
int id PK
int order_id FK
varchar from_status
varchar to_status
datetime created_at
}
DK_ORDER ||--o{ DK_ORDER_ITEM : "包含多条明细"
DK_ORDER ||--o{ DK_ORDER_PAYMENT : "多次支付"
DK_ORDER ||--o{ DK_ORDER_REFUND : "多次退款"
DK_ORDER ||--|| DK_ORDER_ADDRESS : "收货地址快照"
DK_ORDER ||--|| DK_ORDER_INVOICE : "发票信息"
DK_ORDER ||--o{ DK_ORDER_COUPON : "使用优惠券"
DK_ORDER ||--o{ DK_ORDER_STATUS_LOG : "状态流转日志"
内容域数据模型(文章)
- 主要表
- 文章内容、分类、SEO、状态、排序等。
- 关系说明
- 文章与分类为 N:1 关系;与评论、收藏、分享等扩展模块通过外键或中间表关联(由对应模块 SQL 定义)。
ORM 数据访问模式
- 读路径
- 通过 Model::query()/where()/with() 构建查询,底层经 Builder 生成 SQL,返回 hydrated 模型或集合。
- 写路径
- create/fill/save 写入新记录;update/destroy 更新或删除;批量 destroy 触发模型事件。
- 关系与预加载
- with() 预加载避免 N+1;关系方法返回 Relation 实例并缓存结果。
- 事件与全局作用域
- deleting/deleted 事件用于级联清理或审计;addGlobalScope 实现软删除、租户隔离等通用过滤。
flowchart TD
Start(["开始"]) --> Q["构造查询<br/>Model::query()->where()->with()"]
Q --> Exec{"执行查询"}
Exec --> |成功| Hydrate["水合模型/集合"]
Exec --> |失败| HandleErr["异常处理/重试"]
Hydrate --> Return["返回结果"]
HandleErr --> Return
Return --> End(["结束"])
依赖关系分析
- 模块间耦合
- 订单域强依赖用户域(user_id)、商品域(item_id)、支付/退款模块(gateway、transaction_id)。
- 内容域相对独立,主要通过分类与标签与其他模块产生弱耦合。
- 外部依赖
- 支付网关、短信、邮件、云存储等通过 service 层抽象,不直接侵入数据模型。
- 潜在循环依赖
- 通过外键与领域边界控制,避免跨模块直接引用;必要时使用"快照字段"(如订单中的商品名称、价格)降低实时关联成本。
更新 新的多表用户架构通过清晰的表间关系,降低了模块间的耦合度,提高了系统的可维护性。v2.0 的双表前缀系统确保了向后兼容性。
graph LR
U["用户域"] --> O["订单域"]
P["商品域"] --> O
O --> S["售后/退款"]
O --> M["支付/提现"]
A["内容域"] -.-> O
A -.-> U
性能考虑
- 索引策略
- 订单表已针对 user_id+status、status+created_at、paid_at、pay_id+status+paid_at 建立复合索引,利于按用户与状态维度的报表与对账查询。
- 商品表对 slug 与 operator 维度建立索引,提升前端展示与后台筛选效率。
- 用户表对 email/mobile/openid 建立唯一索引,保障登录与第三方登录性能。
- 查询优化
- 使用 with() 预加载减少 N+1 查询。
- 分页查询限制返回字段,避免大对象(如 content/defined)参与不必要计算。
- 对高频条件列建立合适索引,避免全表扫描。
- 事务与一致性
- 涉及订单创建、支付、库存扣减、钱包变动等多表写操作时,务必使用事务保证原子性。
- 支付幂等:利用 payment_sn/gateway+transaction_id 唯一约束防止重复入账。
- 存储与归档
- 日志类表(订单状态日志、用户日志、等级日志)定期归档或分区,控制单表规模。
- 大文本字段(content/raw_request/raw_callback)注意冷热分离与压缩策略。
更新 多表架构通过合理的数据分片,减少了单表数据量,提升了查询性能和维护效率。v2.0 的 utf8mb4 字符集支持更丰富的字符集需求。
故障排查指南
- 常见问题定位
- 订单未到账:检查 dk_order_payment.status、gateway、transaction_id 与回调报文 raw_callback。
- 重复支付:核对 payment_sn 唯一性与幂等逻辑。
- 用户无法登录:校验 email/mobile 唯一冲突、token 过期、登录失败次数与锁定时间。
- 商品不可见:确认 product.status、category 层级、slug 是否被占用。
- 审计与追踪
- 使用 dk_order_status_log、dk_user_log 回溯状态变化与操作来源。
- 结合 IP、操作人、时间戳进行问题定界。
结论
DouPHP v2.0 的数据库设计以模块化为核心,通过清晰的实体关系、合理的索引与约束、以及统一的 ORM 抽象,支撑了用户、商品、订单、内容等核心业务的稳定运行。重大的架构转换从 dou* 到 dk* 表前缀系统进一步提升了系统的可扩展性和维护性。建议在后续演进中持续完善:
- 补充内容域的完整表结构与关系图
- 引入更完善的迁移工具链与灰度发布流程
- 强化监控与慢查询治理,持续优化热点表与索引
- 充分利用多表架构优势,进一步优化查询性能和存储空间
- 确保双表前缀系统的平滑过渡和数据一致性
附录
- 数据库连接与配置
- 主机、库名、用户名、密码、表前缀、字符集等配置项位于配置文件,便于多环境管理与安全隔离。
- v2.0 中 API 层默认使用 dk 表前缀,主应用保持 dou 前缀以支持向后兼容。
- 迁移与版本管理
- 每个模块的 storage/backup/*.sql 作为基准结构;_update 目录存放增量升级脚本,配合工具实现平滑升级与回滚。
- 提供了从 dou* 到 dk* 的完整迁移路径和升级脚本。
- 安全与备份
- 敏感字段(密码、令牌、身份证号)需加密存储与脱敏展示。
- 制定定期全量与增量备份策略,保留足够历史副本,并进行恢复演练。
更新 新的多表架构和双表前缀系统需要特别注意数据一致性和完整性约束,建议在数据迁移过程中加强验证和测试。v2.0 的 utf8mb4 字符集支持更丰富的国际化需求。