32 KiB
流量池系统设计文档 - 评审与优化建议
评审版本:V1.0
评审日期:2026-01-29
原文档:traffic_pool_design.md
目录
一、逻辑问题(必须修复)
1.1 🔴 分组规则逻辑运算符设计缺陷
问题描述:
当前 ck_traffic_pool_group_rule 表的设计无法正确表达复杂的逻辑关系。
原设计示例:
-- 高价值客户池规则
(2, 0, 'friendStatus', '=', '2', 'number', 'AND'),
(2, 0, 'rfmM', '>=', '1000', 'number', 'OR'),
(2, 0, 'level', '=', '2', 'number', 'AND');
问题:
- 平铺结构无法表达括号分组:
A AND (B OR C)这种逻辑无法实现 - 逻辑运算符优先级不明确:上述规则会被解析为
A AND B OR C AND ? - 最后一条规则的
logicOperator无意义
业务需求理解:
高价值客户池应该是:已通过好友 AND (消费金额>=1000 OR 等级=VIP)
解决方案:
方案A:使用嵌套JSON结构(推荐)
直接在 ck_traffic_pool_group.ruleConfig 中存储完整规则,废弃 ck_traffic_pool_group_rule 表:
{
"logic": "AND",
"conditions": [
{
"type": "field",
"field": "friendStatus",
"operator": "=",
"value": 2,
"valueType": "number"
},
{
"type": "group",
"logic": "OR",
"conditions": [
{
"type": "field",
"field": "rfmM",
"operator": ">=",
"value": 1000,
"valueType": "number"
},
{
"type": "field",
"field": "level",
"operator": "=",
"value": 2,
"valueType": "number"
}
]
}
]
}
方案B:保留规则表,增加分组支持
ALTER TABLE ck_traffic_pool_group_rule ADD COLUMN (
ruleGroup INT NOT NULL DEFAULT 0 COMMENT '规则分组(同组内用组内逻辑,组间用组间逻辑)',
groupLogic VARCHAR(10) DEFAULT 'AND' COMMENT '组间逻辑关系'
);
修改后的数据示例:
-- 高价值客户池规则
-- 组0:friendStatus = 2
-- 组1:rfmM >= 1000 OR level = 2
-- 组间逻辑:AND
(2, 0, 'friendStatus', '=', '2', 'number', 'AND', 0, 'AND'),
(2, 0, 'rfmM', '>=', '1000', 'number', 'OR', 1, 'AND'),
(2, 0, 'level', '=', '2', 'number', 'AND', 1, 'AND');
推荐方案A,原因:
- JSON 结构更灵活,支持无限层级嵌套
- 前端配置界面更容易实现拖拽嵌套
- 减少一张表的维护成本
1.2 🔴 RFM 的 R 值设计问题
问题描述:
rfmR 字段定义为"最近一次互动距今天数",但这是一个动态值,会随时间自动增长。
问题:
- 存储的值会"自动过期":今天存的
rfmR=0,明天实际应该是rfmR=1 - 需要定时任务每天更新全表数据,成本极高
- 查询时数据可能不准确
解决方案:
方案A:改为存储时间戳(推荐)
-- 修改字段定义
ALTER TABLE ck_traffic_pool_company
MODIFY COLUMN rfmR INT(11) DEFAULT NULL COMMENT 'R值-最后互动时间戳(动态计算距今天数)';
-- 或者重命名更清晰
ALTER TABLE ck_traffic_pool_company
CHANGE rfmR lastInteractTime INT(11) DEFAULT NULL COMMENT '最后互动时间';
查询时动态计算:
SELECT
*,
DATEDIFF(NOW(), FROM_UNIXTIME(lastInteractTime)) AS rfmR
FROM ck_traffic_pool_company;
方案B:保留 rfmR,增加计算时间字段
ALTER TABLE ck_traffic_pool_company ADD COLUMN
rfmCalculateTime INT(11) DEFAULT NULL COMMENT 'RFM计算时间';
查询时校正:
SELECT
*,
rfmR + DATEDIFF(NOW(), FROM_UNIXTIME(rfmCalculateTime)) AS realRfmR
FROM ck_traffic_pool_company;
推荐方案A,原因:
- 数据永远准确,无需定时任务
- 存储空间相同
- 计算成本可接受
1.3 🔴 identifier 唯一性与流量合并问题
问题描述:
同一个真实用户可能通过不同渠道进入系统,产生多条流量记录:
| 场景 | identifier | 问题 |
|---|---|---|
| 手机号获客 | 13800138000 | identifierType=3 |
| 微信群成员 | wxid_abc123 | identifierType=1 |
| 后续确认是同一人 | ? | 如何合并? |
当前设计缺陷:
- 缺少流量合并机制
- 无法记录合并历史
- 合并后历史数据如何处理不明确
解决方案:
在 ck_traffic_pool 表增加合并字段
ALTER TABLE ck_traffic_pool ADD COLUMN (
mergeStatus TINYINT(1) DEFAULT 0 COMMENT '合并状态:0=正常,1=已被合并',
mergedToId INT(11) UNSIGNED DEFAULT NULL COMMENT '被合并到的目标流量ID',
mergeTime INT(11) DEFAULT NULL COMMENT '合并时间'
);
-- 增加索引
ALTER TABLE ck_traffic_pool ADD INDEX idx_mergedToId (mergedToId);
新增流量合并记录表
CREATE TABLE `ck_traffic_pool_merge_record` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`targetPoolId` INT(11) UNSIGNED NOT NULL COMMENT '目标流量ID(保留的)',
`sourcePoolId` INT(11) UNSIGNED NOT NULL COMMENT '来源流量ID(被合并的)',
`sourceIdentifier` VARCHAR(64) NOT NULL COMMENT '来源标识',
`mergeReason` VARCHAR(255) DEFAULT NULL COMMENT '合并原因',
`operatorId` INT(11) DEFAULT NULL COMMENT '操作人ID',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_targetPoolId` (`targetPoolId`),
KEY `idx_sourcePoolId` (`sourcePoolId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量合并记录表';
合并业务逻辑
1. 确认两条流量属于同一人
↓
2. 选择主流量(优先微信ID)
↓
3. 更新被合并流量:mergeStatus=1, mergedToId=主流量ID
↓
4. 迁移/合并子表数据(source、tag、behavior等)
↓
5. 记录合并日志
二、不合理之处(建议修复)
2.1 🟡 重复唯一索引
问题描述:
ck_traffic_pool_company 表有两个功能重复的唯一索引:
uk_pool_company (poolId, companyId)
uk_identifier_company (identifier, companyId)
由于 poolId 与 identifier 在 ck_traffic_pool 表中是一一对应关系,这两个索引实际等价。
建议:
保留 uk_identifier_company,删除 uk_pool_company:
ALTER TABLE ck_traffic_pool_company DROP INDEX uk_pool_company;
理由:
identifier是业务标识,查询更常用- 保留
poolId字段但不建唯一索引,仍可用于关联查询
2.2 🟡 微信标签同步逻辑不清晰
问题描述:
文档未说明微信标签同步的详细逻辑:
- 如何匹配已存在的标签定义?
- 新标签如何自动创建
tag_define记录? - 微信侧删除标签后,流量池如何处理?
- 标签名称变更如何同步?
建议补充的同步流程:
1. 获取微信好友标签列表
↓
2. 遍历每个标签名
├── 查询 tag_define 是否存在(按 companyId + tagType=1 + tagName)
│ ├── 不存在 → 自动创建 tag_define 记录
│ └── 存在 → 获取 tagDefineId
↓
3. 同步到 ck_traffic_pool_tag
├── 已存在 → 更新 updateTime
└── 不存在 → 新增记录,source=4(微信同步)
↓
4. 处理已删除的标签
└── 微信侧不存在但流量池存在 → 软删除(isDel=1)或保留历史
建议增加配置项:
-- 在 ck_traffic_pool_tag_define 增加
ALTER TABLE ck_traffic_pool_tag_define ADD COLUMN
syncFromWechat TINYINT(1) DEFAULT 0 COMMENT '是否来自微信同步:0=否,1=是';
2.3 🟡 行为表缺少分区/归档策略
问题描述:
ck_traffic_pool_behavior 使用 BIGINT 主键,预期数据量巨大,但缺少:
- 分区策略
- 归档策略
- 数据保留期限定义
建议:
按月分区
CREATE TABLE `ck_traffic_pool_behavior` (
-- 字段定义略...
PRIMARY KEY (`id`, `behaviorTime`),
-- 其他索引...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (behaviorTime) (
PARTITION p202601 VALUES LESS THAN (UNIX_TIMESTAMP('2026-02-01')),
PARTITION p202602 VALUES LESS THAN (UNIX_TIMESTAMP('2026-03-01')),
PARTITION p202603 VALUES LESS THAN (UNIX_TIMESTAMP('2026-04-01')),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
归档策略建议
| 数据年龄 | 处理方式 |
|---|---|
| 0-3个月 | 热数据,保留在主表 |
| 3-12个月 | 温数据,可迁移到归档表 |
| >12个月 | 冷数据,可压缩存储或删除 |
新增归档表
CREATE TABLE `ck_traffic_pool_behavior_archive` (
-- 字段与主表相同
-- 按年分区
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.4 🟡 统计字段并发更新风险
问题描述:
totalMsgCount、totalOrderCount 等统计字段在高并发场景下存在数据竞争问题。
错误示例:
// 可能导致数据丢失
$record = Model::find($id);
$record->totalMsgCount = $record->totalMsgCount + 1;
$record->save();
正确做法:
// 使用原子操作
Db::table('ck_traffic_pool_company')
->where('id', $id)
->inc('totalMsgCount', 1)
->update();
// 或使用 SQL
UPDATE ck_traffic_pool_company
SET totalMsgCount = totalMsgCount + 1
WHERE id = ?;
建议在文档中补充并发更新规范。
三、性能优化建议
3.1 增加必要索引
-- ck_traffic_pool_behavior: 按公司和时间查询
ALTER TABLE ck_traffic_pool_behavior
ADD INDEX idx_company_time (companyId, behaviorTime);
-- ck_traffic_pool_behavior: 按流量和行为类型查询
ALTER TABLE ck_traffic_pool_behavior
ADD INDEX idx_pool_behavior (poolCompanyId, behaviorType);
-- ck_traffic_pool_tag: 按公司和标签名快速查询
ALTER TABLE ck_traffic_pool_tag
ADD INDEX idx_company_tagname (companyId, tagName);
-- ck_traffic_pool_source: 按来源类型统计
ALTER TABLE ck_traffic_pool_source
ADD INDEX idx_company_sourcetype (companyId, sourceType);
-- ck_traffic_pool_company: 分配状态查询
ALTER TABLE ck_traffic_pool_company
ADD INDEX idx_company_allocate (companyId, allocateStatus, expireTime);
3.2 增加分组统计缓存表
问题:动态规则分组每次查询都需要全表扫描并计算规则,性能较差。
建议新增缓存表:
CREATE TABLE `ck_traffic_pool_group_stats` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`groupId` INT(11) UNSIGNED NOT NULL COMMENT '分组ID',
`companyId` INT(11) UNSIGNED NOT NULL COMMENT '公司ID',
`memberCount` INT(11) NOT NULL DEFAULT 0 COMMENT '成员数量',
`newCountToday` INT(11) NOT NULL DEFAULT 0 COMMENT '今日新增',
`newCountWeek` INT(11) NOT NULL DEFAULT 0 COMMENT '本周新增',
`newCountMonth` INT(11) NOT NULL DEFAULT 0 COMMENT '本月新增',
`calculateTime` INT(11) NOT NULL COMMENT '计算时间',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
`updateTime` INT(11) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_company` (`groupId`, `companyId`),
KEY `idx_companyId` (`companyId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量池分组统计缓存表';
更新策略:
| 场景 | 更新方式 |
|---|---|
| 列表页展示数量 | 读取缓存表 |
| 流量入池/状态变更 | 异步更新缓存 |
| 定时任务 | 每小时全量重算 |
3.3 大数据量分页优化
当流量池数据量达到百万级时,传统分页会很慢:
-- 慢查询
SELECT * FROM ck_traffic_pool_company
WHERE companyId = 1
LIMIT 1000000, 20;
建议使用游标分页:
-- 快速查询(基于上一页最后一条ID)
SELECT * FROM ck_traffic_pool_company
WHERE companyId = 1 AND id > 1000000
ORDER BY id ASC
LIMIT 20;
四、扩展性优化建议
4.1 增加流量来源的首次来源标记
问题:一个流量可能有多条来源记录,但对于归因分析,首次来源最重要。
建议:
-- 在 ck_traffic_pool_source 增加
ALTER TABLE ck_traffic_pool_source ADD COLUMN
isFirstSource TINYINT(1) DEFAULT 0 COMMENT '是否首次来源:0=否,1=是';
-- 增加索引
ALTER TABLE ck_traffic_pool_source
ADD INDEX idx_company_first (companyId, isFirstSource);
在 ck_traffic_pool_company 增加冗余字段:
ALTER TABLE ck_traffic_pool_company ADD COLUMN (
firstSourceType TINYINT(2) DEFAULT NULL COMMENT '首次来源类型',
firstSourceTime INT(11) DEFAULT NULL COMMENT '首次来源时间'
);
4.2 增加流量生命周期状态
问题:当前只有 status 字段,无法表达流量的生命周期阶段。
建议增加 lifecycle 字段:
ALTER TABLE ck_traffic_pool_company ADD COLUMN
lifecycle TINYINT(2) DEFAULT 1 COMMENT '生命周期:1=新流量,2=跟进中,3=已成交,4=沉默,5=流失,6=已回收';
生命周期转换规则:
新流量(1) ──分配──> 跟进中(2)
跟进中(2) ──成交──> 已成交(3)
跟进中(2) ──30天无互动──> 沉默(4)
沉默(4) ──90天无互动──> 流失(5)
流失(5) ──回收──> 已回收(6)
已回收(6) ──重新激活──> 跟进中(2)
4.3 支持多标识符关联
问题:当前一个流量只能有一个 identifier,但实际可能有多个标识符。
建议新增标识符关联表:
CREATE TABLE `ck_traffic_pool_identifier` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`poolId` INT(11) UNSIGNED NOT NULL COMMENT '流量池总表ID',
`identifierType` TINYINT(2) NOT NULL COMMENT '标识类型:1=微信ID,2=微信号,3=手机号,4=邮箱',
`identifierValue` VARCHAR(64) NOT NULL COMMENT '标识值',
`isPrimary` TINYINT(1) DEFAULT 0 COMMENT '是否主标识:0=否,1=是',
`verifyStatus` TINYINT(1) DEFAULT 0 COMMENT '验证状态:0=未验证,1=已验证',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
`updateTime` INT(11) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_type_value` (`identifierType`, `identifierValue`),
KEY `idx_poolId` (`poolId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量标识符关联表';
五、补充字段建议
5.1 ck_traffic_pool 总表
| 字段名 | 类型 | 说明 |
|---|---|---|
mergeStatus |
tinyint(1) | 合并状态:0=正常,1=已被合并 |
mergedToId |
int(11) | 被合并到的目标流量ID |
mergeTime |
int(11) | 合并时间 |
dataQuality |
tinyint(2) | 数据质量:1=低,2=中,3=高 |
5.2 ck_traffic_pool_company 公司子表
| 字段名 | 类型 | 说明 |
|---|---|---|
firstSourceType |
tinyint(2) | 首次来源类型 |
firstSourceTime |
int(11) | 首次来源时间 |
lastActiveTime |
int(11) | 最后活跃时间(综合消息/订单等) |
lifecycle |
tinyint(2) | 生命周期状态 |
followUpCount |
int(11) | 跟进次数 |
lastFollowUpTime |
int(11) | 最后跟进时间 |
nextFollowUpTime |
int(11) | 下次跟进时间 |
lostReason |
varchar(255) | 流失原因 |
5.3 ck_traffic_pool_group 分组表
| 字段名 | 类型 | 说明 |
|---|---|---|
lastCalculateTime |
int(11) | 上次规则计算时间 |
autoRefresh |
tinyint(1) | 是否自动刷新:0=否,1=是 |
refreshInterval |
int(11) | 刷新间隔(秒) |
5.4 ck_traffic_pool_source 来源表
| 字段名 | 类型 | 说明 |
|---|---|---|
isFirstSource |
tinyint(1) | 是否首次来源 |
conversionStatus |
tinyint(2) | 转化状态:0=未转化,1=已转化 |
conversionTime |
int(11) | 转化时间 |
六、补充表结构建议
6.1 流量合并记录表
CREATE TABLE `ck_traffic_pool_merge_record` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`targetPoolId` INT(11) UNSIGNED NOT NULL COMMENT '目标流量ID(保留的)',
`targetIdentifier` VARCHAR(64) NOT NULL COMMENT '目标标识',
`sourcePoolId` INT(11) UNSIGNED NOT NULL COMMENT '来源流量ID(被合并的)',
`sourceIdentifier` VARCHAR(64) NOT NULL COMMENT '来源标识',
`mergeReason` VARCHAR(255) DEFAULT NULL COMMENT '合并原因',
`mergeType` TINYINT(2) DEFAULT 1 COMMENT '合并类型:1=手动,2=自动识别',
`operatorId` INT(11) DEFAULT NULL COMMENT '操作人ID',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_targetPoolId` (`targetPoolId`),
KEY `idx_sourcePoolId` (`sourcePoolId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量合并记录表';
6.2 分组统计缓存表
CREATE TABLE `ck_traffic_pool_group_stats` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`groupId` INT(11) UNSIGNED NOT NULL COMMENT '分组ID',
`companyId` INT(11) UNSIGNED NOT NULL COMMENT '公司ID',
`memberCount` INT(11) NOT NULL DEFAULT 0 COMMENT '成员数量',
`newCountToday` INT(11) NOT NULL DEFAULT 0 COMMENT '今日新增',
`newCountWeek` INT(11) NOT NULL DEFAULT 0 COMMENT '本周新增',
`newCountMonth` INT(11) NOT NULL DEFAULT 0 COMMENT '本月新增',
`calculateTime` INT(11) NOT NULL COMMENT '计算时间',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
`updateTime` INT(11) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_company` (`groupId`, `companyId`),
KEY `idx_companyId` (`companyId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量池分组统计缓存表';
6.3 流量快照表(用于历史对比)
CREATE TABLE `ck_traffic_pool_company_snapshot` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`poolCompanyId` INT(11) UNSIGNED NOT NULL COMMENT '公司流量详情表ID',
`companyId` INT(11) UNSIGNED NOT NULL COMMENT '公司ID',
`snapshotDate` DATE NOT NULL COMMENT '快照日期',
`friendStatus` TINYINT(2) DEFAULT NULL COMMENT '好友状态',
`level` TINYINT(2) DEFAULT NULL COMMENT '客户等级',
`rfmR` INT(11) DEFAULT 0 COMMENT 'R值',
`rfmF` INT(11) DEFAULT 0 COMMENT 'F值',
`rfmM` DECIMAL(12,2) DEFAULT 0.00 COMMENT 'M值',
`rfmScore` INT(11) DEFAULT 0 COMMENT 'RFM评分',
`totalMsgCount` INT(11) DEFAULT 0 COMMENT '累计消息数',
`totalOrderCount` INT(11) DEFAULT 0 COMMENT '累计订单数',
`totalOrderAmount` DECIMAL(12,2) DEFAULT 0.00 COMMENT '累计订单金额',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_pool_date` (`poolCompanyId`, `snapshotDate`),
KEY `idx_company_date` (`companyId`, `snapshotDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量快照表';
6.4 流量标识符关联表
CREATE TABLE `ck_traffic_pool_identifier` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`poolId` INT(11) UNSIGNED NOT NULL COMMENT '流量池总表ID',
`identifierType` TINYINT(2) NOT NULL COMMENT '标识类型:1=微信ID,2=微信号,3=手机号,4=邮箱',
`identifierValue` VARCHAR(64) NOT NULL COMMENT '标识值',
`isPrimary` TINYINT(1) DEFAULT 0 COMMENT '是否主标识:0=否,1=是',
`verifyStatus` TINYINT(1) DEFAULT 0 COMMENT '验证状态:0=未验证,1=已验证',
`sourceType` TINYINT(2) DEFAULT NULL COMMENT '来源类型',
`createTime` INT(11) NOT NULL COMMENT '创建时间',
`updateTime` INT(11) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_type_value` (`identifierType`, `identifierValue`),
KEY `idx_poolId` (`poolId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流量标识符关联表';
七、业务流程补充建议
7.1 补充微信标签同步流程
┌─────────────────────────────────────────────────────────────────────┐
│ 微信标签同步流程 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 1. 从 s2_wechat_friend 获取好友标签列表(labels字段) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. 解析标签字符串,遍历每个标签名 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. 查询 ck_traffic_pool_tag_define │
│ WHERE companyId=? AND tagType=1 AND tagName=? │
│ ├── 存在 → 获取 tagDefineId │
│ └── 不存在 → 自动创建 tagDefine 记录 │
│ - tagCode = 'wechat_' + md5(tagName) │
│ - categoryId = 微信默认标签类目ID │
│ - syncFromWechat = 1 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. 同步到 ck_traffic_pool_tag │
│ ├── 已存在(poolCompanyId + tagDefineId)→ 更新 updateTime │
│ └── 不存在 → 新增记录 │
│ - source = 4(微信同步) │
│ - tagType = 1 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. 处理已删除的标签(可选) │
│ - 查询流量池中存在但微信侧不存在的标签 │
│ - 策略A:软删除(isDel=1) │
│ - 策略B:保留历史记录,增加 syncStatus 字段标记 │
└─────────────────────────────────────────────────────────────────────┘
7.2 补充流量合并流程
┌─────────────────────────────────────────────────────────────────────┐
│ 流量合并流程 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 1. 识别重复流量 │
│ - 手动:操作人员指定 │
│ - 自动:匹配手机号/微信号等 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. 选择目标流量(保留哪条) │
│ 优先级:微信ID > 微信号 > 手机号 │
│ 或:数据更完整的 > 数据较少的 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. 开启事务,执行合并 │
└─────────────────────────────────────────────────────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ 3.1 更新总表 │ │ 3.2 合并公司子表数据 │
│ - 被合并流量: │ │ - 来源记录:迁移 │
│ mergeStatus = 1 │ │ - 标签记录:去重合并 │
│ mergedToId = 目标ID │ │ - 行为记录:迁移 │
│ mergeTime = 当前时间 │ │ - 分配记录:迁移 │
└──────────────────────────┘ └──────────────────────────┘
│ │
└───────────┬───────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. 合并统计数据 │
│ - totalMsgCount = SUM(两条记录) │
│ - totalOrderCount = SUM(两条记录) │
│ - totalOrderAmount = SUM(两条记录) │
│ - firstSourceTime = MIN(两条记录) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. 记录合并日志 │
│ INSERT INTO ck_traffic_pool_merge_record │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 6. 提交事务 │
└─────────────────────────────────────────────────────────────────────┘
7.3 补充软删除级联逻辑
当 ck_traffic_pool_company 记录被软删除时:
| 关联表 | 处理方式 | 说明 |
|---|---|---|
ck_traffic_pool_source |
同步软删除 | 历史来源失去意义 |
ck_traffic_pool_tag |
同步软删除 | 标签关联失效 |
ck_traffic_pool_behavior |
不删除 | 保留历史行为用于分析 |
ck_traffic_pool_allot_record |
不删除 | 保留分配历史 |
ck_traffic_pool_group_member |
同步软删除 | 移出手动分组 |
八、总结
问题优先级分类
| 优先级 | 类型 | 数量 | 建议 |
|---|---|---|---|
| 🔴 P0 | 逻辑问题 | 3 | 必须在开发前修复 |
| 🟡 P1 | 不合理之处 | 4 | 建议开发中修复 |
| 🟢 P2 | 优化建议 | 若干 | 可在迭代中逐步完善 |
必须修复清单
- 分组规则逻辑运算符重构 - 改用嵌套JSON结构
- RFM R值存储方式调整 - 改为存储时间戳
- 增加流量合并机制 - 新增合并字段和记录表
建议修复清单
- 删除重复唯一索引
- 补充微信标签同步流程文档
- 增加行为表分区策略
- 补充统计字段并发更新规范
建议新增表
ck_traffic_pool_merge_record- 合并记录表ck_traffic_pool_group_stats- 分组统计缓存表ck_traffic_pool_company_snapshot- 流量快照表ck_traffic_pool_identifier- 标识符关联表(可选)
确认以上评审内容后,可开始修订设计文档。