订单支付系统是电商、本地生活等线上交易类业务的核心模块,使用mysql设计该系统的数据库时,需要覆盖订单创建、支付发起、支付回调、退款处理等全流程业务场景,同时保障数据的准确性和一致性。

核心业务场景梳理
在设计表结构前,需要先明确订单支付系统的核心业务流程:用户提交订单生成待支付订单,用户发起支付后生成支付记录,支付渠道回调通知支付结果,支付成功后订单状态更新,若发生退款则生成退款记录并更新订单和支付状态。基于这些场景,我们需要设计对应的核心表。
核心表结构设计
1. 订单表 order_info
订单表用于存储用户提交的基础订单信息,是系统的核心基础表,字段设计如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| order_no | varchar(64) | 订单编号,唯一索引,对外展示使用 |
| user_id | bigint | 用户ID,普通索引 |
| total_amount | decimal(10,2) | 订单总金额,单位元 |
| pay_amount | decimal(10,2) | 实际支付金额,单位元 |
| order_status | tinyint | 订单状态:0待支付,1已支付,2已取消,3已完成,4已退款 |
| create_time | datetime | 订单创建时间 |
| update_time | datetime | 订单更新时间 |
对应的建表sql如下:
CREATE TABLE `order_info` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `order_no` varchar(64) NOT NULL COMMENT '订单编号', `user_id` bigint NOT NULL COMMENT '用户ID', `total_amount` decimal(10,2) NOT NULL COMMENT '订单总金额', `pay_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '实际支付金额', `order_status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态:0待支付,1已支付,2已取消,3已完成,4已退款', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`), KEY `idx_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单基础信息表';
2. 支付记录表 pay_record
支付记录表用于存储每一次支付发起的相关信息,一个订单可能对应多次支付尝试,因此订单和支付记录是一对多的关系。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| pay_no | varchar(64) | 支付流水号,唯一索引 |
| order_no | varchar(64) | 关联订单编号,普通索引 |
| pay_channel | tinyint | 支付渠道:1微信,2支付宝,3银行卡 |
| pay_amount | decimal(10,2) | 本次支付金额 |
| pay_status | tinyint | 支付状态:0待支付,1支付成功,2支付失败,3支付关闭 |
| channel_trade_no | varchar(64) | 第三方支付渠道的交易号 |
| create_time | datetime | 支付记录创建时间 |
| update_time | datetime | 支付记录更新时间 |
对应的建表sql如下:
CREATE TABLE `pay_record` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `pay_no` varchar(64) NOT NULL COMMENT '支付流水号', `order_no` varchar(64) NOT NULL COMMENT '关联订单编号', `pay_channel` tinyint NOT NULL COMMENT '支付渠道:1微信,2支付宝,3银行卡', `pay_amount` decimal(10,2) NOT NULL COMMENT '本次支付金额', `pay_status` tinyint NOT NULL DEFAULT '0' COMMENT '支付状态:0待支付,1支付成功,2支付失败,3支付关闭', `channel_trade_no` varchar(64) DEFAULT NULL COMMENT '第三方支付渠道交易号', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_pay_no` (`pay_no`), KEY `idx_order_no` (`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付记录表';
3. 退款记录表 refund_record
退款记录表用于存储退款相关的信息,一个支付记录可能对应多次退款,因此支付记录和退款记录是一对多的关系。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| refund_no | varchar(64) | 退款流水号,唯一索引 |
| pay_no | varchar(64) | 关联支付流水号,普通索引 |
| refund_amount | decimal(10,2) | 退款金额 |
| refund_status | tinyint | 退款状态:0待审核,1退款中,2退款成功,3退款失败 |
| refund_reason | varchar(255) | 退款原因 |
| create_time | datetime | 退款记录创建时间 |
| update_time | datetime | 退款记录更新时间 |
对应的建表sql如下:
CREATE TABLE `refund_record` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `refund_no` varchar(64) NOT NULL COMMENT '退款流水号', `pay_no` varchar(64) NOT NULL COMMENT '关联支付流水号', `refund_amount` decimal(10,2) NOT NULL COMMENT '退款金额', `refund_status` tinyint NOT NULL DEFAULT '0' COMMENT '退款状态:0待审核,1退款中,2退款成功,3退款失败', `refund_reason` varchar(255) DEFAULT NULL COMMENT '退款原因', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_refund_no` (`refund_no`), KEY `idx_pay_no` (`pay_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='退款记录表';
表关联与事务处理
订单支付流程中涉及多表更新,比如支付成功后需要更新order_info的订单状态,同时更新pay_record的支付状态,这类操作需要使用mysql的事务保障一致性,示例代码如下:
-- 开启事务 START TRANSACTION; -- 更新支付记录状态为成功 UPDATE pay_record SET pay_status = 1, channel_trade_no = '第三方交易号123' WHERE pay_no = 'PAY20240501001'; -- 更新订单状态为已支付,更新实际支付金额 UPDATE order_info SET order_status = 1, pay_amount = 99.00 WHERE order_no = 'ORDER20240501001'; -- 提交事务 COMMIT;
如果更新过程中出现异常,需要执行ROLLBACK回滚事务,避免数据不一致。
设计注意事项
- 订单编号、支付流水号、退款流水号建议采用全局唯一规则生成,避免重复。
- 金额字段统一使用
decimal类型,不要使用float或double,避免精度丢失问题。 - 高频查询的字段需要添加合适的索引,提升查询效率,但不要过度添加索引影响写入性能。
- 重要状态变更建议添加操作日志表,记录每一次状态修改的操作人、操作时间、修改前后的值,便于问题排查。