diff --git a/docs/cdp-callcenter-financial-implementation.md b/docs/cdp-callcenter-financial-implementation.md new file mode 100644 index 000000000..79b8f403d --- /dev/null +++ b/docs/cdp-callcenter-financial-implementation.md @@ -0,0 +1,603 @@ +# 呼叫中心+金融行业CDP实施方案 + +## 目录 +- [一、业务场景分析](#一业务场景分析) +- [二、数据源对接方案](#二数据源对接方案) +- [三、实施路线图](#三实施路线图) +- [四、Quick Start方案](#四quick-start方案) + +--- + +## 一、业务场景分析 + +### 1.1 典型业务流程 + +```mermaid +graph LR + A[广告投放] --> B[线索进入] + B --> C[呼叫中心外呼] + C --> D{是否接通?} + D -->|是| E[意向判断] + D -->|否| F[标记未接通] + E --> G{意向度?} + G -->|高意向| H[转销售跟进] + G -->|中低意向| I[培育池] + F --> J[择机再呼] + H --> K[企业微信添加] + K --> L[持续互动] + L --> M[商机转化] +``` + +### 1.2 核心痛点 + +| 痛点 | 说明 | CDP解决方案 | +|-----|------|-----------| +| **线索重复** | 同一客户从多个渠道进来 | OneID去重 | +| **信息孤岛** | 呼叫中心和企微数据不通 | 统一客户视图 | +| **外呼盲目** | 不知道客户最佳接听时段 | 通话行为分析标签 | +| **跟进混乱** | 不知道客户企业的组织架构 | 组织关系图谱 | +| **价值不明** | 不知道哪些客户价值高 | 客户价值评分标签 | + +--- + +## 二、数据源对接方案 + +### 2.1 呼叫中心系统对接 + +#### 2.1.1 常见呼叫中心系统 + +| 系统名称 | 对接方式 | 数据获取 | +|---------|---------|---------| +| 云呼叫中心(阿里云/腾讯云) | API对接 | 实时webhook + 定时拉取 | +| Avaya | 数据库同步 | 读取MySQL/Oracle | +| Genesys | API对接 | REST API | +| 自建系统 | 数据库同步或API | 需定制开发 | + +#### 2.1.2 呼叫中心数据采集架构 + +```mermaid +graph LR + A[呼叫中心系统] -->|Webhook实时推送| B[CDP数据采集网关] + A -->|定时拉取API| B + A -->|数据库同步| C[DataX/Kettle] + C --> B + B --> D[Kafka] + D --> E[Flink实时处理] + E --> F[ODS原始表] + F --> G[DWD标准表] + G --> H[标签计算] +``` + +#### 2.1.3 对接数据清单 + +**必须采集的数据**: +- ✅ 通话记录(call_record) +- ✅ 客户信息(customer) +- ✅ 坐席信息(agent) +- ✅ 通话录音URL(可选) + +**数据采集频率**: +- 🔄 实时推送:通话结束后立即推送 +- 🔄 定时同步:每小时增量同步一次 +- 🔄 全量同步:每天凌晨全量同步一次(补数) + +### 2.2 企业微信对接 + +#### 2.2.1 需要的API权限 + +| API类别 | 具体接口 | 用途 | +|--------|---------|------| +| 通讯录管理 | 获取部门列表、成员列表 | 同步销售团队信息 | +| 客户联系 | 获取客户列表、客户详情 | 同步外部联系人 | +| 客户联系 | 获取客户群列表 | 同步客户群信息 | +| 会话内容存档 | 获取会话内容(需单独申请) | 采集聊天记录 | +| 客户朋友圈 | 获取客户朋友圈互动 | 采集互动行为 | + +#### 2.2.2 企业微信数据采集流程 + +```sql +-- Step 1: 采集外部联系人 +-- API: GET https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list +-- 写入 ods_wework_external_contact + +-- Step 2: OneID匹配 +-- 根据手机号/unionid匹配或创建CDP ID + +-- Step 3: 绑定到企业 +-- 根据企业名称匹配或创建account_id + +-- Step 4: 采集聊天记录 +-- API: 会话内容存档接口 +-- 写入 ods_wework_chat_event + +-- Step 5: 转换为标准事件 +-- 从ods层转换到dwd_contact_event +``` + +### 2.3 广告平台对接 + +#### 2.3.1 广告平台API对接 + +| 平台 | API文档 | 主要数据 | +|-----|---------|---------| +| 腾讯广告 | marketing.qq.com | 投放数据、线索数据 | +| 百度推广 | dev.baidu.com | 关键词数据、转化数据 | +| 巨量引擎(字节) | open.oceanengine.com | 创意数据、落地页数据 | + +#### 2.3.2 广告线索处理流程 + +```mermaid +graph LR + A[广告平台] -->|线索提交| B[CDP接收] + B --> C{查询OneID} + C -->|已存在| D[更新联系人信息] + C -->|不存在| E[创建新联系人] + D --> F[打标签:广告来源] + E --> F + F --> G[推送到呼叫中心] + G --> H[生成外呼任务] +``` + +--- + +## 三、实施路线图 + +### 3.1 Phase 1: 基础MVP (2-3周) + +**目标**:快速上线,打通呼叫中心→企微的数据流 + +#### Week 1-2: 数据采集 + +```yaml +任务: + - 对接呼叫中心API,采集通话记录 + - 对接企业微信API,采集外部联系人 + - 建立ODS原始表 + - 实现定时同步任务 + +交付物: + - ods_callcenter_call_record (通话记录表) + - ods_wework_external_contact (企微联系人表) + - 数据同步脚本 + +验收标准: + - 每天能采集到前一天的通话记录 + - 每小时能同步企微联系人变更 +``` + +#### Week 3: OneID + 标准化 + +```yaml +任务: + - 实现OneID匹配逻辑(基于手机号) + - 将ODS数据转换为DWD标准模型 + - 建立联系人主表和行为事件表 + +交付物: + - dwd_contact (联系人主表) + - dwd_contact_event (行为事件表) + - dwd_id_mapping (ID映射表) + - ETL数据转换脚本 + +验收标准: + - 能将呼叫中心和企微的同一个人识别出来 + - 能看到联系人的通话记录和企微聊天记录 +``` + +### 3.2 Phase 2: 标签体系 (2-3周) + +#### Week 4: 基础标签 + +```yaml +实现标签: + 联系人标签: + - 高接通率 (近30次外呼接通率>70%) + - 通话时长长 (平均通话>5分钟) + - 高意向客户 (意向度=高) + - 近7天活跃 (近7天有互动) + - 已添加企微 (企微状态=已添加) + + 企业标签: + - 金融行业 + - 高价值客户 (预估年度价值>10万) + - 商机阶段 (线索/商机/成交) + +交付物: + - dwd_tag_config (标签配置表) + - dwd_tag_result (标签结果表) + - 标签计算脚本(SQL/Python) +``` + +#### Week 5-6: 标签管理平台 + +```yaml +功能: + - 标签列表查看 + - 标签详情(覆盖人数、最近更新时间) + - 手动刷新标签 + - 查看某个联系人的所有标签 + +技术实现: + - 后端: Spring Boot + - 前端: React + Ant Design + - 数据库: MySQL +``` + +### 3.3 Phase 3: 圈人能力 (2周) + +#### Week 7-8: 圈人功能 + +```yaml +实现场景: + 场景1: 基础圈人 + - 按标签圈人 (勾选标签即可) + - 按属性圈人 (职位、行业等) + - 圈人结果预览 + - 导出Excel + + 场景2: 高级圈人 + - 企业维度过滤 (先选企业,再选人) + - 多条件组合 (AND/OR逻辑) + - 圈人结果推送到呼叫中心 + +交付物: + - 圈人规则引擎 + - 圈人结果管理 + - 导出功能 + - 推送功能 +``` + +### 3.4 Phase 4: 统一视图 (2周) + +#### Week 9-10: 客户360视图 + +```yaml +功能模块: + - 企业基本信息卡片 + - 企业标签展示 + - 关键联系人列表 + - 联系人标签展示 + - 近期互动时间轴 + - 组织架构图(简版) + +页面结构: + /customer/360/:accountId + ├─ 企业信息区 + ├─ 联系人列表区 + ├─ 互动记录区 + └─ 商机信息区 +``` + +--- + +## 四、Quick Start方案 + +### 4.1 30分钟快速演示方案 + +如果你需要快速验证可行性,可以用这个最小化方案: + +#### Step 1: 准备测试数据 (5分钟) + +```sql +-- 创建简化的测试表 +CREATE TABLE test_contact ( + cdp_id VARCHAR(64) PRIMARY KEY, + name VARCHAR(128), + mobile VARCHAR(32), + company VARCHAR(256), + job_title VARCHAR(128), + source VARCHAR(32) +); + +-- 插入测试数据 +INSERT INTO test_contact VALUES +('CDP_001', '张三', '13800138001', 'XX金融公司', 'CFO', 'CALLCENTER'), +('CDP_001', '张三', '13800138001', 'XX金融公司', 'CFO', 'WEWORK'), -- 同一个人 +('CDP_002', '李四', '13800138002', 'XX金融公司', '财务经理', 'CALLCENTER'); + +-- OneID去重查询 +SELECT + mobile, + name, + company, + GROUP_CONCAT(source) AS sources, + COUNT(DISTINCT source) AS source_count +FROM test_contact +GROUP BY mobile, name, company +HAVING COUNT(DISTINCT source) > 1; -- 找到多源数据的同一个人 +``` + +#### Step 2: 模拟标签计算 (10分钟) + +```sql +-- 创建标签表 +CREATE TABLE test_tag ( + cdp_id VARCHAR(64), + tag_name VARCHAR(128), + tag_value VARCHAR(128), + PRIMARY KEY (cdp_id, tag_name) +); + +-- 模拟打标签 +INSERT INTO test_tag VALUES +('CDP_001', '高接通率', 'true'), +('CDP_001', '高意向', 'true'), +('CDP_001', 'CXO级别', 'true'), +('CDP_002', '中意向', 'true'); + +-- 圈人查询: 找到"高接通率"且"高意向"的CXO +SELECT + c.cdp_id, + c.name, + c.mobile, + c.company, + c.job_title, + GROUP_CONCAT(t.tag_name) AS tags +FROM test_contact c +INNER JOIN test_tag t ON c.cdp_id = t.cdp_id +WHERE t.tag_name IN ('高接通率', '高意向', 'CXO级别') +GROUP BY c.cdp_id +HAVING COUNT(DISTINCT t.tag_name) = 3; -- 3个标签都满足 +``` + +#### Step 3: 模拟360视图 (15分钟) + +```sql +-- 创建互动记录表 +CREATE TABLE test_event ( + event_id VARCHAR(64) PRIMARY KEY, + cdp_id VARCHAR(64), + event_type VARCHAR(32), + event_time DATETIME, + event_desc VARCHAR(256) +); + +-- 插入测试数据 +INSERT INTO test_event VALUES +('E001', 'CDP_001', 'call', '2024-10-29 10:30:00', '外呼接通,通话15分钟'), +('E002', 'CDP_001', 'wework_chat', '2024-10-29 14:20:00', '企微咨询产品价格'), +('E003', 'CDP_001', 'call', '2024-10-28 16:00:00', '外呼接通,预约下周拜访'); + +-- 查询360视图 +SELECT + -- 联系人信息 + c.cdp_id, + c.name, + c.mobile, + c.company, + c.job_title, + + -- 标签 + (SELECT GROUP_CONCAT(tag_name) FROM test_tag WHERE cdp_id = c.cdp_id) AS tags, + + -- 近期互动 + (SELECT COUNT(*) FROM test_event WHERE cdp_id = c.cdp_id + AND event_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)) AS interaction_l7d, + + -- 最近互动时间 + (SELECT MAX(event_time) FROM test_event WHERE cdp_id = c.cdp_id) AS last_interaction +FROM test_contact c +WHERE c.cdp_id = 'CDP_001' +LIMIT 1; +``` + +### 4.2 演示效果 + +运行上面的SQL后,你会得到: + +``` +CDP_001的360视图: +├─ 基本信息: 张三 | CFO | XX金融公司 | 138****8001 +├─ 数据来源: 呼叫中心、企业微信 (已打通) +├─ 标签: 高接通率、高意向、CXO级别 +├─ 近7天互动: 3次 +├─ 最近互动: 2024-10-29 14:20:00 (企微咨询) +└─ 互动明细: + • 2024-10-29 10:30 外呼接通,通话15分钟 + • 2024-10-29 14:20 企微咨询产品价格 + • 2024-10-28 16:00 外呼接通,预约下周拜访 +``` + +--- + +## 五、关键技术决策 + +### 5.1 OneID匹配优先级(金融+呼叫中心场景) + +```python +# OneID匹配优先级 +MATCH_RULES = [ + { + 'priority': 1, + 'field': 'mobile', + 'weight': 1.0, + 'description': '手机号精确匹配(最高优先级)' + }, + { + 'priority': 2, + 'field': 'email', + 'weight': 0.9, + 'description': '邮箱精确匹配' + }, + { + 'priority': 3, + 'field': 'wework_unionid', + 'weight': 0.95, + 'description': '企微unionid匹配' + }, + { + 'priority': 4, + 'field': 'name_company', + 'weight': 0.7, + 'description': '姓名+企业名称模糊匹配' + } +] + +# 匹配逻辑 +def match_or_create_cdp_id(contact_data): + # 1. 先用手机号查询 + if contact_data.get('mobile'): + cdp_id = query_by_mobile(contact_data['mobile']) + if cdp_id: + return cdp_id, 'MOBILE', 1.0 + + # 2. 再用邮箱查询 + if contact_data.get('email'): + cdp_id = query_by_email(contact_data['email']) + if cdp_id: + return cdp_id, 'EMAIL', 0.9 + + # 3. 再用unionid查询 + if contact_data.get('unionid'): + cdp_id = query_by_unionid(contact_data['unionid']) + if cdp_id: + return cdp_id, 'UNIONID', 0.95 + + # 4. 都没匹配到,创建新CDP ID + new_cdp_id = generate_cdp_id() + return new_cdp_id, 'NEW', 1.0 +``` + +### 5.2 数据同步频率建议 + +| 数据类型 | 实时性要求 | 同步频率 | 同步方式 | +|---------|----------|---------|---------| +| 通话记录 | 高 | 准实时(5分钟) | Webhook推送 + 补偿拉取 | +| 企微聊天 | 高 | 准实时(10分钟) | 订阅事件 + 定时拉取 | +| 外部联系人 | 中 | 每小时 | 增量同步 | +| 广告线索 | 高 | 准实时(5分钟) | API拉取 | +| 标签计算 | 低 | 每天凌晨 | 定时任务 | + +### 5.3 性能优化建议 + +#### 5.3.1 数据库设计 + +```sql +-- 重要索引 +ALTER TABLE dwd_contact +ADD INDEX idx_mobile_hash (mobile_hash), +ADD INDEX idx_account_id (account_id), +ADD INDEX idx_update_time (update_time); + +ALTER TABLE dwd_contact_event +ADD INDEX idx_cdp_date (cdp_id, event_date), +ADD INDEX idx_event_type_date (event_type, event_date); + +-- 分区表(事件表按月分区) +ALTER TABLE dwd_contact_event +PARTITION BY RANGE (TO_DAYS(event_date)) ( + PARTITION p_202410 VALUES LESS THAN (TO_DAYS('2024-11-01')), + PARTITION p_202411 VALUES LESS THAN (TO_DAYS('2024-12-01')), + PARTITION p_202412 VALUES LESS THAN (TO_DAYS('2025-01-01')), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +#### 5.3.2 Redis缓存策略 + +```python +# 缓存联系人基本信息(TTL 1小时) +CACHE_KEY_CONTACT = "cdp:contact:{cdp_id}" +CACHE_TTL_CONTACT = 3600 + +# 缓存联系人标签(TTL 10分钟) +CACHE_KEY_TAGS = "cdp:tags:{cdp_id}" +CACHE_TTL_TAGS = 600 + +# 缓存客户360视图(TTL 5分钟) +CACHE_KEY_360 = "cdp:360:{account_id}" +CACHE_TTL_360 = 300 + +# 查询逻辑 +def get_contact_info(cdp_id): + # 1. 先查Redis + cache_key = f"cdp:contact:{cdp_id}" + cached_data = redis.get(cache_key) + if cached_data: + return json.loads(cached_data) + + # 2. 查数据库 + contact = db.query("SELECT * FROM dwd_contact WHERE cdp_id = %s", cdp_id) + + # 3. 写入Redis + redis.setex(cache_key, CACHE_TTL_CONTACT, json.dumps(contact)) + + return contact +``` + +--- + +## 六、常见问题FAQ + +### Q1: 呼叫中心的通话记录没有企业名称,如何关联到企业? + +**A**: 分步骤处理: + +```sql +-- Step 1: 先根据手机号找到联系人 +SELECT cdp_id, account_id +FROM dwd_contact +WHERE mobile_hash = SHA256('13800138001'); + +-- Step 2: 如果没找到,尝试根据客户名称模糊匹配 +SELECT account_id +FROM dwd_customer_account +WHERE account_name LIKE '%客户名称%'; + +-- Step 3: 实在匹配不到,先创建"未分配"企业,后续人工分配 +INSERT INTO dwd_customer_account (account_id, account_name, customer_type) +VALUES (generate_account_id(), '待确认-' + customer_name, 'LEAD'); +``` + +### Q2: 一个手机号对应多个人怎么办?(例如公司前台电话) + +**A**: 这是数据质量问题,需要特殊处理: + +1. **检测**: 如果一个手机号对应多个不同姓名,标记为"共享号码" +2. **拆分**: 引入"座机"字段,区分手机号和座机 +3. **优先级**: OneID匹配时,手机号+姓名一起匹配 + +```sql +-- 检测共享号码 +SELECT mobile_hash, COUNT(DISTINCT contact_name) AS name_count +FROM dwd_contact +GROUP BY mobile_hash +HAVING COUNT(DISTINCT contact_name) > 1; + +-- 标记为共享号码 +UPDATE dwd_contact +SET extra_attributes = JSON_SET(extra_attributes, '$.is_shared_mobile', true) +WHERE mobile_hash IN (共享号码列表); +``` + +### Q3: 企业微信和呼叫中心的联系人信息不一致怎么办? + +**A**: 数据冲突处理策略: + +| 字段 | 冲突处理策略 | +|-----|------------| +| 姓名 | 以最近更新的为准 | +| 职位 | 以企微为准(更新更及时) | +| 手机号 | 以呼叫中心为准(更准确) | +| 企业名称 | 人工审核后合并 | + +```sql +-- 数据合并逻辑(以最近更新为准) +UPDATE dwd_contact c1 +INNER JOIN ( + SELECT cdp_id, MAX(update_time) AS latest_time + FROM dwd_id_mapping + GROUP BY cdp_id +) latest ON c1.cdp_id = latest.cdp_id +SET c1.contact_name = ( + SELECT contact_name FROM dwd_id_mapping + WHERE cdp_id = c1.cdp_id + ORDER BY update_time DESC LIMIT 1 +); +``` + +--- + +**文档版本**: v1.0 +**最后更新**: 2024-10-30 +**适用场景**: 呼叫中心+金融行业CDP实施 diff --git a/docs/cdp-tagging-and-audience-guide.md b/docs/cdp-tagging-and-audience-guide.md new file mode 100644 index 000000000..bec01b45c --- /dev/null +++ b/docs/cdp-tagging-and-audience-guide.md @@ -0,0 +1,756 @@ +# CDP打标签与圈人实战指南 + +## 目录 +- [一、标签体系设计](#一标签体系设计) +- [二、圈人场景与策略](#二圈人场景与策略) +- [三、统一视图设计](#三统一视图设计) +- [四、呼叫中心场景适配](#四呼叫中心场景适配) +- [五、金融行业扩展](#五金融行业扩展) + +--- + +## 一、标签体系设计 + +### 1.1 标签体系的双层模型 + +在B2B场景下,标签体系必须是**双层结构**: + +``` +标签体系 +├─ 企业标签(Account Tag) +│ ├─ 作用对象:客户企业 +│ ├─ 存储位置:tag_result表(target_type=ACCOUNT) +│ └─ 使用场景:企业筛选、行业分析、客户分层 +│ +└─ 联系人标签(Contact Tag) + ├─ 作用对象:联系人(决策人、影响者等) + ├─ 存储位置:tag_result表(target_type=CONTACT) + └─ 使用场景:精准触达、组织穿透、个性化沟通 +``` + +### 1.2 标签结果表设计(统一存储) + +```sql +CREATE TABLE dwd_tag_result ( + -- 主键 + result_id VARCHAR(64) PRIMARY KEY, + + -- 目标主体(核心字段) + target_type VARCHAR(32) NOT NULL COMMENT '目标类型: ACCOUNT(企业)/CONTACT(联系人)', + target_id VARCHAR(64) NOT NULL COMMENT '目标ID: account_id或cdp_id', + + -- 标签信息 + tag_id VARCHAR(64) NOT NULL COMMENT '标签ID', + tag_name VARCHAR(128) NOT NULL COMMENT '标签名称', + tag_category VARCHAR(64) COMMENT '标签分类', + + -- 标签值 + tag_value_type VARCHAR(32) COMMENT '值类型: BOOLEAN/STRING/NUMBER', + tag_value TEXT COMMENT '标签值', + + -- 标签元数据 + tag_source VARCHAR(32) COMMENT '标签来源: RULE(规则)/MANUAL(人工)/ML(模型)', + confidence DECIMAL(5,2) DEFAULT 1.00 COMMENT '置信度(0-1)', + + -- 有效期 + start_time DATETIME COMMENT '生效时间', + end_time DATETIME COMMENT '失效时间(NULL表示永久有效)', + is_valid TINYINT DEFAULT 1 COMMENT '是否有效', + + -- 审计 + created_by VARCHAR(64) COMMENT '创建人', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_target_tag (target_type, target_id, tag_id), + INDEX idx_target (target_type, target_id), + INDEX idx_tag (tag_id), + INDEX idx_category (tag_category) +) COMMENT='标签结果统一存储表'; +``` + +### 1.3 金融行业标签体系示例 + +#### 1.3.1 企业标签(ACCOUNT) + +| 标签类别 | 标签示例 | 业务价值 | +|---------|---------|---------| +| **基础属性** | 金融科技/传统银行/保险公司/证券公司 | 行业细分 | +| **规模特征** | 注册资本1亿+/员工500+ | 客户分层 | +| **业务阶段** | 潜在客户/试用客户/付费客户/流失客户 | 生命周期管理 | +| **意向度** | 高意向/中意向/低意向/无意向 | 销售优先级 | +| **产品偏好** | 关注合规产品/关注风控产品/关注贷款产品 | 精准推荐 | +| **活跃度** | 7天活跃/30天沉默/90天流失 | 客户激活 | +| **风险评估** | 低风险/中风险/高风险 | 金融合规 | +| **价值评估** | S级客户/A级客户/B级客户 | 资源分配 | + +#### 1.3.2 联系人标签(CONTACT) + +| 标签类别 | 标签示例 | 业务价值 | +|---------|---------|---------| +| **决策角色** | 决策者/影响者/使用者/把关者 | 组织穿透 | +| **职级标签** | CXO/VP/总监/经理/员工 | 触达优先级 | +| **部门标签** | 财务部/IT部/风控部/业务部 | 精准营销 | +| **活跃度** | 高频互动/正常互动/低频互动/沉默用户 | 客户关怀 | +| **兴趣偏好** | 关注产品功能/关注价格/关注案例/关注服务 | 个性化沟通 | +| **渠道偏好** | 企微活跃/电话活跃/邮件活跃 | 渠道选择 | +| **通话特征** | 通话时长长/接通率高/回拨率高 | 呼叫中心专用 | +| **关系强度** | 强关系/弱关系/未建联 | 关系维护 | + +### 1.4 标签打标流程 + +```mermaid +graph LR + A[数据输入] --> B{判断主体类型} + B -->|企业维度数据| C[计算企业标签] + B -->|联系人维度数据| D[计算联系人标签] + + C --> E[写入标签结果表
target_type=ACCOUNT] + D --> F[写入标签结果表
target_type=CONTACT] + + E --> G[更新Redis缓存] + F --> G + + G --> H[应用层查询] +``` + +**核心原则:数据属于谁,标签就打给谁** + +--- + +## 二、圈人场景与策略 + +### 2.1 圈人的本质是"圈联系人" + +在B2B场景下,**最终要触达的是"人"**,所以: + +> **圈人 = 圈选符合条件的联系人(cdp_id列表)** + +但是,你可以用**企业维度作为过滤条件**。 + +### 2.2 圈人条件的组合模式 + +#### 模式1:纯联系人维度圈人 + +**场景**:找到所有金融行业的CFO,推送新产品 + +```json +{ + "target_type": "CONTACT", + "conditions": { + "and": [ + { + "field": "job_title", + "operator": "CONTAINS", + "value": "CFO" + }, + { + "field": "job_level", + "operator": "IN", + "value": ["CXO", "VP"] + }, + { + "tag": "近30天活跃", + "value": true + } + ] + } +} +``` + +**SQL实现**: + +```sql +SELECT DISTINCT c.cdp_id, c.contact_name, c.job_title, c.account_id +FROM dwd_contact c +WHERE c.job_title LIKE '%CFO%' + AND c.job_level IN ('CXO', 'VP') + AND EXISTS ( + SELECT 1 FROM dwd_tag_result t + WHERE t.target_type = 'CONTACT' + AND t.target_id = c.cdp_id + AND t.tag_name = '近30天活跃' + AND t.is_valid = 1 + ); +``` + +#### 模式2:企业维度过滤 + 联系人筛选 + +**场景**:找到所有"高意向"金融企业中的"决策者"联系人 + +```json +{ + "target_type": "CONTACT", + "conditions": { + "and": [ + { + "account_filter": { + "industry": "金融", + "account_tag": "高意向客户" + } + }, + { + "contact_filter": { + "job_level": ["CXO", "VP", "DIRECTOR"], + "contact_tag": "决策者" + } + } + ] + } +} +``` + +**SQL实现**: + +```sql +-- Step 1: 先圈出符合条件的企业 +WITH target_accounts AS ( + SELECT DISTINCT a.account_id + FROM dwd_customer_account a + WHERE a.industry = '金融' + AND EXISTS ( + SELECT 1 FROM dwd_tag_result t + WHERE t.target_type = 'ACCOUNT' + AND t.target_id = a.account_id + AND t.tag_name = '高意向客户' + AND t.is_valid = 1 + ) +) +-- Step 2: 再从这些企业中找符合条件的联系人 +SELECT DISTINCT c.cdp_id, c.contact_name, c.job_title, c.account_id +FROM dwd_contact c +INNER JOIN target_accounts ta ON c.account_id = ta.account_id +WHERE c.job_level IN ('CXO', 'VP', 'DIRECTOR') + AND EXISTS ( + SELECT 1 FROM dwd_tag_result t + WHERE t.target_type = 'CONTACT' + AND t.target_id = c.cdp_id + AND t.tag_name = '决策者' + AND t.is_valid = 1 + ); +``` + +#### 模式3:组织关系圈人(企业级CDP的杀手锏) + +**场景**:某金融企业已经触达了财务经理,现在要找到他的上级(CFO) + +```json +{ + "target_type": "CONTACT", + "conditions": { + "account_id": "ACCT_000001", + "org_relation": { + "base_contact": "CDP_123456", + "relation_type": "MANAGER", + "relation_direction": "UP", + "max_level": 2 + } + } +} +``` + +**Neo4j查询**: + +```cypher +// 向上查询2级上级 +MATCH (c:Contact {cdp_id: 'CDP_123456'})-[:REPORT_TO*1..2]->(manager:Contact) +WHERE manager.account_id = 'ACCT_000001' +RETURN manager.cdp_id, manager.name, manager.job_title +``` + +### 2.3 圈人结果的应用 + +圈人的最终输出是**联系人列表**,可以: + +1. **导出Excel**:给销售团队线下跟进 +2. **推送企业微信**:批量发送消息 +3. **呼叫中心外呼**:生成外呼任务列表 +4. **广告投放**:上传到广告平台做Lookalike +5. **自动化流程**:触发自动化营销动作 + +--- + +## 三、统一视图设计 + +### 3.1 问题的本质 + +你担心"主体有多个不好做",核心原因是: + +> **存储层是分离的(企业表 + 联系人表),但应用层需要统一视图** + +### 3.2 解决方案:360度客户视图 + +在应用层(前端/API)提供**统一的360度视图**,把企业和联系人整合展示。 + +#### 3.2.1 客户360视图API设计 + +```json +// API: GET /api/v1/customer/360/{account_id} + +{ + "account_info": { + "account_id": "ACCT_000001", + "account_name": "XX金融科技公司", + "industry": "金融科技", + "customer_type": "OPPORTUNITY", + "customer_level": "A", + "tags": [ + {"tag_name": "高意向客户", "tag_value": true}, + {"tag_name": "B轮融资", "tag_value": true}, + {"tag_name": "近30天活跃", "tag_value": true} + ], + "metrics": { + "total_contacts": 5, + "decision_maker_count": 2, + "interaction_count_l30d": 28, + "last_contact_date": "2024-10-29" + } + }, + "contacts": [ + { + "cdp_id": "CDP_000001", + "contact_name": "张三", + "job_title": "CFO", + "job_level": "CXO", + "decision_role": "DECISION_MAKER", + "mobile": "138****1234", + "tags": [ + {"tag_name": "决策者", "tag_value": true}, + {"tag_name": "高频互动", "tag_value": true}, + {"tag_name": "关注产品功能", "tag_value": true} + ], + "recent_activities": [ + { + "event_type": "wework_chat", + "event_time": "2024-10-29 14:30:00", + "event_desc": "咨询产品定价" + }, + { + "event_type": "call", + "event_time": "2024-10-28 10:15:00", + "event_desc": "电话沟通30分钟" + } + ] + }, + { + "cdp_id": "CDP_000002", + "contact_name": "李四", + "job_title": "财务经理", + "job_level": "MANAGER", + "decision_role": "USER", + "report_to": { + "cdp_id": "CDP_000001", + "name": "张三" + }, + "tags": [ + {"tag_name": "使用者", "tag_value": true}, + {"tag_name": "关注价格", "tag_value": true} + ] + } + ], + "org_chart": { + "chart_data": "组织架构图数据(JSON格式)" + }, + "opportunity": { + "opportunity_count": 2, + "total_amount": 500000, + "latest_stage": "方案阶段" + } +} +``` + +#### 3.2.2 前端展示结构 + +``` +┌─────────────────────────────────────────────────────┐ +│ XX金融科技公司 [A级客户] [高意向] [B轮] │ +│ 行业: 金融科技 | 规模: 500-2000人 | 负责人: 王销售 │ +├─────────────────────────────────────────────────────┤ +│ [企业标签] │ +│ 🏷️ 高意向客户 🏷️ B轮融资 🏷️ 近30天活跃 │ +├─────────────────────────────────────────────────────┤ +│ [关键联系人] │ +│ 👤 张三 - CFO [决策者] │ +│ 📞 138****1234 💬 近7天互动5次 │ +│ 🏷️ 高频互动 🏷️ 关注产品功能 │ +│ │ +│ 👤 李四 - 财务经理 [使用者] (向张三汇报) │ +│ 📞 139****5678 💬 近7天互动2次 │ +│ 🏷️ 关注价格 │ +├─────────────────────────────────────────────────────┤ +│ [组织架构] │ +│ [查看组织架构图] │ +├─────────────────────────────────────────────────────┤ +│ [近期互动] │ +│ • 2024-10-29 14:30 张三通过企微咨询产品定价 │ +│ • 2024-10-28 10:15 与张三电话沟通30分钟 │ +│ • 2024-10-27 16:20 李四浏览了产品方案页面 │ +└─────────────────────────────────────────────────────┘ +``` + +### 3.3 关键点总结 + +| 层面 | 如何处理 | +|-----|---------| +| **存储层** | 企业表和联系人表分离存储 | +| **标签层** | 标签结果表用target_type区分 | +| **查询层** | SQL关联查询或Redis缓存 | +| **应用层** | API整合返回统一视图 | +| **展示层** | 前端组件化展示,用户无感知 | + +--- + +## 四、呼叫中心场景适配 + +### 4.1 呼叫中心特有Schema扩展 + +#### 4.1.1 通话记录表 (ods_callcenter_call_record) + +```sql +CREATE TABLE ods_callcenter_call_record ( + -- 主键 + call_id VARCHAR(64) PRIMARY KEY COMMENT '通话ID', + + -- 通话基本信息 + call_type VARCHAR(32) COMMENT '通话类型: OUTBOUND(外呼)/INBOUND(呼入)/CALLBACK(回拨)', + call_direction VARCHAR(16) COMMENT '呼叫方向: IN/OUT', + call_time DATETIME NOT NULL COMMENT '通话时间', + call_date DATE NOT NULL COMMENT '通话日期', + + -- 客户信息 + customer_mobile VARCHAR(32) COMMENT '客户手机号', + customer_name VARCHAR(128) COMMENT '客户姓名', + customer_company VARCHAR(256) COMMENT '客户企业', + + -- 坐席信息 + agent_id VARCHAR(64) COMMENT '坐席ID', + agent_name VARCHAR(128) COMMENT '坐席姓名', + agent_dept VARCHAR(128) COMMENT '坐席部门', + + -- 通话状态 + call_status VARCHAR(32) COMMENT '通话状态: CONNECTED(接通)/NO_ANSWER(未接)/BUSY(占线)/REJECTED(拒接)', + ring_duration INT COMMENT '振铃时长(秒)', + talk_duration INT COMMENT '通话时长(秒)', + + -- 通话内容 + call_subject VARCHAR(256) COMMENT '通话主题', + call_summary TEXT COMMENT '通话小结', + call_intention VARCHAR(32) COMMENT '客户意向: HIGH(高)/MEDIUM(中)/LOW(低)/NONE(无)', + call_result VARCHAR(32) COMMENT '通话结果: 成功预约/需要跟进/暂无需求/拒绝', + next_follow_time DATETIME COMMENT '下次跟进时间', + + -- 录音信息 + record_file_url VARCHAR(512) COMMENT '录音文件URL', + record_duration INT COMMENT '录音时长(秒)', + + -- 质检信息 + quality_score DECIMAL(5,2) COMMENT '质检分数', + quality_tags TEXT COMMENT '质检标签(JSON)', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + + INDEX idx_customer_mobile (customer_mobile, call_date), + INDEX idx_agent (agent_id, call_date), + INDEX idx_call_time (call_time), + INDEX idx_status (call_status, call_date) +) COMMENT='呼叫中心通话记录表' +PARTITION BY RANGE (TO_DAYS(call_date)) ( + PARTITION p_202410 VALUES LESS THAN (TO_DAYS('2024-11-01')), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +#### 4.1.2 通话记录→行为事件映射 + +```sql +-- 将通话记录转换为标准的行为事件 +INSERT INTO dwd_contact_event ( + event_id, + event_type, + event_time, + event_date, + cdp_id, + account_id, + channel, + event_properties, + source_type, + source_id, + create_time +) +SELECT + call_id AS event_id, + CASE + WHEN call_type = 'OUTBOUND' THEN 'call_outbound' + WHEN call_type = 'INBOUND' THEN 'call_inbound' + WHEN call_type = 'CALLBACK' THEN 'call_callback' + END AS event_type, + call_time AS event_time, + call_date AS event_date, + -- 根据手机号查询CDP ID + (SELECT cdp_id FROM dwd_id_mapping + WHERE source_type='CALLCENTER' + AND match_field='MOBILE' + AND match_value_hash=SHA256(customer_mobile) + LIMIT 1) AS cdp_id, + -- 根据企业名查询account_id + (SELECT account_id FROM dwd_customer_account + WHERE account_name=customer_company + LIMIT 1) AS account_id, + 'PHONE' AS channel, + -- 组装事件属性 + JSON_OBJECT( + 'call_type', call_type, + 'call_status', call_status, + 'talk_duration', talk_duration, + 'call_intention', call_intention, + 'call_result', call_result, + 'call_summary', call_summary, + 'agent_id', agent_id, + 'agent_name', agent_name + ) AS event_properties, + 'CALLCENTER' AS source_type, + call_id AS source_id, + NOW() AS create_time +FROM ods_callcenter_call_record +WHERE call_date >= CURDATE() - INTERVAL 1 DAY + AND call_status = 'CONNECTED'; -- 只转换接通的电话 +``` + +### 4.2 呼叫中心专用标签 + +#### 4.2.1 联系人通话特征标签 + +| 标签名称 | 标签逻辑 | 业务价值 | +|---------|---------|---------| +| 高接通率 | 近30次外呼接通率>70% | 优先外呼 | +| 通话时长长 | 平均通话时长>5分钟 | 意向度高 | +| 高回拨率 | 主动回拨率>30% | 关系强 | +| 最佳接听时段 | 统计接通率最高的时段 | 精准触达 | +| 拒接用户 | 连续3次拒接 | 暂停外呼 | +| 空号/停机 | 呼叫状态为空号 | 清洗数据 | + +**标签计算SQL示例**: + +```sql +-- 高接通率标签 +INSERT INTO dwd_tag_result (target_type, target_id, tag_id, tag_name, tag_value) +SELECT + 'CONTACT' AS target_type, + cdp_id AS target_id, + 'TAG_HIGH_ANSWER_RATE' AS tag_id, + '高接通率' AS tag_name, + 'true' AS tag_value +FROM ( + SELECT + cdp_id, + COUNT(*) AS total_calls, + SUM(CASE WHEN call_status='CONNECTED' THEN 1 ELSE 0 END) AS connected_calls, + SUM(CASE WHEN call_status='CONNECTED' THEN 1 ELSE 0 END) * 1.0 / COUNT(*) AS answer_rate + FROM dwd_contact_event + WHERE event_type LIKE 'call_%' + AND event_date >= CURDATE() - INTERVAL 30 DAY + GROUP BY cdp_id + HAVING total_calls >= 10 -- 至少呼叫10次 +) t +WHERE answer_rate > 0.7; +``` + +### 4.3 呼叫中心圈人场景 + +**场景1:找到"高意向+高接通率"的客户进行外呼** + +```sql +SELECT + c.cdp_id, + c.contact_name, + c.mobile_encrypted, + c.account_id, + a.account_name, + GROUP_CONCAT(t.tag_name) AS tags +FROM dwd_contact c +INNER JOIN dwd_customer_account a ON c.account_id = a.account_id +INNER JOIN dwd_tag_result t ON t.target_id = c.cdp_id AND t.target_type = 'CONTACT' +WHERE t.tag_name IN ('高意向', '高接通率') + AND c.relationship_status = 'CONNECTED' + AND c.is_deleted = 0 +GROUP BY c.cdp_id +HAVING COUNT(DISTINCT t.tag_name) = 2; -- 两个标签都满足 +``` + +**场景2:找到"已外呼但未接通"的客户,选择最佳时段回拨** + +```sql +-- 统计每个联系人的最佳接听时段 +WITH best_time AS ( + SELECT + cdp_id, + HOUR(event_time) AS call_hour, + COUNT(*) AS total_calls, + SUM(CASE WHEN JSON_EXTRACT(event_properties, '$.call_status')='CONNECTED' + THEN 1 ELSE 0 END) AS connected_calls + FROM dwd_contact_event + WHERE event_type = 'call_outbound' + AND event_date >= CURDATE() - INTERVAL 60 DAY + GROUP BY cdp_id, HOUR(event_time) +) +SELECT + c.cdp_id, + c.contact_name, + c.mobile_encrypted, + bt.call_hour AS best_hour, + MAX(bt.connected_calls * 1.0 / bt.total_calls) AS best_answer_rate +FROM dwd_contact c +INNER JOIN best_time bt ON c.cdp_id = bt.cdp_id +WHERE EXISTS ( + -- 近7天有外呼但未接通 + SELECT 1 FROM dwd_contact_event e + WHERE e.cdp_id = c.cdp_id + AND e.event_type = 'call_outbound' + AND e.event_date >= CURDATE() - INTERVAL 7 DAY + AND JSON_EXTRACT(e.event_properties, '$.call_status') != 'CONNECTED' +) +GROUP BY c.cdp_id, bt.call_hour +ORDER BY best_answer_rate DESC; +``` + +--- + +## 五、金融行业扩展 + +### 5.1 金融行业特有字段 + +#### 5.1.1 客户企业表扩展(金融) + +```sql +ALTER TABLE dwd_customer_account +ADD COLUMN financial_license VARCHAR(128) COMMENT '金融牌照类型', +ADD COLUMN risk_level VARCHAR(32) COMMENT '风险等级: LOW/MEDIUM/HIGH', +ADD COLUMN kyc_status VARCHAR(32) COMMENT 'KYC状态: NOT_STARTED/IN_PROGRESS/PASSED/FAILED', +ADD COLUMN aml_status VARCHAR(32) COMMENT '反洗钱状态: PASS/RISK/BLOCK', +ADD COLUMN credit_rating VARCHAR(32) COMMENT '信用评级: AAA/AA/A/BBB/BB/B/CCC', +ADD COLUMN blacklist_status TINYINT DEFAULT 0 COMMENT '是否黑名单: 0=否/1=是'; + +-- 或者使用extra_attributes存储 +UPDATE dwd_customer_account +SET extra_attributes = JSON_SET( + COALESCE(extra_attributes, '{}'), + '$.financial_info.license', '小贷牌照', + '$.financial_info.risk_level', 'LOW', + '$.financial_info.kyc_status', 'PASSED', + '$.financial_info.credit_rating', 'AA' +) +WHERE account_id = 'ACCT_000001'; +``` + +#### 5.1.2 联系人表扩展(金融) + +```sql +ALTER TABLE dwd_contact +ADD COLUMN risk_preference VARCHAR(32) COMMENT '风险偏好: CONSERVATIVE/BALANCED/AGGRESSIVE', +ADD COLUMN investment_experience VARCHAR(32) COMMENT '投资经验: NOVICE/EXPERIENCED/PROFESSIONAL', +ADD COLUMN aum BIGINT COMMENT '资产管理规模(分)', +ADD COLUMN credit_score INT COMMENT '信用分数(0-1000)'; +``` + +### 5.2 金融行业合规要求 + +#### 5.2.1 敏感字段访问控制 + +```sql +-- 创建敏感数据访问日志表 +CREATE TABLE dwd_sensitive_data_access_log ( + log_id VARCHAR(64) PRIMARY KEY, + user_id VARCHAR(64) NOT NULL COMMENT '访问用户ID', + user_name VARCHAR(128) COMMENT '用户姓名', + access_type VARCHAR(32) COMMENT '访问类型: VIEW/EXPORT/EDIT', + target_type VARCHAR(32) COMMENT '目标类型: CONTACT/ACCOUNT', + target_id VARCHAR(64) COMMENT '目标ID', + sensitive_fields TEXT COMMENT '访问的敏感字段(JSON)', + access_reason VARCHAR(256) COMMENT '访问原因', + ip_address VARCHAR(64) COMMENT 'IP地址', + access_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '访问时间', + + INDEX idx_user (user_id, access_time), + INDEX idx_target (target_type, target_id, access_time) +) COMMENT='敏感数据访问日志'; +``` + +#### 5.2.2 数据脱敏规则(金融) + +| 字段类型 | 脱敏规则 | 示例 | +|---------|---------|------| +| 手机号 | 中间4位打码 | 138****1234 | +| 身份证 | 只保留前6后4位 | 110101********1234 | +| 银行卡号 | 只保留后4位 | **** **** **** 1234 | +| 姓名 | 姓氏保留+打码 | 张** | +| 金额 | 按角色显示 | 普通用户看不到 | + +### 5.3 金融行业标签示例 + +```sql +-- 插入金融行业专用标签定义 +INSERT INTO dwd_tag_config (tag_id, tag_name, tag_category, target_type, calculation_rule) +VALUES +-- 企业标签 +('TAG_FIN_LICENSE', '持有金融牌照', '金融合规', 'ACCOUNT', + 'SELECT account_id FROM dwd_customer_account WHERE financial_license IS NOT NULL'), + +('TAG_HIGH_RISK', '高风险企业', '风险评估', 'ACCOUNT', + 'SELECT account_id FROM dwd_customer_account WHERE risk_level = "HIGH"'), + +('TAG_KYC_PASSED', 'KYC已通过', '合规认证', 'ACCOUNT', + 'SELECT account_id FROM dwd_customer_account WHERE kyc_status = "PASSED"'), + +-- 联系人标签 +('TAG_HIGH_NET_WORTH', '高净值客户', '客户分层', 'CONTACT', + 'SELECT cdp_id FROM dwd_contact WHERE aum >= 100000000'), -- 1000万以上 + +('TAG_RISK_AVERSE', '风险厌恶型', '投资偏好', 'CONTACT', + 'SELECT cdp_id FROM dwd_contact WHERE risk_preference = "CONSERVATIVE"'), + +('TAG_QUALIFIED_INVESTOR', '合格投资者', '合规认证', 'CONTACT', + 'SELECT cdp_id FROM dwd_contact WHERE credit_score >= 700 AND investment_experience != "NOVICE"'); +``` + +--- + +## 六、总结与最佳实践 + +### 6.1 核心原则 + +| 原则 | 说明 | +|-----|------| +| **存储分离** | 企业和联系人分表存储 | +| **标签双层** | 标签体系分为企业标签和联系人标签 | +| **圈人统一** | 圈人的输出统一为联系人列表 | +| **视图整合** | 应用层提供360度统一视图 | +| **数据溯源** | 所有数据记录来源系统 | + +### 6.2 常见误区 + +❌ **误区1**:把企业和联系人合并成一张表 +- 问题:一个企业有多个联系人,数据冗余严重 + +❌ **误区2**:只给企业打标签,不给联系人打标签 +- 问题:无法区分同一企业不同联系人的特征 + +❌ **误区3**:圈人时既圈企业又圈联系人,搞不清主体 +- 问题:最终要触达的是"人",所以圈人输出必须是联系人列表 + +### 6.3 实施建议 + +1. **Phase 1**: 先实现基础的企业和联系人管理 +2. **Phase 2**: 建立OneID体系,打通多源数据 +3. **Phase 3**: 建立标签体系(先企业标签,再联系人标签) +4. **Phase 4**: 实现圈人能力(先简单条件,再复杂组合) +5. **Phase 5**: 优化统一视图,提升用户体验 + +--- + +**文档版本**: v1.0 +**最后更新**: 2024-10-30 +**适用场景**: B2B企业级CDP(金融行业/呼叫中心) diff --git a/docs/enterprise-cdp-data-schemas.md b/docs/enterprise-cdp-data-schemas.md new file mode 100644 index 000000000..6c99a5367 --- /dev/null +++ b/docs/enterprise-cdp-data-schemas.md @@ -0,0 +1,1343 @@ +# 企业级CDP数据Schema设计 + +## 目录 + +- [一、Schema设计原则](#一schema设计原则) +- [二、标准化数据模型(DWD层)](#二标准化数据模型dwd层) + - [2.1 客户企业主题](#21-客户企业主题) + - [2.2 联系人主题](#22-联系人主题) + - [2.3 行为事件主题](#23-行为事件主题) + - [2.4 组织关系主题](#24-组织关系主题) + - [2.5 OneID映射表](#25-oneid映射表) +- [三、数据源Schema(ODS层)](#三数据源schemaods层) + - [3.1 企业微信数据Schema](#31-企业微信数据schema) + - [3.2 CRM数据Schema](#32-crm数据schema) + - [3.3 广告数据Schema](#33-广告数据schema) +- [四、数据映射规则](#四数据映射规则) + - [4.1 企业微信→标准模型映射](#41-企业微信标准模型映射) + - [4.2 CRM→标准模型映射](#42-crm标准模型映射) + - [4.3 广告→标准模型映射](#43-广告标准模型映射) +- [五、扩展字段设计](#五扩展字段设计) + +--- + +## 一、Schema设计原则 + +### 1.1 核心原则 + +1. **标准化优先**: DWD层采用统一的数据模型,不依赖于数据源 +2. **可扩展性**: 使用JSON字段存储灵活的扩展属性 +3. **时间有效性**: 关键实体支持有效期管理(start_time, end_time) +4. **数据溯源**: 记录数据来源(source_type, source_id) +5. **幂等性**: 支持重复加工,使用唯一键保证数据不重复 + +### 1.2 命名规范 + +- **表名**: 使用下划线命名法,如 `dwd_customer_account` +- **字段名**: 使用下划线命名法,如 `account_name` +- **枚举值**: 使用大写+下划线,如 `WEWORK`, `CRM` +- **时间字段**: 统一使用 `_time` 后缀,如 `create_time` +- **金额字段**: 统一使用分为单位,字段类型为 `BIGINT` + +### 1.3 数据类型规范 + +| 业务类型 | 数据类型 | 说明 | 示例 | +|---------|---------|------|------| +| 主键ID | VARCHAR(64) | 使用雪花算法生成 | "123456789012345678" | +| 金额 | BIGINT | 以分为单位 | 100000 (表示1000.00元) | +| 枚举 | VARCHAR(32) | 大写字母+下划线 | "WEWORK", "CRM" | +| 时间戳 | BIGINT | Unix时间戳(毫秒) | 1698739200000 | +| 时间 | DATETIME | 标准时间格式 | 2024-10-30 12:00:00 | +| 布尔 | TINYINT | 0=false, 1=true | 0, 1 | +| JSON | TEXT | 存储非结构化数据 | {"key": "value"} | +| 手机号 | VARCHAR(32) | 加密后存储 | "AES_ENCRYPTED_DATA" | + +--- + +## 二、标准化数据模型(DWD层) + +### 2.1 客户企业主题 + +#### 2.1.1 客户企业主表 (dwd_customer_account) + +存储客户企业的基本信息和业务属性。 + +```sql +CREATE TABLE dwd_customer_account ( + -- 主键与标识 + account_id VARCHAR(64) PRIMARY KEY COMMENT '客户企业ID(CDP统一ID)', + account_name VARCHAR(256) NOT NULL COMMENT '企业名称', + account_name_en VARCHAR(256) COMMENT '企业英文名称', + + -- 企业基本信息 + industry VARCHAR(64) COMMENT '所属行业: 互联网/金融/制造/教育等', + sub_industry VARCHAR(64) COMMENT '细分行业', + company_type VARCHAR(32) COMMENT '企业类型: 国企/民企/外企/合资', + company_scale VARCHAR(32) COMMENT '企业规模: 0-50/50-150/150-500/500-2000/2000+', + employee_count INT COMMENT '员工人数', + + -- 经营信息 + annual_revenue BIGINT COMMENT '年营收(分)', + registered_capital BIGINT COMMENT '注册资本(分)', + founded_date DATE COMMENT '成立日期', + listing_status VARCHAR(32) COMMENT '上市状态: 未上市/新三板/A股/港股/美股', + financing_stage VARCHAR(32) COMMENT '融资阶段: 未融资/天使轮/A轮/B轮/C轮/上市', + + -- 企业地址 + country VARCHAR(64) DEFAULT '中国' COMMENT '国家', + province VARCHAR(64) COMMENT '省份', + city VARCHAR(64) COMMENT '城市', + district VARCHAR(64) COMMENT '区/县', + address TEXT COMMENT '详细地址', + + -- 企业标识 + unified_social_credit_code VARCHAR(32) COMMENT '统一社会信用代码', + business_license_number VARCHAR(32) COMMENT '营业执照号', + + -- 客户分类与状态 + customer_type VARCHAR(32) COMMENT '客户类型: LEAD(潜在客户)/OPPORTUNITY(商机)/CUSTOMER(成交客户)/LOST(流失客户)', + customer_level VARCHAR(32) COMMENT '客户等级: S(战略)/A(重点)/B(普通)/C(小客户)', + customer_status VARCHAR(32) DEFAULT 'ACTIVE' COMMENT '客户状态: ACTIVE(活跃)/INACTIVE(不活跃)/CLOSED(已关闭)', + + -- 客户关系 + parent_account_id VARCHAR(64) COMMENT '母公司ID(支持集团客户)', + account_hierarchy_level INT DEFAULT 1 COMMENT '层级: 1=集团/2=子公司/3=分公司', + + -- 业务负责人 + owner_staff_id VARCHAR(64) COMMENT '客户负责人(销售)ID', + owner_staff_name VARCHAR(128) COMMENT '客户负责人姓名', + owner_dept_id VARCHAR(64) COMMENT '负责部门ID', + owner_dept_name VARCHAR(128) COMMENT '负责部门名称', + + -- 业务数据 + first_contact_date DATE COMMENT '首次接触日期', + last_contact_date DATE COMMENT '最近接触日期', + total_opportunity_count INT DEFAULT 0 COMMENT '商机总数', + total_opportunity_amount BIGINT DEFAULT 0 COMMENT '商机总额(分)', + total_contract_count INT DEFAULT 0 COMMENT '合同总数', + total_contract_amount BIGINT DEFAULT 0 COMMENT '合同总额(分)', + + -- 活跃度指标 + interaction_count_l7d INT DEFAULT 0 COMMENT '近7天互动次数', + interaction_count_l30d INT DEFAULT 0 COMMENT '近30天互动次数', + last_active_time DATETIME COMMENT '最后活跃时间', + + -- 数据溯源 + source_type VARCHAR(32) COMMENT '数据来源: CRM/WEWORK/IMPORT/API', + source_id VARCHAR(128) COMMENT '来源系统中的ID', + source_create_time DATETIME COMMENT '来源系统创建时间', + + -- 扩展字段 + extra_attributes TEXT COMMENT '扩展属性(JSON格式)', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + is_deleted TINYINT DEFAULT 0 COMMENT '是否删除: 0=否/1=是', + + INDEX idx_account_name (account_name), + INDEX idx_owner_staff (owner_staff_id), + INDEX idx_customer_type (customer_type), + INDEX idx_source (source_type, source_id), + INDEX idx_parent (parent_account_id) +) COMMENT='客户企业主表'; +``` + +**核心字段说明**: + +| 字段类别 | 核心字段 | 业务含义 | +|---------|---------|---------| +| 企业身份 | account_id, account_name | 唯一标识客户企业 | +| 企业画像 | industry, company_scale, annual_revenue | 用于客户分层和圈人 | +| 客户分类 | customer_type, customer_level | 销售管理的核心字段 | +| 组织关系 | parent_account_id, account_hierarchy_level | 支持集团型客户 | +| 业务指标 | total_contract_amount, interaction_count_l30d | 客户价值评估 | +| 数据溯源 | source_type, source_id | 追溯数据来源 | + +#### 2.1.2 客户企业组织架构表 (dwd_customer_org) + +存储客户企业内部的组织架构信息。 + +```sql +CREATE TABLE dwd_customer_org ( + -- 主键 + org_id VARCHAR(64) PRIMARY KEY COMMENT '组织ID', + + -- 所属企业 + account_id VARCHAR(64) NOT NULL COMMENT '所属客户企业ID', + + -- 组织信息 + org_name VARCHAR(256) NOT NULL COMMENT '组织名称', + org_name_en VARCHAR(256) COMMENT '组织英文名称', + org_code VARCHAR(64) COMMENT '组织编码', + org_type VARCHAR(32) COMMENT '组织类型: DEPT(部门)/CENTER(中心)/TEAM(小组)/BRANCH(分公司)', + + -- 层级关系 + parent_org_id VARCHAR(64) COMMENT '父组织ID', + org_level INT DEFAULT 1 COMMENT '组织层级: 1/2/3/...', + org_path TEXT COMMENT '组织路径: /root/dept1/team1', + + -- 负责人 + leader_cdp_id VARCHAR(64) COMMENT '组织负责人CDP ID', + leader_name VARCHAR(128) COMMENT '负责人姓名', + + -- 状态 + org_status VARCHAR(32) DEFAULT 'ACTIVE' COMMENT '组织状态: ACTIVE/INACTIVE', + + -- 数据溯源 + source_type VARCHAR(32) COMMENT '数据来源: CRM/WEWORK/IMPORT', + source_id VARCHAR(128) COMMENT '来源系统中的ID', + + -- 扩展字段 + extra_attributes TEXT COMMENT '扩展属性(JSON)', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + is_deleted TINYINT DEFAULT 0, + + INDEX idx_account (account_id), + INDEX idx_parent (parent_org_id), + INDEX idx_leader (leader_cdp_id) +) COMMENT='客户企业组织架构表'; +``` + +--- + +### 2.2 联系人主题 + +#### 2.2.1 联系人主表 (dwd_contact) + +存储客户企业的联系人(决策人、影响者等)信息。 + +```sql +CREATE TABLE dwd_contact ( + -- 主键与标识 + cdp_id VARCHAR(64) PRIMARY KEY COMMENT '联系人CDP统一ID', + + -- 所属企业 + account_id VARCHAR(64) NOT NULL COMMENT '所属客户企业ID', + account_name VARCHAR(256) COMMENT '所属企业名称(冗余)', + + -- 基本信息 + contact_name VARCHAR(128) NOT NULL COMMENT '姓名', + contact_name_en VARCHAR(128) COMMENT '英文名', + gender VARCHAR(8) COMMENT '性别: MALE/FEMALE/UNKNOWN', + avatar_url VARCHAR(512) COMMENT '头像URL', + + -- 职位信息 + job_title VARCHAR(128) COMMENT '职位名称', + job_level VARCHAR(32) COMMENT '职级: STAFF(员工)/SUPERVISOR(主管)/MANAGER(经理)/DIRECTOR(总监)/VP(副总裁)/CXO(C级高管)', + seniority VARCHAR(32) COMMENT '资历: JUNIOR(初级)/MIDDLE(中级)/SENIOR(高级)/EXPERT(专家)', + department VARCHAR(256) COMMENT '部门', + + -- 联系方式(敏感信息) + mobile_encrypted VARCHAR(256) COMMENT '手机号(加密)', + mobile_hash VARCHAR(64) COMMENT '手机号哈希(用于匹配)', + email_encrypted VARCHAR(256) COMMENT '邮箱(加密)', + email_hash VARCHAR(64) COMMENT '邮箱哈希(用于匹配)', + wechat VARCHAR(128) COMMENT '微信号', + + -- 组织关系 + org_id VARCHAR(64) COMMENT '所属组织ID', + org_name VARCHAR(256) COMMENT '所属组织名称(冗余)', + report_to_cdp_id VARCHAR(64) COMMENT '直属上级CDP ID', + report_to_name VARCHAR(128) COMMENT '直属上级姓名(冗余)', + + -- 决策角色 + decision_role VARCHAR(32) COMMENT '决策角色: DECISION_MAKER(决策者)/INFLUENCER(影响者)/USER(使用者)/GATEKEEPER(把关者)', + importance_level VARCHAR(32) COMMENT '重要程度: HIGH(高)/MEDIUM(中)/LOW(低)', + + -- 客户关系 + relationship_status VARCHAR(32) DEFAULT 'UNCONNECTED' COMMENT '关系状态: UNCONNECTED(未触达)/CONNECTED(已触达)/ACTIVE(活跃)/INACTIVE(不活跃)', + owner_staff_id VARCHAR(64) COMMENT '对接销售ID', + owner_staff_name VARCHAR(128) COMMENT '对接销售姓名', + + -- 活跃度 + first_contact_date DATE COMMENT '首次接触日期', + last_contact_date DATE COMMENT '最近接触日期', + interaction_count_total INT DEFAULT 0 COMMENT '总互动次数', + interaction_count_l7d INT DEFAULT 0 COMMENT '近7天互动次数', + interaction_count_l30d INT DEFAULT 0 COMMENT '近30天互动次数', + last_active_time DATETIME COMMENT '最后活跃时间', + + -- 数据质量 + data_quality_score DECIMAL(5,2) COMMENT '数据质量分数(0-100)', + data_completeness DECIMAL(5,2) COMMENT '数据完整度(0-100)', + + -- 数据溯源 + primary_source_type VARCHAR(32) COMMENT '主数据源: CRM/WEWORK/IMPORT', + primary_source_id VARCHAR(128) COMMENT '主数据源ID', + + -- 扩展字段 + extra_attributes TEXT COMMENT '扩展属性(JSON)', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + is_deleted TINYINT DEFAULT 0, + + INDEX idx_account (account_id), + INDEX idx_name (contact_name), + INDEX idx_job_level (job_level), + INDEX idx_mobile_hash (mobile_hash), + INDEX idx_email_hash (email_hash), + INDEX idx_owner (owner_staff_id), + INDEX idx_report_to (report_to_cdp_id) +) COMMENT='联系人主表'; +``` + +**核心字段说明**: + +| 字段类别 | 核心字段 | 业务含义 | +|---------|---------|---------| +| 身份标识 | cdp_id, account_id | 唯一标识联系人及其所属企业 | +| 职位信息 | job_title, job_level | 判断决策权重的核心字段 | +| 敏感信息 | mobile_encrypted, email_encrypted | 加密存储,用hash做匹配 | +| 组织关系 | report_to_cdp_id, org_id | 支持组织穿透查询 | +| 决策角色 | decision_role, importance_level | 销售策略制定的关键 | +| 活跃度 | interaction_count_l30d, last_active_time | 客户意向判断 | + +#### 2.2.2 联系人组织关系表 (dwd_contact_org_relation) + +支持一个联系人在多个组织中的情况(矩阵式管理、兼职等)。 + +```sql +CREATE TABLE dwd_contact_org_relation ( + -- 主键 + relation_id VARCHAR(64) PRIMARY KEY COMMENT '关系ID', + + -- 联系人与组织 + cdp_id VARCHAR(64) NOT NULL COMMENT '联系人CDP ID', + account_id VARCHAR(64) NOT NULL COMMENT '客户企业ID', + org_id VARCHAR(64) NOT NULL COMMENT '组织ID', + + -- 职位信息 + job_title VARCHAR(128) COMMENT '在该组织的职位', + job_level VARCHAR(32) COMMENT '职级', + job_type VARCHAR(32) COMMENT '岗位类型: PRIMARY(主职)/PART_TIME(兼职)/DOTTED_LINE(虚线汇报)', + + -- 汇报关系 + report_to_cdp_id VARCHAR(64) COMMENT '在该组织的直属上级', + report_to_name VARCHAR(128) COMMENT '上级姓名', + + -- 有效期 + start_date DATE COMMENT '生效日期', + end_date DATE COMMENT '失效日期(NULL表示仍有效)', + is_current TINYINT DEFAULT 1 COMMENT '是否当前有效: 0=否/1=是', + + -- 数据溯源 + source_type VARCHAR(32) COMMENT '数据来源', + source_id VARCHAR(128) COMMENT '来源系统ID', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_contact_org_type (cdp_id, org_id, job_type, is_current), + INDEX idx_cdp (cdp_id), + INDEX idx_org (org_id), + INDEX idx_report_to (report_to_cdp_id), + INDEX idx_current (is_current) +) COMMENT='联系人组织关系表'; +``` + +--- + +### 2.3 行为事件主题 + +#### 2.3.1 行为事件明细表 (dwd_contact_event) + +存储联系人的所有行为事件明细,支持按日期分区。 + +```sql +CREATE TABLE dwd_contact_event ( + -- 事件标识 + event_id VARCHAR(64) PRIMARY KEY COMMENT '事件ID', + event_type VARCHAR(64) NOT NULL COMMENT '事件类型', + event_time DATETIME NOT NULL COMMENT '事件发生时间', + event_date DATE NOT NULL COMMENT '事件日期(分区字段)', + + -- 事件主体 + cdp_id VARCHAR(64) NOT NULL COMMENT '联系人CDP ID', + account_id VARCHAR(64) COMMENT '所属企业ID', + + -- 事件对象(如果有) + target_type VARCHAR(32) COMMENT '目标类型: STAFF(员工)/PAGE(页面)/DOCUMENT(文档)/PRODUCT(产品)', + target_id VARCHAR(64) COMMENT '目标ID', + target_name VARCHAR(256) COMMENT '目标名称', + + -- 事件属性 + event_properties TEXT COMMENT '事件属性(JSON格式)', + + -- 渠道信息 + channel VARCHAR(32) COMMENT '事件渠道: WEWORK(企微)/WEB(网站)/EMAIL(邮件)/PHONE(电话)/MEETING(会议)', + device_type VARCHAR(32) COMMENT '设备类型: PC/MOBILE/PAD', + + -- 位置信息 + ip_address VARCHAR(64) COMMENT 'IP地址', + country VARCHAR(64) COMMENT '国家', + province VARCHAR(64) COMMENT '省份', + city VARCHAR(64) COMMENT '城市', + + -- 数据溯源 + source_type VARCHAR(32) NOT NULL COMMENT '数据来源: WEWORK/WEB/CRM/EMAIL', + source_id VARCHAR(128) COMMENT '来源系统事件ID', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间', + + INDEX idx_cdp_time (cdp_id, event_date), + INDEX idx_account_time (account_id, event_date), + INDEX idx_event_type (event_type, event_date), + INDEX idx_channel (channel, event_date) +) COMMENT='行为事件明细表' +PARTITION BY RANGE (TO_DAYS(event_date)) ( + PARTITION p_202410 VALUES LESS THAN (TO_DAYS('2024-11-01')), + PARTITION p_202411 VALUES LESS THAN (TO_DAYS('2024-12-01')), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +**常见事件类型定义**: + +| 事件类型 | 说明 | event_properties示例 | +|---------|------|---------------------| +| wework_add_contact | 企微添加外部联系人 | {"add_way": "扫码", "state": "渠道A"} | +| wework_chat | 企微聊天消息 | {"msg_type": "text", "direction": "in"} | +| wework_group_join | 加入企微群聊 | {"group_id": "xxx", "group_name": "产品交流群"} | +| page_view | 页面浏览 | {"page_url": "/product/detail", "duration": 120} | +| document_view | 文档查看 | {"doc_id": "123", "doc_name": "产品方案.pdf"} | +| email_open | 邮件打开 | {"campaign_id": "xxx", "subject": "新产品发布"} | +| email_click | 邮件链接点击 | {"link_url": "https://..."} | +| meeting_attend | 参加会议 | {"meeting_id": "xxx", "duration": 60} | +| form_submit | 表单提交 | {"form_type": "试用申请", "fields": {...}} | +| crm_call | CRM电话记录 | {"duration": 300, "call_result": "有意向"} | +| crm_visit | CRM拜访记录 | {"visit_type": "现场", "result": "洽谈顺利"} | + +--- + +### 2.4 组织关系主题 + +#### 2.4.1 组织关系图谱 (dwd_org_graph) + +针对复杂的组织关系查询,建议使用图数据库(Neo4j),但也可以用关系表存储。 + +```sql +CREATE TABLE dwd_org_graph ( + -- 主键 + relation_id VARCHAR(64) PRIMARY KEY COMMENT '关系ID', + + -- 关系类型 + relation_type VARCHAR(32) NOT NULL COMMENT '关系类型: REPORT_TO(汇报)/COLLEAGUE(同事)/SAME_ORG(同部门)', + + -- 关系双方 + from_cdp_id VARCHAR(64) NOT NULL COMMENT '起点联系人CDP ID', + to_cdp_id VARCHAR(64) NOT NULL COMMENT '终点联系人CDP ID', + + -- 关系属性 + relation_strength DECIMAL(5,2) COMMENT '关系强度(0-1)', + relation_distance INT COMMENT '关系距离(如几级汇报关系)', + + -- 所属企业 + account_id VARCHAR(64) NOT NULL COMMENT '客户企业ID', + + -- 有效期 + start_date DATE COMMENT '生效日期', + end_date DATE COMMENT '失效日期', + is_current TINYINT DEFAULT 1 COMMENT '是否当前有效', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_from_to_type (from_cdp_id, to_cdp_id, relation_type, is_current), + INDEX idx_from (from_cdp_id), + INDEX idx_to (to_cdp_id), + INDEX idx_account (account_id), + INDEX idx_type (relation_type) +) COMMENT='组织关系图谱表'; +``` + +**Neo4j图模型(推荐)**: + +```cypher +// 联系人节点 +(c:Contact { + cdp_id: "CDP_123456", + name: "张三", + job_title: "技术总监", + job_level: "DIRECTOR", + account_id: "ACCT_001" +}) + +// 组织节点 +(o:Organization { + org_id: "ORG_123", + org_name: "技术部", + account_id: "ACCT_001" +}) + +// 汇报关系 +(c1:Contact)-[:REPORT_TO {since: "2024-01-01"}]->(c2:Contact) + +// 所属关系 +(c:Contact)-[:BELONG_TO {job_type: "PRIMARY"}]->(o:Organization) + +// 同事关系 +(c1:Contact)-[:COLLEAGUE {org_id: "ORG_123"}]->(c2:Contact) +``` + +--- + +### 2.5 OneID映射表 + +#### 2.5.1 ID映射关系表 (dwd_id_mapping) + +存储CDP统一ID与各来源系统ID的映射关系。 + +```sql +CREATE TABLE dwd_id_mapping ( + -- 主键 + mapping_id VARCHAR(64) PRIMARY KEY COMMENT '映射记录ID', + + -- CDP统一ID + cdp_id VARCHAR(64) NOT NULL COMMENT '联系人CDP统一ID', + entity_type VARCHAR(32) NOT NULL DEFAULT 'CONTACT' COMMENT '实体类型: CONTACT/ACCOUNT', + + -- 来源系统ID + source_type VARCHAR(32) NOT NULL COMMENT '来源系统: CRM/WEWORK/IMPORT/WEB', + source_id VARCHAR(128) NOT NULL COMMENT '来源系统中的ID', + source_name VARCHAR(256) COMMENT '来源系统中的名称', + + -- 匹配信息 + match_field VARCHAR(32) COMMENT '匹配字段: MOBILE/EMAIL/UNIONID/NAME_COMPANY', + match_value_hash VARCHAR(128) COMMENT '匹配值哈希', + match_confidence DECIMAL(5,2) DEFAULT 1.00 COMMENT '匹配置信度(0-1)', + match_method VARCHAR(32) COMMENT '匹配方式: AUTO(自动)/MANUAL(人工)', + + -- 状态 + mapping_status VARCHAR(32) DEFAULT 'ACTIVE' COMMENT '映射状态: ACTIVE(有效)/CONFLICT(冲突)/MERGED(已合并)', + conflict_reason TEXT COMMENT '冲突原因', + + -- 审计信息 + created_by VARCHAR(64) COMMENT '创建人', + reviewed_by VARCHAR(64) COMMENT '审核人', + review_time DATETIME COMMENT '审核时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_source (source_type, source_id), + INDEX idx_cdp (cdp_id), + INDEX idx_match (match_field, match_value_hash), + INDEX idx_status (mapping_status) +) COMMENT='ID映射关系表'; +``` + +**核心业务逻辑**: + +1. **新数据进入时**: 根据 `match_field` (手机号/邮箱等)查询是否已存在映射 +2. **存在映射**: 直接使用已有的 `cdp_id` +3. **不存在映射**: 生成新的 `cdp_id`,创建映射记录 +4. **冲突检测**: 一个 `source_id` 对应多个 `cdp_id` 时,标记为 `CONFLICT`,需人工审核 + +--- + +## 三、数据源Schema(ODS层) + +### 3.1 企业微信数据Schema + +#### 3.1.1 企微外部联系人表 (ods_wework_external_contact) + +存储从企业微信获取的外部联系人原始数据。 + +```sql +CREATE TABLE ods_wework_external_contact ( + -- 主键 + id VARCHAR(64) PRIMARY KEY COMMENT '自增ID', + + -- 企微标识 + external_userid VARCHAR(128) NOT NULL COMMENT '企微外部联系人ID', + unionid VARCHAR(128) COMMENT '微信unionid(跨应用唯一)', + + -- 基本信息 + name VARCHAR(128) COMMENT '外部联系人名称', + avatar VARCHAR(512) COMMENT '头像URL', + type TINYINT COMMENT '外部联系人类型: 1=微信用户/2=企微用户', + gender TINYINT COMMENT '性别: 0=未知/1=男/2=女', + + -- 企业信息 + corp_name VARCHAR(256) COMMENT '企业名称', + corp_full_name VARCHAR(512) COMMENT '企业全称', + position VARCHAR(128) COMMENT '职位', + + -- 添加信息 + add_way INT COMMENT '添加方式', + state VARCHAR(256) COMMENT '渠道参数', + userid VARCHAR(128) NOT NULL COMMENT '添加该外部联系人的企业员工userid', + + -- 标签 + tag_ids TEXT COMMENT '企微标签ID列表(JSON数组)', + + -- 备注 + remark VARCHAR(512) COMMENT '备注', + description VARCHAR(1024) COMMENT '描述', + remark_corp_name VARCHAR(256) COMMENT '备注企业名称', + remark_mobiles TEXT COMMENT '备注手机号(JSON数组)', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集信息 + corp_id VARCHAR(128) COMMENT '企业微信企业ID', + data_source VARCHAR(32) DEFAULT 'WEWORK_API' COMMENT '数据来源', + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_external_userid (external_userid), + INDEX idx_unionid (unionid), + INDEX idx_userid (userid), + INDEX idx_corp_name (corp_name), + INDEX idx_sync_time (sync_time) +) COMMENT='企微外部联系人原始表'; +``` + +#### 3.1.2 企微聊天事件表 (ods_wework_chat_event) + +存储企微聊天互动原始数据。 + +```sql +CREATE TABLE ods_wework_chat_event ( + -- 主键 + event_id VARCHAR(64) PRIMARY KEY COMMENT '事件ID', + + -- 消息标识 + msgid VARCHAR(128) COMMENT '消息ID', + seq BIGINT COMMENT '消息序列号', + + -- 时间 + msg_time DATETIME NOT NULL COMMENT '消息时间', + event_date DATE NOT NULL COMMENT '事件日期', + + -- 消息主体 + from_userid VARCHAR(128) COMMENT '发送者userid(员工)', + tolist TEXT COMMENT '接收者列表(JSON数组)', + roomid VARCHAR(128) COMMENT '群聊ID', + + -- 外部联系人 + external_userid VARCHAR(128) COMMENT '外部联系人ID', + + -- 消息内容 + msgtype VARCHAR(32) COMMENT '消息类型: text/image/voice/video/file/link/emotion/weapp', + content TEXT COMMENT '消息内容(根据类型不同格式不同)', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集信息 + corp_id VARCHAR(128) COMMENT '企业微信企业ID', + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + + INDEX idx_external_user (external_userid, event_date), + INDEX idx_from_user (from_userid, event_date), + INDEX idx_room (roomid, event_date), + INDEX idx_msg_time (msg_time) +) COMMENT='企微聊天事件原始表' +PARTITION BY RANGE (TO_DAYS(event_date)) ( + PARTITION p_202410 VALUES LESS THAN (TO_DAYS('2024-11-01')), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +#### 3.1.3 企微客户群表 (ods_wework_group_chat) + +存储企微客户群信息。 + +```sql +CREATE TABLE ods_wework_group_chat ( + -- 主键 + chat_id VARCHAR(128) PRIMARY KEY COMMENT '群聊ID', + + -- 群信息 + name VARCHAR(256) COMMENT '群名称', + owner VARCHAR(128) COMMENT '群主userid', + notice VARCHAR(1024) COMMENT '群公告', + + -- 成员信息 + member_list TEXT COMMENT '群成员列表(JSON数组)', + member_count INT COMMENT '成员数量', + + -- 群状态 + status TINYINT COMMENT '群状态: 0=正常/1=已解散', + + -- 创建时间 + create_time_ts BIGINT COMMENT '群创建时间戳', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集 + corp_id VARCHAR(128) COMMENT '企业微信企业ID', + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + INDEX idx_owner (owner), + INDEX idx_status (status) +) COMMENT='企微客户群原始表'; +``` + +--- + +### 3.2 CRM数据Schema + +#### 3.2.1 CRM客户表 (ods_crm_account) + +存储从CRM系统同步的客户企业原始数据。 + +```sql +CREATE TABLE ods_crm_account ( + -- 主键 + id VARCHAR(64) PRIMARY KEY COMMENT '自增ID', + + -- CRM标识 + crm_account_id VARCHAR(128) NOT NULL COMMENT 'CRM系统客户ID', + + -- 客户基本信息 + account_name VARCHAR(256) COMMENT '客户名称', + account_name_en VARCHAR(256) COMMENT '英文名称', + industry VARCHAR(64) COMMENT '行业', + company_type VARCHAR(32) COMMENT '企业类型', + employee_count INT COMMENT '员工数', + annual_revenue DECIMAL(20,2) COMMENT '年营收', + + -- 地址信息 + country VARCHAR(64) COMMENT '国家', + province VARCHAR(64) COMMENT '省份', + city VARCHAR(64) COMMENT '城市', + address TEXT COMMENT '详细地址', + + -- 客户分类 + customer_type VARCHAR(32) COMMENT '客户类型', + customer_level VARCHAR(32) COMMENT '客户等级', + customer_status VARCHAR(32) COMMENT '客户状态', + + -- 业务负责人 + owner_id VARCHAR(64) COMMENT '负责人ID', + owner_name VARCHAR(128) COMMENT '负责人姓名', + + -- 业务数据 + opportunity_count INT COMMENT '商机数量', + contract_count INT COMMENT '合同数量', + total_amount DECIMAL(20,2) COMMENT '合同总额', + + -- CRM时间字段 + crm_create_time DATETIME COMMENT 'CRM创建时间', + crm_update_time DATETIME COMMENT 'CRM更新时间', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集信息 + crm_source VARCHAR(32) COMMENT 'CRM系统来源: SALESFORCE/DYNAMICS/自建', + sync_time DATETIME COMMENT '同步时间', + sync_type VARCHAR(16) COMMENT '同步类型: FULL/INCR', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_crm_id (crm_account_id), + INDEX idx_account_name (account_name), + INDEX idx_owner (owner_id), + INDEX idx_sync_time (sync_time) +) COMMENT='CRM客户原始表'; +``` + +#### 3.2.2 CRM联系人表 (ods_crm_contact) + +```sql +CREATE TABLE ods_crm_contact ( + -- 主键 + id VARCHAR(64) PRIMARY KEY COMMENT '自增ID', + + -- CRM标识 + crm_contact_id VARCHAR(128) NOT NULL COMMENT 'CRM联系人ID', + crm_account_id VARCHAR(128) COMMENT 'CRM客户ID', + + -- 基本信息 + contact_name VARCHAR(128) COMMENT '姓名', + gender VARCHAR(8) COMMENT '性别', + + -- 职位信息 + title VARCHAR(128) COMMENT '职位', + department VARCHAR(256) COMMENT '部门', + + -- 联系方式 + mobile VARCHAR(32) COMMENT '手机号', + email VARCHAR(128) COMMENT '邮箱', + wechat VARCHAR(128) COMMENT '微信', + phone VARCHAR(32) COMMENT '座机', + + -- 汇报关系 + report_to_id VARCHAR(128) COMMENT '上级CRM ID', + report_to_name VARCHAR(128) COMMENT '上级姓名', + + -- 决策角色 + decision_role VARCHAR(32) COMMENT '决策角色', + + -- CRM时间字段 + crm_create_time DATETIME COMMENT 'CRM创建时间', + crm_update_time DATETIME COMMENT 'CRM更新时间', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集 + crm_source VARCHAR(32) COMMENT 'CRM系统来源', + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_crm_id (crm_contact_id), + INDEX idx_account (crm_account_id), + INDEX idx_mobile (mobile), + INDEX idx_email (email) +) COMMENT='CRM联系人原始表'; +``` + +#### 3.2.3 CRM活动记录表 (ods_crm_activity) + +存储CRM中的客户互动活动(电话、拜访、邮件等)。 + +```sql +CREATE TABLE ods_crm_activity ( + -- 主键 + activity_id VARCHAR(64) PRIMARY KEY COMMENT '活动ID', + + -- CRM标识 + crm_activity_id VARCHAR(128) NOT NULL COMMENT 'CRM活动ID', + crm_account_id VARCHAR(128) COMMENT '关联客户ID', + crm_contact_id VARCHAR(128) COMMENT '关联联系人ID', + + -- 活动信息 + activity_type VARCHAR(32) COMMENT '活动类型: CALL(电话)/VISIT(拜访)/EMAIL(邮件)/MEETING(会议)', + activity_subject VARCHAR(256) COMMENT '活动主题', + activity_description TEXT COMMENT '活动描述', + activity_result VARCHAR(128) COMMENT '活动结果', + + -- 时间信息 + activity_date DATE COMMENT '活动日期', + activity_time DATETIME COMMENT '活动时间', + duration INT COMMENT '持续时长(分钟)', + + -- 参与人 + owner_id VARCHAR(64) COMMENT '负责人ID', + owner_name VARCHAR(128) COMMENT '负责人姓名', + participants TEXT COMMENT '参与人列表(JSON)', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集 + crm_source VARCHAR(32) COMMENT 'CRM系统来源', + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + + INDEX idx_account (crm_account_id, activity_date), + INDEX idx_contact (crm_contact_id, activity_date), + INDEX idx_type (activity_type, activity_date), + INDEX idx_owner (owner_id, activity_date) +) COMMENT='CRM活动记录原始表' +PARTITION BY RANGE (TO_DAYS(activity_date)) ( + PARTITION p_202410 VALUES LESS THAN (TO_DAYS('2024-11-01')), + PARTITION p_future VALUES LESS THAN MAXVALUE +); +``` + +--- + +### 3.3 广告数据Schema + +#### 3.3.1 广告投放数据表 (ods_ad_campaign) + +存储广告平台的投放数据(腾讯广告、字节广告等)。 + +```sql +CREATE TABLE ods_ad_campaign ( + -- 主键 + record_id VARCHAR(64) PRIMARY KEY COMMENT '记录ID', + + -- 广告平台标识 + platform VARCHAR(32) NOT NULL COMMENT '广告平台: TENCENT(腾讯)/BYTEDANCE(字节)/BAIDU(百度)', + account_id VARCHAR(128) COMMENT '广告账户ID', + account_name VARCHAR(256) COMMENT '广告账户名称', + + -- 广告层级 + campaign_id VARCHAR(128) COMMENT '广告计划ID', + campaign_name VARCHAR(256) COMMENT '广告计划名称', + ad_group_id VARCHAR(128) COMMENT '广告组ID', + ad_group_name VARCHAR(256) COMMENT '广告组名称', + ad_id VARCHAR(128) COMMENT '广告创意ID', + ad_name VARCHAR(256) COMMENT '广告创意名称', + + -- 投放信息 + targeting_type VARCHAR(32) COMMENT '定向类型: KEYWORD(关键词)/INTEREST(兴趣)/BEHAVIOR(行为)/LOOKALIKE(相似)', + targeting_config TEXT COMMENT '定向配置(JSON)', + + -- 数据统计(按天) + stat_date DATE NOT NULL COMMENT '统计日期', + + -- 曝光与点击 + impression_count INT DEFAULT 0 COMMENT '曝光量', + click_count INT DEFAULT 0 COMMENT '点击量', + ctr DECIMAL(10,4) COMMENT '点击率', + + -- 成本数据 + cost_amount BIGINT DEFAULT 0 COMMENT '消耗金额(分)', + cpc BIGINT COMMENT '点击单价(分)', + cpm BIGINT COMMENT '千次展示成本(分)', + + -- 转化数据 + conversion_count INT DEFAULT 0 COMMENT '转化量', + conversion_cost BIGINT COMMENT '转化成本(分)', + conversion_rate DECIMAL(10,4) COMMENT '转化率', + + -- 线索数据 + lead_count INT DEFAULT 0 COMMENT '线索量', + lead_cost BIGINT COMMENT '线索成本(分)', + valid_lead_count INT DEFAULT 0 COMMENT '有效线索量', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集 + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_ad_date (platform, campaign_id, ad_id, stat_date), + INDEX idx_campaign (campaign_id, stat_date), + INDEX idx_ad (ad_id, stat_date), + INDEX idx_date (stat_date) +) COMMENT='广告投放数据原始表'; +``` + +#### 3.3.2 广告线索数据表 (ods_ad_lead) + +存储从广告平台获取的线索数据。 + +```sql +CREATE TABLE ods_ad_lead ( + -- 主键 + lead_id VARCHAR(64) PRIMARY KEY COMMENT '线索ID', + + -- 广告平台标识 + platform VARCHAR(32) NOT NULL COMMENT '广告平台', + platform_lead_id VARCHAR(128) COMMENT '平台线索ID', + + -- 广告来源 + campaign_id VARCHAR(128) COMMENT '广告计划ID', + campaign_name VARCHAR(256) COMMENT '广告计划名称', + ad_id VARCHAR(128) COMMENT '广告创意ID', + ad_name VARCHAR(256) COMMENT '广告创意名称', + + -- 线索信息 + company_name VARCHAR(256) COMMENT '企业名称', + contact_name VARCHAR(128) COMMENT '联系人姓名', + mobile VARCHAR(32) COMMENT '手机号', + email VARCHAR(128) COMMENT '邮箱', + position VARCHAR(128) COMMENT '职位', + + -- 留资表单 + form_id VARCHAR(128) COMMENT '表单ID', + form_name VARCHAR(256) COMMENT '表单名称', + form_data TEXT COMMENT '表单数据(JSON)', + + -- 线索质量 + lead_status VARCHAR(32) COMMENT '线索状态: NEW(新)/VALID(有效)/INVALID(无效)', + lead_quality VARCHAR(32) COMMENT '线索质量: HIGH/MEDIUM/LOW', + invalid_reason VARCHAR(256) COMMENT '无效原因', + + -- 时间信息 + lead_time DATETIME COMMENT '线索产生时间', + lead_date DATE COMMENT '线索日期', + + -- 原始数据 + raw_data TEXT COMMENT '原始JSON数据', + + -- 数据采集 + sync_time DATETIME COMMENT '同步时间', + + -- 系统字段 + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + UNIQUE KEY uk_platform_lead (platform, platform_lead_id), + INDEX idx_mobile (mobile), + INDEX idx_company (company_name), + INDEX idx_campaign (campaign_id, lead_date), + INDEX idx_status (lead_status) +) COMMENT='广告线索数据原始表'; +``` + +--- + +## 四、数据映射规则 + +### 4.1 企业微信→标准模型映射 + +#### 4.1.1 外部联系人→联系人主表 + +| 目标字段(dwd_contact) | 来源字段(ods_wework_external_contact) | 映射逻辑 | +|---------------------|--------------------------------------|---------| +| cdp_id | - | 根据unionid或手机号查询或生成新ID | +| account_id | - | 根据corp_name查询或创建客户企业 | +| contact_name | name | 直接映射 | +| gender | gender | 1→MALE, 2→FEMALE, 0→UNKNOWN | +| avatar_url | avatar | 直接映射 | +| job_title | position | 直接映射 | +| department | - | 从corp_full_name中提取 | +| mobile_encrypted | remark_mobiles | 取第一个手机号,AES加密 | +| mobile_hash | remark_mobiles | 取第一个手机号,SHA256哈希 | +| relationship_status | - | 固定为 CONNECTED | +| primary_source_type | - | 固定为 WEWORK | +| primary_source_id | external_userid | 直接映射 | + +**映射SQL示例**: + +```sql +INSERT INTO dwd_contact ( + cdp_id, + account_id, + contact_name, + gender, + avatar_url, + job_title, + mobile_encrypted, + mobile_hash, + relationship_status, + primary_source_type, + primary_source_id, + create_time +) +SELECT + get_or_create_cdp_id(unionid, mobile) AS cdp_id, + get_or_create_account_id(corp_name) AS account_id, + name, + CASE gender + WHEN 1 THEN 'MALE' + WHEN 2 THEN 'FEMALE' + ELSE 'UNKNOWN' + END AS gender, + avatar, + position, + aes_encrypt(JSON_EXTRACT(remark_mobiles, '$[0]')) AS mobile_encrypted, + sha256(JSON_EXTRACT(remark_mobiles, '$[0]')) AS mobile_hash, + 'CONNECTED', + 'WEWORK', + external_userid, + NOW() +FROM ods_wework_external_contact +WHERE sync_time >= '2024-10-30 00:00:00'; +``` + +#### 4.1.2 聊天事件→行为事件表 + +| 目标字段(dwd_contact_event) | 来源字段(ods_wework_chat_event) | 映射逻辑 | +|----------------------------|--------------------------------|---------| +| event_id | event_id | 直接映射 | +| event_type | msgtype | "wework_chat_" + msgtype | +| event_time | msg_time | 直接映射 | +| event_date | event_date | 直接映射 | +| cdp_id | external_userid | 查询id_mapping表获取cdp_id | +| channel | - | 固定为 WEWORK | +| event_properties | content + raw_data | 组装JSON | +| source_type | - | 固定为 WEWORK | +| source_id | msgid | 直接映射 | + +--- + +### 4.2 CRM→标准模型映射 + +#### 4.2.1 CRM客户→客户企业表 + +| 目标字段(dwd_customer_account) | 来源字段(ods_crm_account) | 映射逻辑 | +|-------------------------------|--------------------------|---------| +| account_id | crm_account_id | 查询或生成CDP account_id | +| account_name | account_name | 直接映射 | +| industry | industry | 直接映射 | +| company_scale | employee_count | 按区间转换 | +| annual_revenue | annual_revenue | 转换为分(×100) | +| customer_type | customer_type | 映射枚举值 | +| customer_level | customer_level | 直接映射 | +| source_type | - | 固定为 CRM | +| source_id | crm_account_id | 直接映射 | + +#### 4.2.2 CRM联系人→联系人主表 + +| 目标字段(dwd_contact) | 来源字段(ods_crm_contact) | 映射逻辑 | +|---------------------|--------------------------|---------| +| cdp_id | - | 根据mobile/email查询或生成 | +| account_id | crm_account_id | 查询account映射 | +| contact_name | contact_name | 直接映射 | +| gender | gender | MALE/FEMALE/UNKNOWN | +| job_title | title | 直接映射 | +| department | department | 直接映射 | +| mobile_encrypted | mobile | AES加密 | +| mobile_hash | mobile | SHA256哈希 | +| email_encrypted | email | AES加密 | +| email_hash | email | SHA256哈希 | +| report_to_cdp_id | report_to_id | 查询联系人映射 | +| decision_role | decision_role | 直接映射 | +| primary_source_type | - | 固定为 CRM | +| primary_source_id | crm_contact_id | 直接映射 | + +#### 4.2.3 CRM活动→行为事件表 + +| 目标字段(dwd_contact_event) | 来源字段(ods_crm_activity) | 映射逻辑 | +|----------------------------|---------------------------|---------| +| event_id | activity_id | 直接映射 | +| event_type | activity_type | "crm_" + activity_type | +| event_time | activity_time | 直接映射 | +| event_date | activity_date | 直接映射 | +| cdp_id | crm_contact_id | 查询映射获取cdp_id | +| account_id | crm_account_id | 查询映射获取account_id | +| channel | - | 固定为 CRM | +| event_properties | activity_subject + activity_description | 组装JSON | + +--- + +### 4.3 广告→标准模型映射 + +#### 4.3.1 广告线索→联系人表 + +广告线索需要特殊处理,因为可能是全新的潜在客户。 + +```sql +-- Step 1: 创建或查询客户企业 +INSERT INTO dwd_customer_account (account_id, account_name, customer_type, ...) +SELECT + get_or_create_account_id(company_name), + company_name, + 'LEAD', -- 来自广告的都是潜在客户 + ... +FROM ods_ad_lead +WHERE lead_status = 'VALID'; + +-- Step 2: 创建或更新联系人 +INSERT INTO dwd_contact (cdp_id, account_id, contact_name, mobile_encrypted, ...) +SELECT + get_or_create_cdp_id_by_mobile(mobile), + get_account_id_by_name(company_name), + contact_name, + aes_encrypt(mobile), + ... +FROM ods_ad_lead +WHERE lead_status = 'VALID'; + +-- Step 3: 记录线索事件 +INSERT INTO dwd_contact_event (event_id, event_type, cdp_id, event_properties, ...) +SELECT + CONCAT('ad_lead_', lead_id), + 'ad_lead_submit', + get_cdp_id_by_mobile(mobile), + JSON_OBJECT( + 'platform', platform, + 'campaign_id', campaign_id, + 'campaign_name', campaign_name, + 'form_data', form_data + ), + ... +FROM ods_ad_lead; +``` + +#### 4.3.2 广告投放数据→汇总表 + +广告数据通常不需要映射到DWD明细层,直接在DWS汇总层使用。 + +```sql +-- 创建广告效果汇总表 +CREATE TABLE dws_ad_performance_daily ( + stat_date DATE, + platform VARCHAR(32), + campaign_id VARCHAR(128), + campaign_name VARCHAR(256), + impression_count INT, + click_count INT, + cost_amount BIGINT, + lead_count INT, + valid_lead_count INT, + ... +) COMMENT='广告效果日汇总表'; +``` + +--- + +## 五、扩展字段设计 + +### 5.1 扩展字段(extra_attributes)的使用 + +由于不同企业的业务需求差异较大,标准schema无法覆盖所有场景,因此设计了`extra_attributes`扩展字段。 + +#### 5.1.1 扩展字段结构 + +```json +{ + "custom_fields": { + "preferred_contact_time": "14:00-16:00", + "hobby": ["打篮球", "阅读"], + "wechat_remark": "重点客户" + }, + "integration_data": { + "salesforce_sync_time": "2024-10-30 12:00:00", + "external_system_id": "EXT_12345" + }, + "business_metrics": { + "last_order_amount": 50000, + "customer_lifetime_value": 200000 + } +} +``` + +#### 5.1.2 扩展字段查询 + +MySQL 5.7+ 支持JSON字段查询: + +```sql +-- 查询扩展字段 +SELECT + contact_name, + JSON_EXTRACT(extra_attributes, '$.custom_fields.hobby') AS hobby, + JSON_EXTRACT(extra_attributes, '$.business_metrics.customer_lifetime_value') AS clv +FROM dwd_contact +WHERE JSON_EXTRACT(extra_attributes, '$.custom_fields.preferred_contact_time') IS NOT NULL; + +-- 更新扩展字段 +UPDATE dwd_contact +SET extra_attributes = JSON_SET( + extra_attributes, + '$.custom_fields.wechat_remark', + 'VIP客户' +) +WHERE cdp_id = 'CDP_123456'; +``` + +### 5.2 行业特定字段扩展示例 + +#### 5.2.1 金融行业扩展 + +```json +{ + "financial_info": { + "risk_level": "LOW", + "credit_score": 750, + "aum": 5000000, + "investment_preference": ["股票", "基金"], + "kyc_status": "PASSED" + } +} +``` + +#### 5.2.2 教育行业扩展 + +```json +{ + "education_info": { + "student_count": 500, + "school_type": "K12", + "has_online_course": true, + "teaching_platform": "钉钉" + } +} +``` + +#### 5.2.3 制造业扩展 + +```json +{ + "manufacturing_info": { + "production_capacity": "10000台/月", + "main_products": ["工业机器人", "自动化设备"], + "certification": ["ISO9001", "ISO14001"], + "factory_count": 3 + } +} +``` + +--- + +## 六、Schema设计最佳实践 + +### 6.1 数据质量保障 + +1. **必填字段约束**: 关键字段设置NOT NULL约束 +2. **唯一性约束**: 为业务唯一键建立UNIQUE索引 +3. **外键关系**: 逻辑外键(不建物理外键,保证性能) +4. **默认值**: 为状态字段设置合理的默认值 +5. **枚举值校验**: 应用层校验枚举值的合法性 + +### 6.2 性能优化 + +1. **索引设计**: 为常用查询条件建立合适的索引 +2. **分区表**: 大表按日期分区(如事件表) +3. **冷热分离**: 历史数据归档,保持活跃表精简 +4. **宽表设计**: DWS层适当做宽表,减少JOIN +5. **缓存策略**: 热点数据缓存到Redis + +### 6.3 数据安全 + +1. **敏感字段加密**: 手机号、邮箱等AES加密存储 +2. **哈希索引**: 用哈希值做匹配和查询 +3. **权限控制**: 数据库层+应用层双重权限控制 +4. **审计日志**: 记录敏感数据的访问和修改 +5. **数据脱敏**: 非生产环境使用脱敏数据 + +### 6.4 可扩展性 + +1. **预留扩展字段**: 每个核心表预留extra_attributes +2. **版本管理**: Schema变更需要版本管理 +3. **兼容性**: 新增字段,不删除已有字段 +4. **平滑迁移**: 大表结构变更采用影子表方式 + +--- + +## 七、总结 + +### 7.1 Schema设计关键点 + +1. **分层清晰**: ODS保持原始/DWD标准统一/DWS面向应用 +2. **OneID核心**: 所有数据以CDP统一ID为中心 +3. **组织关系**: 支持复杂的企业组织架构 +4. **数据溯源**: 记录数据来源,支持追溯 +5. **可扩展性**: 通过JSON字段支持灵活扩展 + +### 7.2 下一步工作 + +1. **数据采集开发**: 开发各数据源的采集Connector +2. **ID-Mapping实现**: 实现OneID匹配算法 +3. **ETL开发**: 开发ODS→DWD→DWS的数据加工流程 +4. **数据质量监控**: 建立数据质量监控体系 +5. **性能优化**: 根据实际数据量进行性能调优 + +--- + +**文档版本**: v1.0 +**最后更新**: 2024-10-30 +**作者**: CDP数据团队