代理分润系统是源码交易平台、转卡码平台、支付中转服务等商业系统的核心功能模块之一。一套设计合理的分润数据库,不仅能准确记录每一笔分润流水,还能支撑高并发结算、多级代理关系和灵活的规则配置。
本文将从实战角度出发,完整讲解代理分润系统的数据库设计思路与核心SQL实现,涵盖代理等级管理、分润规则配置、自动结算与提现审批的全流程。文中所有建表语句和代码示例均来自 源码商城 实际使用的转卡码系统。
一、核心业务模型与ER设计
代理分润系统涉及五个核心实体:代理用户、代理等级、分润规则、结算流水和提现申请。它们之间的核心关系如下:
- 一个代理属于一个等级(等级定义了分润百分比和提现门槛)
- 每个等级可以配置多条分润规则(按订单类型、商品分类区分)
- 每笔成功订单生成一条或多条结算流水(关联到具体代理和规则)
- 代理发起提现,关联多条已结算流水
二、核心建表语句
1. 代理等级表(agent_levels)
CREATE TABLE `agent_levels` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '等级名称,如 普通代理、高级代理、金牌代理',
`level` tinyint(3) unsigned NOT NULL DEFAULT 1 COMMENT '等级数值,越大权限越高',
`profit_percent` decimal(5,2) NOT NULL DEFAULT 0.00 COMMENT '默认分润百分比,如 30.00 表示 30%',
`min_withdraw` decimal(10,2) NOT NULL DEFAULT 100.00 COMMENT '最低提现金额(元)',
`max_withdraw_daily` decimal(10,2) NOT NULL DEFAULT 5000.00 COMMENT '每日提现上限',
`auto_settle` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否自动结算 1=是 0=否',
`settle_interval` varchar(20) NOT NULL DEFAULT 'daily' COMMENT '结算周期:daily/weekly/monthly',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_level` (`level`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代理等级表';
2. 代理用户表(agents)
CREATE TABLE `agents` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL COMMENT '关联user表',
`parent_agent_id` int(11) unsigned DEFAULT NULL COMMENT '上级代理ID,NULL表示顶级',
`level_id` int(11) unsigned NOT NULL COMMENT '当前代理等级ID',
`invite_code` varchar(32) NOT NULL COMMENT '唯一邀请码',
`total_earnings` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计收益',
`balance` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '可提现余额',
`status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '1=正常 0=冻结',
`applied_at` datetime DEFAULT NULL COMMENT '申请成为代理的时间',
`approved_at` datetime DEFAULT NULL COMMENT '审核通过时间',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_invite_code` (`invite_code`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_parent` (`parent_agent_id`),
KEY `idx_level` (`level_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代理用户表';
3. 分润规则表(profit_rules)
CREATE TABLE `profit_rules` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`level_id` int(11) unsigned NOT NULL COMMENT '关联代理等级',
`rule_name` varchar(100) NOT NULL COMMENT '规则名称',
`product_type` varchar(50) DEFAULT NULL COMMENT '商品类型,NULL表示全部',
`profit_type` enum('percent','fixed') NOT NULL DEFAULT 'percent' COMMENT '分润类型:百分比或固定金额',
`profit_value` decimal(10,2) NOT NULL COMMENT '分润值(百分比如30.00 或 固定金额如5.00)',
`parent_share` decimal(5,2) DEFAULT 0.00 COMMENT '上级代理分润比例(%),支持多级',
`grandparent_share` decimal(5,2) DEFAULT 0.00 COMMENT '上上级代理分润比例',
`priority` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT '优先级,数值越大越优先',
`status` tinyint(1) NOT NULL DEFAULT 1,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_level_product` (`level_id`, `product_type`),
KEY `idx_priority` (`priority`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分润规则表';
4. 结算流水表(settlement_logs)
这是整个系统最核心的表,每笔订单的每一级分润都会生成一条记录:
CREATE TABLE `settlement_logs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`order_id` varchar(64) NOT NULL COMMENT '原始订单ID',
`agent_id` int(11) unsigned NOT NULL COMMENT '获得分润的代理ID',
`profit_rule_id` int(11) unsigned DEFAULT NULL COMMENT '关联的分润规则ID',
`order_amount` decimal(10,2) NOT NULL COMMENT '订单金额',
`profit_amount` decimal(10,2) NOT NULL COMMENT '分润金额',
`profit_level` tinyint(3) unsigned NOT NULL DEFAULT 1 COMMENT '分润层级:1=直推 2=间推 3=三级',
`status` enum('pending','settled','frozen','cancelled') NOT NULL DEFAULT 'pending' COMMENT '结算状态',
`settle_batch_no` varchar(64) DEFAULT NULL COMMENT '结算批次号,用于批量结算对账',
`remark` varchar(255) DEFAULT NULL,
`settled_at` datetime DEFAULT NULL COMMENT '实际结算时间',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_status` (`status`),
KEY `idx_agent_status` (`agent_id`, `status`),
KEY `idx_settle_batch` (`settle_batch_no`),
KEY `idx_created` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='结算流水表';
-- 按月分区示例,提升海量数据查询性能
ALTER TABLE `settlement_logs`
PARTITION BY RANGE (TO_DAYS(`created_at`)) (
PARTITION p202606 VALUES LESS THAN (TO_DAYS('2026-07-01')),
PARTITION p202607 VALUES LESS THAN (TO_DAYS('2026-08-01')),
PARTITION p202608 VALUES LESS THAN (TO_DAYS('2026-09-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
5. 提现申请表(withdraw_requests)
CREATE TABLE `withdraw_requests` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`agent_id` int(11) unsigned NOT NULL,
`amount` decimal(10,2) NOT NULL COMMENT '提现金额',
`fee` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '手续费',
`actual_amount` decimal(10,2) NOT NULL COMMENT '实际到账金额',
`account_type` enum('alipay','wechat','bank') NOT NULL COMMENT '提现账户类型',
`account_info` varchar(500) NOT NULL COMMENT '账户信息JSON',
`status` enum('pending','processing','success','failed','rejected') NOT NULL DEFAULT 'pending',
`reviewer_id` int(11) unsigned DEFAULT NULL COMMENT '审核人',
`review_remark` varchar(255) DEFAULT NULL,
`reviewed_at` datetime DEFAULT NULL,
`completed_at` datetime DEFAULT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_status` (`status`),
KEY `idx_agent_status` (`agent_id`, `status`),
KEY `idx_created` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='提现申请表';
三、分润计算逻辑的Python实现
有了数据库表结构,接下来看看分润计算的完整逻辑。以下是一个通用的多级分润计算函数:
#!/usr/bin/env python3
# profit_calc.py - 多级分润计算引擎
import pymysql
from decimal import Decimal
def calculate_profit(order_id, order_amount, product_type):
"""
根据订单计算各级代理分润
返回分润记录列表 [(agent_id, profit_amount, level), ...]
"""
conn = get_db_connection()
cursor = conn.cursor(pymysql.cursors.DictCursor)
# 1. 查询下单用户的上级代理链(最多3级)
cursor.execute("""
WITH RECURSIVE agent_chain AS (
SELECT id, user_id, parent_agent_id, level_id, 1 AS depth
FROM agents WHERE user_id = %s
UNION ALL
SELECT a.id, a.user_id, a.parent_agent_id, a.level_id, ac.depth + 1
FROM agents a
INNER JOIN agent_chain ac ON a.id = ac.parent_agent_id
WHERE ac.depth < 3
)
SELECT * FROM agent_chain ORDER BY depth
""", (order_user_id,))
chain = cursor.fetchall()
# 2. 对每一级代理,查询匹配的分润规则
profit_records = []
for row in chain:
agent_id = row['id']
level_id = row['level_id']
depth = row['depth']
cursor.execute("""
SELECT * FROM profit_rules
WHERE level_id = %s
AND (product_type IS NULL OR product_type = %s)
AND status = 1
ORDER BY priority DESC
LIMIT 1
""", (level_id, product_type))
rule = cursor.fetchone()
if not rule:
continue
# 根据规则计算分润金额
share_key = {1: 'parent_share', 2: 'grandparent_share'}.get(depth)
if depth == 1:
profit_pct = Decimal(str(rule['profit_value']))
elif share_key and rule[share_key]:
profit_pct = Decimal(str(rule[share_key]))
else:
continue
profit_amount = order_amount * profit_pct / Decimal('100')
profit_records.append({
'agent_id': agent_id,
'order_id': order_id,
'order_amount': order_amount,
'profit_amount': profit_amount.quantize(Decimal('0.01')),
'profit_level': depth,
'profit_rule_id': rule['id'],
'status': 'pending'
})
# 3. 批量插入结算流水表
if profit_records:
insert_sql = """
INSERT INTO settlement_logs
(order_id, agent_id, profit_rule_id, order_amount,
profit_amount, profit_level, status)
VALUES (%(order_id)s, %(agent_id)s, %(profit_rule_id)s,
%(order_amount)s, %(profit_amount)s, %(profit_level)s, %(status)s)
"""
cursor.executemany(insert_sql, profit_records)
conn.commit()
cursor.close()
conn.close()
return profit_records
四、索引优化与性能调优
分润系统在日订单量过万后,结算流水表会迅速膨胀到百万级。以下是我在实际项目中总结的关键优化策略:
4.1 复合索引优先
最频繁的查询是按代理ID+状态筛选待结算记录:
-- 高频查询:查某个代理的待结算流水
EXPLAIN SELECT * FROM settlement_logs WHERE agent_id=123 AND status='pending';
-- 已经建立了复合索引 idx_agent_status,覆盖此查询
-- 查某批次的结算记录用于对账
EXPLAIN SELECT * FROM settlement_logs WHERE settle_batch_no='B20260713001';
-- idx_settle_batch 索引确保该查询走索引而非全表扫描
4.2 按月分区表
如前文建表语句所示,对 settlement_logs 按月分区后,查询某个月的数据直接在对应分区扫描,避免跨分区全表扫描。配合定时任务自动创建新分区:
# crontab - 每月1日凌晨创建下月分区
0 3 1 * * /usr/bin/python3 /opt/scripts/create_partition.py
4.3 批量结算代替逐条结算
不要在每次订单完成时立即结算,而是使用定时任务批量结算,减少数据库事务频次:
UPDATE settlement_logs
SET status = 'settled',
settle_batch_no = CONCAT('B', DATE_FORMAT(NOW(), '%Y%m%d'), LPAD(@batch_seq, 4, '0')),
settled_at = NOW()
WHERE status = 'pending'
AND created_at < DATE_SUB(NOW(), INTERVAL 1 HOUR)
LIMIT 500;
五、与转卡码系统的集成
在 源码商城 提供的 转卡码系统 中,代理分润模块与订单系统深度集成。当客户购买卡密并通过回调确认支付成功后,系统自动根据上述数据库结构和计算逻辑,在同一个事务中完成以下操作:
- 扣减卡密库存
- 记录订单状态为已支付
- 查询下单用户的代理链
- 按照分润规则表计算各级分润
- 插入结算流水记录
- 更新代理余额
💡 提示: 源码商城的转卡码系统 V3 版本内置了完整的代理分润模块,支持多级代理、自动结算、批量提现等功能。购买即送完整数据库设计文档。
六、总结
一个设计良好的代理分润数据库,是整个代理体系稳定运行的基石。本文从五个核心表出发,完整介绍了代理分润系统的数据库设计思路、SQL建表语句、Python分润计算实现以及索引优化策略。良好的ER设计加上合理的索引和分区,可以支撑百万级日订单量的分润结算需求。
关键设计要点回顾:
- 结算流水表 采用按月分区,配合复合索引覆盖高频查询
- 分润规则表 支持百分比与固定金额两种模式,并可配置多级代理共享比例
- 批量结算 代替逐条更新,显著降低数据库压力
- 使用 递归CTE 高效查询代理链,避免应用层多次查询