Files
CKB-Interface/docs/traffic_pool_design_review.md
2026-03-24 10:39:16 +08:00

32 KiB
Raw Blame History

流量池系统设计文档 - 评审与优化建议

评审版本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');

问题

  1. 平铺结构无法表达括号分组:A AND (B OR C) 这种逻辑无法实现
  2. 逻辑运算符优先级不明确:上述规则会被解析为 A AND B OR C AND ?
  3. 最后一条规则的 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 '组间逻辑关系'
);

修改后的数据示例:

-- 高价值客户池规则
-- 组0friendStatus = 2
-- 组1rfmM >= 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 字段定义为"最近一次互动距今天数",但这是一个动态值,会随时间自动增长。

问题

  1. 存储的值会"自动过期":今天存的 rfmR=0,明天实际应该是 rfmR=1
  2. 需要定时任务每天更新全表数据,成本极高
  3. 查询时数据可能不准确

解决方案

方案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
后续确认是同一人 如何合并?

当前设计缺陷

  1. 缺少流量合并机制
  2. 无法记录合并历史
  3. 合并后历史数据如何处理不明确

解决方案

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)

由于 poolIdidentifierck_traffic_pool 表中是一一对应关系,这两个索引实际等价。

建议

保留 uk_identifier_company,删除 uk_pool_company

ALTER TABLE ck_traffic_pool_company DROP INDEX uk_pool_company;

理由:

  • identifier 是业务标识,查询更常用
  • 保留 poolId 字段但不建唯一索引,仍可用于关联查询

2.2 🟡 微信标签同步逻辑不清晰

问题描述

文档未说明微信标签同步的详细逻辑:

  1. 如何匹配已存在的标签定义?
  2. 新标签如何自动创建 tag_define 记录?
  3. 微信侧删除标签后,流量池如何处理?
  4. 标签名称变更如何同步?

建议补充的同步流程

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 主键,预期数据量巨大,但缺少:

  1. 分区策略
  2. 归档策略
  3. 数据保留期限定义

建议

按月分区

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 🟡 统计字段并发更新风险

问题描述

totalMsgCounttotalOrderCount 等统计字段在高并发场景下存在数据竞争问题。

错误示例

// 可能导致数据丢失
$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=微信ID2=微信号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=微信ID2=微信号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 优化建议 若干 可在迭代中逐步完善

必须修复清单

  1. 分组规则逻辑运算符重构 - 改用嵌套JSON结构
  2. RFM R值存储方式调整 - 改为存储时间戳
  3. 增加流量合并机制 - 新增合并字段和记录表

建议修复清单

  1. 删除重复唯一索引
  2. 补充微信标签同步流程文档
  3. 增加行为表分区策略
  4. 补充统计字段并发更新规范

建议新增表

  1. ck_traffic_pool_merge_record - 合并记录表
  2. ck_traffic_pool_group_stats - 分组统计缓存表
  3. ck_traffic_pool_company_snapshot - 流量快照表
  4. ck_traffic_pool_identifier - 标识符关联表(可选)

确认以上评审内容后,可开始修订设计文档。