<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>用户分析 on My Learning Notes</title><link>https://eleanora-lyh.github.io/MyLearningNotes/tags/%E7%94%A8%E6%88%B7%E5%88%86%E6%9E%90/</link><description>Recent content in 用户分析 on My Learning Notes</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Wed, 02 Sep 2026 10:27:13 +0000</lastBuildDate><atom:link href="https://eleanora-lyh.github.io/MyLearningNotes/tags/%E7%94%A8%E6%88%B7%E5%88%86%E6%9E%90/index.xml" rel="self" type="application/rss+xml"/><item><title>【工作杂谈_20260815】用户分析与身份体系: CanonicalUserId：从用户标识到身份图谱</title><link>https://eleanora-lyh.github.io/MyLearningNotes/posts/work/useranalyticsidentity/20260815_%E7%94%A8%E6%88%B7%E5%88%86%E6%9E%90%E4%B8%8E%E8%BA%AB%E4%BB%BD%E4%BD%93%E7%B3%BB_canonicaluserid%E8%BA%AB%E4%BB%BD%E8%A7%A3%E6%9E%90/</link><pubDate>Sat, 15 Aug 2026 22:15:38 +0800</pubDate><guid>https://eleanora-lyh.github.io/MyLearningNotes/posts/work/useranalyticsidentity/20260815_%E7%94%A8%E6%88%B7%E5%88%86%E6%9E%90%E4%B8%8E%E8%BA%AB%E4%BB%BD%E4%BD%93%E7%B3%BB_canonicaluserid%E8%BA%AB%E4%BB%BD%E8%A7%A3%E6%9E%90/</guid><description>&lt;h1 id="1-先说结论canonicaluserid-到底是什么"&gt;1. 先说结论：CanonicalUserId 到底是什么
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;CanonicalUserId 不是行业统一标准字段，也不是天然存在于客户端的某个 ID。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更准确地说，它是身份解析系统根据一组用户标识及其关联证据，为某个业务实体生成或选定的&lt;strong&gt;内部主键&lt;/strong&gt;。它让下游不必分别使用 &lt;code&gt;user_id&lt;/code&gt;、&lt;code&gt;device_id&lt;/code&gt;、Cookie ID、手机号或第三方平台 ID，而是通过一个统一键查询该实体的事件、属性和关系。&lt;/p&gt;
&lt;p&gt;可以先记住下面这句话：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;CanonicalUserId 是身份解析的结果，不是身份解析的依据；它代表的是规则定义下的业务实体，不一定等于现实世界中的自然人。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;例如，系统收集到以下标识：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;anonymous_id = web_7f8a
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;device_id = ios_a91c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;account_id = user_1001
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;crm_id = crm_8872
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;经过可靠的登录、绑定或业务系统映射后，它们可能被归到：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;canonical_user_id = cu_01J5YQ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里的 &lt;code&gt;cu_01J5YQ...&lt;/code&gt; 通常只是一个不透明、稳定的内部代理键。它本身不包含手机号、邮箱等业务含义。&lt;/p&gt;
&lt;h2 id="11-第一个问题不是用哪个-id而是要统一什么实体"&gt;1.1 第一个问题不是“用哪个 ID”，而是“要统一什么实体”
&lt;/h2&gt;&lt;p&gt;“用户”在不同业务中可能指完全不同的对象：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;实体粒度&lt;/th&gt;
 &lt;th&gt;典型定义&lt;/th&gt;
 &lt;th&gt;适用场景&lt;/th&gt;
 &lt;th&gt;容易混淆的地方&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;自然人 Person&lt;/td&gt;
 &lt;td&gt;现实中的一个人&lt;/td&gt;
 &lt;td&gt;跨渠道客户经营、合规客户视图&lt;/td&gt;
 &lt;td&gt;很难仅凭设备和行为绝对确认&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;账号 Account&lt;/td&gt;
 &lt;td&gt;一个可登录账号&lt;/td&gt;
 &lt;td&gt;产品分析、权限、会员体系&lt;/td&gt;
 &lt;td&gt;一人可有多账号，家庭也可能共用账号&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;设备 Device&lt;/td&gt;
 &lt;td&gt;一次安装或浏览器实例&lt;/td&gt;
 &lt;td&gt;设备风控、推送、匿名分析&lt;/td&gt;
 &lt;td&gt;会重装、清 Cookie，也可能多人共用&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;会话 Session&lt;/td&gt;
 &lt;td&gt;一段连续访问&lt;/td&gt;
 &lt;td&gt;流量与访问路径分析&lt;/td&gt;
 &lt;td&gt;生命周期很短，不能代表长期用户&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;家庭 Household&lt;/td&gt;
 &lt;td&gt;一组家庭成员或共用地址&lt;/td&gt;
 &lt;td&gt;家庭订阅、电视、零售营销&lt;/td&gt;
 &lt;td&gt;不能直接替代自然人视图&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;企业/组织 Organization&lt;/td&gt;
 &lt;td&gt;公司、门店或租户&lt;/td&gt;
 &lt;td&gt;B2B SaaS、账号层分析&lt;/td&gt;
 &lt;td&gt;一个自然人可属于多个组织&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;因此，在建立 CanonicalUserId 之前必须先写清楚：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这个 ID 代表自然人、账号，还是设备？&lt;/li&gt;
&lt;li&gt;是否允许一个人对应多个账号？&lt;/li&gt;
&lt;li&gt;是否允许一个账号被多人共用？&lt;/li&gt;
&lt;li&gt;发生账号合并、手机号换绑时，历史如何处理？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于大多数产品行为分析，&lt;strong&gt;把“稳定业务账号”作为已登录用户实体，把匿名浏览器或 App 安装实例作为临时实体&lt;/strong&gt;，往往比宣称“已经识别出自然人”更准确。&lt;/p&gt;
&lt;h2 id="12-几个容易混用的概念"&gt;1.2 几个容易混用的概念
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;概念&lt;/th&gt;
 &lt;th&gt;含义&lt;/th&gt;
 &lt;th&gt;示例&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Identifier&lt;/td&gt;
 &lt;td&gt;外部系统产生的标识值&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;user_1001&lt;/code&gt;、&lt;code&gt;web_7f8a&lt;/code&gt;、手机号&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Namespace&lt;/td&gt;
 &lt;td&gt;标识所属的命名空间和语义&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;account_id&lt;/code&gt;、&lt;code&gt;anonymous_id&lt;/code&gt;、&lt;code&gt;crm_id&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Identity Edge&lt;/td&gt;
 &lt;td&gt;两个标识属于同一实体的证据&lt;/td&gt;
 &lt;td&gt;某设备成功登录了某账号&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Identity Graph&lt;/td&gt;
 &lt;td&gt;以标识为节点、关联证据为边的图&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;web_7f8a -&amp;gt; user_1001 &amp;lt;- ios_a91c&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Identity Resolution&lt;/td&gt;
 &lt;td&gt;根据规则合并、拒绝或拆分身份的过程&lt;/td&gt;
 &lt;td&gt;登录绑定、冲突检测、解绑&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;CanonicalUserId&lt;/td&gt;
 &lt;td&gt;解析后实体的稳定内部主键&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;cu_01J5YQ...&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;User Profile&lt;/td&gt;
 &lt;td&gt;以统一主键聚合出的属性和行为视图&lt;/td&gt;
 &lt;td&gt;会员等级、最近活跃时间、累计消费&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;One ID&lt;/code&gt;、&lt;code&gt;ID-Mapping&lt;/code&gt;、&lt;code&gt;Identity Graph&lt;/code&gt;、&lt;code&gt;Entity Resolution&lt;/code&gt; 经常在同一个话题中出现，但侧重点不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ID-Mapping&lt;/strong&gt; 强调标识之间如何建立映射。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identity Graph&lt;/strong&gt; 强调标识和实体之间的图关系。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entity Resolution&lt;/strong&gt; 范围更广，还可能根据姓名、地址、邮箱等进行规则或概率匹配。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CanonicalUserId / One ID&lt;/strong&gt; 强调最终供下游使用的统一主键。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="2-为什么需要身份归一"&gt;2. 为什么需要身份归一
&lt;/h1&gt;&lt;h2 id="21-一个用户为什么会产生多个标识"&gt;2.1 一个用户为什么会产生多个标识
&lt;/h2&gt;&lt;p&gt;假设同一个账号经历了下面的访问路径：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;时间&lt;/th&gt;
 &lt;th&gt;行为&lt;/th&gt;
 &lt;th&gt;当时可见的标识&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;T1&lt;/td&gt;
 &lt;td&gt;在浏览器匿名查看商品&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;anonymous_id=web_7f8a&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;T2&lt;/td&gt;
 &lt;td&gt;在该浏览器注册并登录&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;web_7f8a + account_id=user_1001&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;T3&lt;/td&gt;
 &lt;td&gt;在 iPhone App 匿名浏览&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;device_id=ios_a91c&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;T4&lt;/td&gt;
 &lt;td&gt;在 App 登录同一账号&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ios_a91c + account_id=user_1001&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;T5&lt;/td&gt;
 &lt;td&gt;在线下 CRM 完善资料&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;account_id=user_1001 + crm_id=crm_8872&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果只按原始标识计数，系统可能把它看成四个用户；如果利用 T2、T4、T5 的确定性关联，则可以得到：&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 W["anonymous_id:web_7f8a"] --&gt;|成功登录| A["account_id:user_1001"]
 D["device_id:ios_a91c"] --&gt;|成功登录| A
 C["crm_id:crm_8872"] --&gt;|业务主数据映射| A
 A --&gt; P["canonical_user_id:cu_01J5YQ"]&lt;/pre&gt;&lt;p&gt;身份归一真正解决的是：&lt;strong&gt;同一个业务实体在不同时间、终端和系统中留下了不同的键，而分析与服务需要一个连续视图。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="22-不做身份归一会怎样"&gt;2.2 不做身份归一会怎样
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;匿名浏览和注册事件分属两人，注册漏斗被截断。&lt;/li&gt;
&lt;li&gt;同一账号换设备后被重复计算，AU、留存和新增用户数偏高。&lt;/li&gt;
&lt;li&gt;广告点击、站内浏览和最终订单无法形成完整归因链路。&lt;/li&gt;
&lt;li&gt;客服、CRM、交易和行为数据无法拼成统一客户视图。&lt;/li&gt;
&lt;li&gt;已退订用户在另一个标识下仍被营销触达。&lt;/li&gt;
&lt;li&gt;风控系统看不到同一账号与多个设备、支付工具之间的关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不过，错误合并通常比漏合并更危险。漏合并会把一人看成多人；错误合并则可能把甲的画像、订单或营销授权给乙，既污染数据，也可能形成隐私和合规事故。&lt;/p&gt;
&lt;h2 id="23-为什么-user_id--device_id-不能成为统一用户键"&gt;2.3 为什么 &lt;code&gt;user_id + device_id&lt;/code&gt; 不能成为统一用户键
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;user_id + device_id&lt;/code&gt; 描述的是“某账号在某设备上的组合”，不是用户实体：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个账号登录三台设备，会产生三个组合键。&lt;/li&gt;
&lt;li&gt;同一设备先后登录两个账号，会产生两个组合键。&lt;/li&gt;
&lt;li&gt;匿名阶段没有 &lt;code&gt;user_id&lt;/code&gt;，组合键无法生成。&lt;/li&gt;
&lt;li&gt;清 Cookie、重装 App 或更换设备后，组合键会再次变化。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同样，下面这种写法也只能作为临时降级方案：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;COALESCE(user_id, device_id)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;匿名时它返回 &lt;code&gt;device_id&lt;/code&gt;，登录后却返回 &lt;code&gt;user_id&lt;/code&gt;，前后仍是两个用户。只有在身份解析已经建立 &lt;code&gt;device_id -&amp;gt; canonical_user_id&lt;/code&gt; 映射后，&lt;code&gt;COALESCE&lt;/code&gt; 才能用于选择解析结果或兜底标识。&lt;/p&gt;
&lt;h1 id="3-身份归一是怎样工作的"&gt;3. 身份归一是怎样工作的
&lt;/h1&gt;&lt;h2 id="31-把标识看成节点把证据看成边"&gt;3.1 把标识看成节点，把证据看成边
&lt;/h2&gt;&lt;p&gt;最直观的模型是图：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;节点：&lt;code&gt;(namespace, normalized_value)&lt;/code&gt;，例如 &lt;code&gt;(account_id, user_1001)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;边：两个节点属于同一实体的证据，例如“设备 D 在认证成功后登录账号 U”。&lt;/li&gt;
&lt;li&gt;连通实体：经过规则校验后可归并到同一 CanonicalUserId 的节点集合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为什么节点必须包含 Namespace？因为不同系统都可能出现值 &lt;code&gt;12345&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(crm_id, 12345) != (account_id, 12345) != (store_member_id, 12345)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一条生产可用的边也不能只有 &lt;code&gt;left_id&lt;/code&gt; 和 &lt;code&gt;right_id&lt;/code&gt;，至少还要能回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关系来自登录、人工绑定、CRM 导入，还是模型推断？&lt;/li&gt;
&lt;li&gt;哪个系统、哪条事件产生了这条关系？&lt;/li&gt;
&lt;li&gt;关系何时生效、何时失效？&lt;/li&gt;
&lt;li&gt;使用了哪个规则版本？&lt;/li&gt;
&lt;li&gt;能否撤销，发生冲突时如何重算？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="32-关联证据并不等价"&gt;3.2 关联证据并不等价
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;证据类型&lt;/th&gt;
 &lt;th&gt;示例&lt;/th&gt;
 &lt;th&gt;一般处理方式&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;强确定性证据&lt;/td&gt;
 &lt;td&gt;服务端确认账号登录、账号合并、主数据映射&lt;/td&gt;
 &lt;td&gt;可直接建立高可信边&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;中等确定性证据&lt;/td&gt;
 &lt;td&gt;已验证邮箱、已验证手机号&lt;/td&gt;
 &lt;td&gt;需考虑共享、回收、换绑和有效期&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;弱标识&lt;/td&gt;
 &lt;td&gt;Cookie、广告 ID、安装 ID、设备 ID&lt;/td&gt;
 &lt;td&gt;可辅助串联匿名行为，不应单独证明自然人相同&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;概率证据&lt;/td&gt;
 &lt;td&gt;姓名、地址、IP、User-Agent、行为相似度&lt;/td&gt;
 &lt;td&gt;输出候选或置信度，谨慎自动合并&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;产品行为分析通常优先采用&lt;strong&gt;确定性匹配&lt;/strong&gt;：只有同一事件或可信业务关系同时带出两个标识时才建边。跨 CRM 的客户去重可能使用规则或机器学习匹配，但必须保留分数、阈值和人工复核机制。&lt;/p&gt;
&lt;p&gt;需要特别注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;邮箱和手机号会变更、共享或被运营商回收，不是天然永久主键。&lt;/li&gt;
&lt;li&gt;IP 地址、机型和 User-Agent 的共现不能证明是同一人。&lt;/li&gt;
&lt;li&gt;对邮箱或手机号做哈希只是降低明文暴露，不会让错误数据变准确，也不自动满足匿名化要求。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="33-标识规范化先于匹配"&gt;3.3 标识规范化先于匹配
&lt;/h2&gt;&lt;p&gt;身份解析前通常需要进行标准化和质量校验：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;邮箱按业务规则处理大小写、空格和非法格式。&lt;/li&gt;
&lt;li&gt;手机号转换为带国家码的 E.164 格式。&lt;/li&gt;
&lt;li&gt;明确业务 ID 是否区分大小写，不应无条件转小写。&lt;/li&gt;
&lt;li&gt;拒绝 &lt;code&gt;null&lt;/code&gt;、&lt;code&gt;unknown&lt;/code&gt;、&lt;code&gt;-1&lt;/code&gt;、全零值等公共占位符。&lt;/li&gt;
&lt;li&gt;每个来源系统声明它能生产哪些 Namespace，以及这些值是否唯一。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果把公共占位符当成有效标识，数以万计的用户可能通过 &lt;code&gt;user_id=null&lt;/code&gt; 被合并成一个巨型身份簇，这类事故常被称为 &lt;strong&gt;Graph Collapse（图坍缩）&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="34-canonicaluserid-应该怎么生成"&gt;3.4 CanonicalUserId 应该怎么生成
&lt;/h2&gt;&lt;p&gt;常见方案有三种：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;方案&lt;/th&gt;
 &lt;th&gt;优点&lt;/th&gt;
 &lt;th&gt;风险与限制&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;直接使用业务 &lt;code&gt;user_id&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;简单、可读、容易关联业务库&lt;/td&gt;
 &lt;td&gt;账号迁移、跨租户、多账号合并时不稳定&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;平台选定某个已有 ID&lt;/td&gt;
 &lt;td&gt;无需额外生成主键&lt;/td&gt;
 &lt;td&gt;选择规则可能不可控，外部 ID 变化会影响使用&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;生成不透明内部 ID&lt;/td&gt;
 &lt;td&gt;与邮箱、设备、账号解耦，便于合并和版本管理&lt;/td&gt;
 &lt;td&gt;需要额外维护成员关系和重定向表&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;复杂系统通常更适合第三种方案：为 Profile 生成 UUID、ULID 或内部序列号，把所有外部标识作为成员挂到 Profile 下。&lt;/p&gt;
&lt;p&gt;当两个 Profile 合并时，不要批量修改所有下游事实表的主键。可以保留一个存活 ID，并记录重定向：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cu_old_02 -&amp;gt; cu_survivor_01
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;下游解析时沿重定向找到当前主 ID，同时仍能追溯历史上使用过的 ID。&lt;/p&gt;
&lt;h2 id="35-为什么不能直接对所有边求连通分量"&gt;3.5 为什么不能直接对所有边求连通分量
&lt;/h2&gt;&lt;p&gt;假设一台共享平板先后登录两个账号：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;account_A -- device_shared -- account_B
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果只使用“存在路径即同一人”的传递闭包，&lt;code&gt;account_A&lt;/code&gt; 和 &lt;code&gt;account_B&lt;/code&gt; 会被合并。这显然不合理：设备可以共享，而账号 ID 在当前业务中可能要求一个 Profile 最多只能有一个。&lt;/p&gt;
&lt;p&gt;生产系统会增加约束和保护规则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;唯一性约束&lt;/strong&gt;：一个 Profile 最多允许一个 &lt;code&gt;account_id&lt;/code&gt; 或 &lt;code&gt;crm_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标识优先级&lt;/strong&gt;：稳定账号 ID 高于邮箱，邮箱高于匿名 ID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数量与时间窗口&lt;/strong&gt;：限制一个 Profile 在一定时间内可关联的设备、邮箱或匿名 ID 数量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;来源可信度&lt;/strong&gt;：服务端认证关系高于客户端自报关系。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阻断值&lt;/strong&gt;：占位符、测试账号和已知异常值不能参与合并。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;冲突隔离&lt;/strong&gt;：规则无法判断时进入待处理队列，而不是强行归并。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可解绑与重算&lt;/strong&gt;：错误边失效后可以重新计算受影响的局部身份簇。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="36-确定性-id-mapping-与概率实体解析"&gt;3.6 确定性 ID-Mapping 与概率实体解析
&lt;/h2&gt;&lt;p&gt;两者解决的是相邻但不完全相同的问题：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;维度&lt;/th&gt;
 &lt;th&gt;确定性 ID-Mapping&lt;/th&gt;
 &lt;th&gt;概率 Entity Resolution&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;输入&lt;/td&gt;
 &lt;td&gt;登录关系、绑定关系、稳定业务 ID&lt;/td&gt;
 &lt;td&gt;姓名、地址、邮箱、电话等属性&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;判断&lt;/td&gt;
 &lt;td&gt;有明确证据才关联&lt;/td&gt;
 &lt;td&gt;根据规则或模型计算相似度&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;输出&lt;/td&gt;
 &lt;td&gt;绑定/不绑定&lt;/td&gt;
 &lt;td&gt;匹配组和置信度&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;典型场景&lt;/td&gt;
 &lt;td&gt;埋点、跨设备产品分析&lt;/td&gt;
 &lt;td&gt;多 CRM 去重、线下客户主数据整合&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;主要风险&lt;/td&gt;
 &lt;td&gt;埋点错误导致错误合并&lt;/td&gt;
 &lt;td&gt;阈值不当导致误匹配或漏匹配&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;第一次建设时，应该先把确定性的登录和绑定链路做好，再评估是否真的需要概率匹配。不要用 IP、设备指纹等弱信号偷偷“猜人”，然后把结果包装成确定的 CanonicalUserId。&lt;/p&gt;
&lt;h1 id="4-用完整用户旅程理解-canonicaluserid"&gt;4. 用完整用户旅程理解 CanonicalUserId
&lt;/h1&gt;&lt;h2 id="41-匿名浏览到登录"&gt;4.1 匿名浏览到登录
&lt;/h2&gt;&lt;p&gt;以 Mixpanel 的 &lt;strong&gt;Simplified ID Merge API&lt;/strong&gt; 为例，客户端 SDK 会先生成 &lt;code&gt;$device_id&lt;/code&gt;。调用 &lt;code&gt;identify(user_id)&lt;/code&gt; 后，后续事件会同时包含 &lt;code&gt;$device_id&lt;/code&gt; 和 &lt;code&gt;$user_id&lt;/code&gt;；当 Mixpanel 首次收到二者共存的事件时，会建立映射。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;mixpanel&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;identify&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;user_1001&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;mixpanel&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;track&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Login Succeeded&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方文档特别要求 &lt;code&gt;identify()&lt;/code&gt; 后至少发送一个事件，因为 Simplified API 是由同时包含 &lt;code&gt;$device_id&lt;/code&gt; 与 &lt;code&gt;$user_id&lt;/code&gt; 的事件触发合并，而不是仅凭本地函数调用完成服务端映射。&lt;/p&gt;
&lt;p&gt;在自己的数仓中，也应该保留两个层次：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;层次&lt;/th&gt;
 &lt;th&gt;保存内容&lt;/th&gt;
 &lt;th&gt;是否允许重写&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;原始事实&lt;/td&gt;
 &lt;td&gt;事件发生时实际携带的匿名 ID、账号 ID、时间和来源&lt;/td&gt;
 &lt;td&gt;不重写&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;解析结果&lt;/td&gt;
 &lt;td&gt;当前或指定版本下的 CanonicalUserId&lt;/td&gt;
 &lt;td&gt;可随规则重算&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这样既能用“当前映射”回看完整注册漏斗，也能用“事件发生时映射”复现历史报表。不同平台的“回溯合并”实现并不相同：有的平台在查询时应用映射，有的平台会更新分析索引；不能简单理解为所有历史原始事件都被物理改写。&lt;/p&gt;
&lt;h2 id="42-跨设备统一"&gt;4.2 跨设备统一
&lt;/h2&gt;&lt;p&gt;跨设备不是通过相似设备特征自动完成的，而是两个设备都出现了同一个可信账号标识：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;web_7f8a --登录--&amp;gt; user_1001
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ios_a91c --登录--&amp;gt; user_1001
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;于是二者可解析到同一个 CanonicalUserId。若 Mac 浏览器始终没有登录、绑定或其他可靠证据，它就应继续保持匿名。&lt;strong&gt;无法确认的身份不合并，是正确结果，不是系统缺陷。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="43-退出登录与共享设备"&gt;4.3 退出登录与共享设备
&lt;/h2&gt;&lt;p&gt;共享设备是最容易发生错误合并的场景。建议把以下状态变化写入统一的 SDK 规范：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登录成功后设置稳定账号 ID，并发送一条成功事件。&lt;/li&gt;
&lt;li&gt;退出或认证超时后清理本地账号身份。&lt;/li&gt;
&lt;li&gt;当使用者可能变化时，生成新的匿名 ID 或会话作用域 ID。&lt;/li&gt;
&lt;li&gt;不要把硬件设备 ID 永久等同于最近一次登录账号。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;reset()&lt;/code&gt; 的具体语义是厂商和版本相关的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mixpanel 当前 Simplified API 文档建议在退出或认证超时时调用 &lt;code&gt;.reset()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Mixpanel Original API 文档为了避免频繁增加身份簇成员，讨论了只在明确切换使用者时 reset 的策略。&lt;/li&gt;
&lt;li&gt;Amplitude 要显式匿名化时，建议把 User ID 设为 &lt;code&gt;null&lt;/code&gt;，同时生成新的 Device ID；否则后续匿名事件可能继续归到该设备上最后一个已知用户。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，不能总结成“退出一定 reset”或“普通退出永远不 reset”。正确做法是先确认所用 SDK 版本，再根据共享设备、匿名期归因和身份簇限制设计状态机。&lt;/p&gt;
&lt;h2 id="44-账号合并解绑与手机号回收"&gt;4.4 账号合并、解绑与手机号回收
&lt;/h2&gt;&lt;p&gt;真实系统还会遇到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户把两个业务账号申请合并。&lt;/li&gt;
&lt;li&gt;客服误绑账号后需要撤销。&lt;/li&gt;
&lt;li&gt;手机号从用户 A 换绑，并在未来被用户 B 使用。&lt;/li&gt;
&lt;li&gt;企业客户更换 CRM，主数据 ID 被重新编码。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这说明映射不是静态字典，而是带时间和版本的关系：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(phone, +86138...) -&amp;gt; account_A [2025-01-01, 2026-03-01)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(phone, +86138...) -&amp;gt; account_B [2026-07-01, ...)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;解绑不应删除原始事件和审计记录，而应使关系在某个时间点失效，并重新计算受影响的 Profile。对历史报表，还要明确使用“当时身份”还是“当前最新身份”。&lt;/p&gt;
&lt;h2 id="45-canonicaluserid-能支持哪些应用"&gt;4.5 CanonicalUserId 能支持哪些应用
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;应用&lt;/th&gt;
 &lt;th&gt;CanonicalUserId 的作用&lt;/th&gt;
 &lt;th&gt;仍需额外定义的规则&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;AU、留存&lt;/td&gt;
 &lt;td&gt;跨设备去重同一用户&lt;/td&gt;
 &lt;td&gt;活跃事件、时间窗口、实体粒度&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;注册漏斗&lt;/td&gt;
 &lt;td&gt;串联注册前匿名行为与注册后行为&lt;/td&gt;
 &lt;td&gt;转化窗口、匿名行为归属策略&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;渠道归因&lt;/td&gt;
 &lt;td&gt;连接广告点击、站内行为和订单&lt;/td&gt;
 &lt;td&gt;First-touch、Last-touch 等归因模型&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;用户画像&lt;/td&gt;
 &lt;td&gt;汇总 CRM、交易和行为属性&lt;/td&gt;
 &lt;td&gt;属性优先级、有效期、冲突规则&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;营销触达&lt;/td&gt;
 &lt;td&gt;跨渠道去重、退订和频控&lt;/td&gt;
 &lt;td&gt;授权、同意状态、渠道可达性&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;风控&lt;/td&gt;
 &lt;td&gt;发现账号、设备、支付工具之间的关系&lt;/td&gt;
 &lt;td&gt;风险边、图遍历、模型和人工审核&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;CanonicalUserId 只解决“这些记录当前应归到哪个实体”。它不会自动解决指标口径、归因模型、画像属性冲突和隐私授权。&lt;/p&gt;
&lt;h1 id="5-从旧方案到身份图谱"&gt;5. 从旧方案到身份图谱
&lt;/h1&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;方案&lt;/th&gt;
 &lt;th&gt;能解决什么&lt;/th&gt;
 &lt;th&gt;主要问题&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;只用 &lt;code&gt;device_id&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;匿名设备内连续访问&lt;/td&gt;
 &lt;td&gt;换设备、清 Cookie、共享设备都会失真&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;只用 &lt;code&gt;user_id&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;已登录账号分析&lt;/td&gt;
 &lt;td&gt;注册前行为丢失，未登录用户不可见&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;COALESCE(user_id, device_id)&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;为每条事件临时选一个非空键&lt;/td&gt;
 &lt;td&gt;登录前后仍是两个实体&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;拼接 &lt;code&gt;user_id + device_id&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;标识账号和设备的组合&lt;/td&gt;
 &lt;td&gt;一人多设备会被拆分，匿名期无法表示&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;单行 &lt;code&gt;user_id -&amp;gt; device_id&lt;/code&gt; 映射&lt;/td&gt;
 &lt;td&gt;最简单的一对一关联&lt;/td&gt;
 &lt;td&gt;无法表示多设备、多个 Namespace、历史和解绑&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;节点、边、Profile 模型&lt;/td&gt;
 &lt;td&gt;多标识、可追溯、可合并和拆分&lt;/td&gt;
 &lt;td&gt;需要规则治理、版本管理和质量监控&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;并不是所有公司都必须一开始就建设图平台：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;产品只允许登录后使用，而且 &lt;code&gt;user_id&lt;/code&gt; 全局稳定时，直接使用 &lt;code&gt;user_id&lt;/code&gt; 已经足够。&lt;/li&gt;
&lt;li&gt;需要串联注册前后行为时，增加 &lt;code&gt;anonymous_id -&amp;gt; user_id&lt;/code&gt; 的确定性映射即可。&lt;/li&gt;
&lt;li&gt;需要跨 CRM、多渠道、绑定/解绑和共享设备治理时，才需要完整 Identity Graph。&lt;/li&gt;
&lt;li&gt;需要根据姓名、地址等模糊属性匹配时，再引入 Entity Resolution。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;复杂度应该由真实业务问题推动，而不是因为“CanonicalUserId”听起来高级就先造一套大系统。&lt;/p&gt;
&lt;h1 id="6-如何在自己的数据平台中落地"&gt;6. 如何在自己的数据平台中落地
&lt;/h1&gt;&lt;h2 id="61-先写-identity-contract"&gt;6.1 先写 Identity Contract
&lt;/h2&gt;&lt;p&gt;在建表和写 Flink 任务之前，先由产品、账号、数据、隐私和安全团队共同确认一份身份契约：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CanonicalUserId 代表什么实体，在哪些租户和业务域内唯一？&lt;/li&gt;
&lt;li&gt;有哪些 Namespace，格式、大小写和标准化规则是什么？&lt;/li&gt;
&lt;li&gt;哪些标识是强标识，哪些可能共享或回收？&lt;/li&gt;
&lt;li&gt;哪些事件可以创建绑定，客户端自报是否可信？&lt;/li&gt;
&lt;li&gt;一个 Profile 允许出现多少个同类标识？&lt;/li&gt;
&lt;li&gt;冲突时按来源、时间还是人工结果决定？&lt;/li&gt;
&lt;li&gt;合并和拆分是否需要回算历史，保留多久？&lt;/li&gt;
&lt;li&gt;哪些标识属于 PII，谁可以查询和导出？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;规则不明确时，技术系统只会更快地产生不明确的结果。&lt;/p&gt;
&lt;h2 id="62-推荐的数据模型"&gt;6.2 推荐的数据模型
&lt;/h2&gt;&lt;p&gt;一行同时放 &lt;code&gt;canonical_user_id + user_id + device_id&lt;/code&gt; 无法表达一对多、来源、有效期和解绑。更可扩展的模型至少包含以下几类表：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;12
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;13
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;14
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;15
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;16
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;17
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;18
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;19
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;20
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;21
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;22
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;23
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;24
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;25
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;26
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;27
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;28
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;29
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;30
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;31
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;32
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;33
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;34
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;35
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;36
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;37
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;38
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;39
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;40
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;41
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;42
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;43
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;44
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;45
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;46
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;47
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;48
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; identity_node (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node_id BIGINT &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; namespace VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; identifier_token VARCHAR(&lt;span style="color:#ae81ff"&gt;128&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pii_class VARCHAR(&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; first_seen_at &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; last_seen_at &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;UNIQUE&lt;/span&gt; (namespace, identifier_token)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; identity_edge (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; edge_id BIGINT &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; left_node_id BIGINT &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; right_node_id BIGINT &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; evidence_type VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; source_system VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; source_event_id VARCHAR(&lt;span style="color:#ae81ff"&gt;128&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; confidence DECIMAL(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; valid_from &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; valid_to &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status VARCHAR(&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rule_version VARCHAR(&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; canonical_profile (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; canonical_user_id VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; entity_type VARCHAR(&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; profile_status VARCHAR(&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; created_at &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; updated_at &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; profile_membership (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; node_id BIGINT &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; canonical_user_id VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; valid_from &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; valid_to &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mapping_version BIGINT &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; is_current BOOLEAN &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt; (node_id, canonical_user_id, mapping_version)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TABLE&lt;/span&gt; profile_redirect (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; retired_user_id VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; survivor_user_id VARCHAR(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reason VARCHAR(&lt;span style="color:#ae81ff"&gt;128&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; created_at &lt;span style="color:#66d9ef"&gt;TIMESTAMP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NOT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中 &lt;code&gt;identifier_token&lt;/code&gt; 可以是受控的内部 Token，或由密钥保护的 HMAC。普通无盐哈希仍容易遭受邮箱、手机号字典枚举，不能替代访问控制和加密。&lt;/p&gt;
&lt;h2 id="63-数据处理链路"&gt;6.3 数据处理链路
&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 S["Web / App / Server / CRM"] --&gt; R["不可变原始事件"]
 R --&gt; N["Namespace 校验与标准化"]
 N --&gt; Q{"质量与冲突检查"}
 Q --&gt;|通过| E["Identity Edge Ledger"]
 Q --&gt;|异常| X["隔离与人工处理"]
 E --&gt; G["Identity Resolution Engine"]
 G --&gt; H["当前映射 + 历史版本"]
 H --&gt; K["在线 KV / Profile API"]
 H --&gt; W["数仓宽表 / BI / 标签"]
 G --&gt; A["合并决策与审计日志"]&lt;/pre&gt;&lt;p&gt;核心原则是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原始事件保持不可变。&lt;/li&gt;
&lt;li&gt;标识关系采用追加式事实和有效期，而不是直接覆盖。&lt;/li&gt;
&lt;li&gt;当前映射和历史映射同时保留。&lt;/li&gt;
&lt;li&gt;在线服务与离线分析可以共享规则，但使用不同的物化形式。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="64-一次解析决策的基本步骤"&gt;6.4 一次解析决策的基本步骤
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1. 从事件中提取所有已声明的 Namespace 和标识值
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2. 标准化并过滤空值、占位符、测试值和非法格式
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3. 查找每个标识当前所属的 Profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;4. 若均未命中，创建新 Profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;5. 若只命中一个，检查数量和唯一性约束后添加成员
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;6. 若命中多个，按证据、来源和优先级判断是否允许合并
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;7. 冲突时拒绝该边或进入隔离队列
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8. 记录决策、规则版本和来源事件
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;9. 更新受影响 Profile 的成员关系和在线缓存
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;登录关系最好由服务端认证成功事件确认，而不是完全信任客户端传来的任意 &lt;code&gt;user_id&lt;/code&gt;。否则攻击者或埋点错误可能把一个设备绑定到其他账号。&lt;/p&gt;
&lt;h2 id="65-合并容易拆分更难"&gt;6.5 合并容易，拆分更难
&lt;/h2&gt;&lt;p&gt;Union-Find（并查集）非常适合只增加边的离线合并，但不擅长删除边。一旦发生误绑或手机号回收，需要拆分身份簇时，单纯并查集很难恢复原关系。&lt;/p&gt;
&lt;p&gt;可撤销系统通常会：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;保留不可变的边和决策日志。&lt;/li&gt;
&lt;li&gt;将错误边标记为失效，而不是物理删除。&lt;/li&gt;
&lt;li&gt;从受影响连通子图重新计算 Profile。&lt;/li&gt;
&lt;li&gt;生成新的 Membership 版本。&lt;/li&gt;
&lt;li&gt;通过 Redirect 或变更日志通知下游更新。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这也是为什么“支持解绑”不是多写一个 &lt;code&gt;DELETE&lt;/code&gt; 接口，而是一项涉及历史、缓存、画像、分群和下游导出的系统能力。&lt;/p&gt;
&lt;h2 id="66-实时链路与离线链路"&gt;6.6 实时链路与离线链路
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;链路&lt;/th&gt;
 &lt;th&gt;目标&lt;/th&gt;
 &lt;th&gt;常见实现&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;实时解析&lt;/td&gt;
 &lt;td&gt;登录后立即拿到统一 Profile，用于个性化和风控&lt;/td&gt;
 &lt;td&gt;Kafka/Flink + KV/缓存 + 规则服务&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;离线重算&lt;/td&gt;
 &lt;td&gt;处理迟到数据、规则升级、合并和拆分&lt;/td&gt;
 &lt;td&gt;Spark/Hive/图计算 + 版本化结果表&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;在线查询&lt;/td&gt;
 &lt;td&gt;按任一标识查当前 CanonicalUserId&lt;/td&gt;
 &lt;td&gt;Profile API、KV 索引&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;历史分析&lt;/td&gt;
 &lt;td&gt;按当前映射或 As-of 映射统计&lt;/td&gt;
 &lt;td&gt;数仓 Membership 快照或 SCD2 表&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;CanonicalUserId 不等于必须使用图数据库。若主要查询是“给定 ID 找 Profile”，关系表加 KV 索引通常已经足够；只有在风控等场景需要多跳关系遍历、路径查询和高扇出分析时，图数据库的价值才明显。&lt;/p&gt;
&lt;h2 id="67-必须监控什么"&gt;6.7 必须监控什么
&lt;/h2&gt;&lt;p&gt;建议至少监控：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;匿名事件占比、已解析事件占比和映射延迟。&lt;/li&gt;
&lt;li&gt;每种 Namespace 的空值率、非法率和阻断值命中率。&lt;/li&gt;
&lt;li&gt;每日新增边、合并、拒绝、冲突和解绑数量。&lt;/li&gt;
&lt;li&gt;Profile 成员数、设备数的 P95/P99 与最大值。&lt;/li&gt;
&lt;li&gt;超大连通分量数量，是否出现单点异常增长。&lt;/li&gt;
&lt;li&gt;同一 Profile 包含多个唯一账号 ID 的违规数量。&lt;/li&gt;
&lt;li&gt;使用身份归一前后的 DAU、漏斗和留存变化。&lt;/li&gt;
&lt;li&gt;规则版本发布后被重分配的事件和 Profile 数量。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上线前应覆盖以下测试：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;场景&lt;/th&gt;
 &lt;th&gt;预期结果&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;同一账号登录两台设备&lt;/td&gt;
 &lt;td&gt;两台设备可解析到同一账号 Profile&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;两个账号先后使用共享设备&lt;/td&gt;
 &lt;td&gt;两个账号不被设备节点合并&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;退出后新用户注册&lt;/td&gt;
 &lt;td&gt;新用户的匿名行为不归到旧账号&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;手机号换绑或回收&lt;/td&gt;
 &lt;td&gt;新旧有效期正确，历史可追溯&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;user_id=null&lt;/code&gt; 或测试占位值&lt;/td&gt;
 &lt;td&gt;不参与合并并触发告警&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;错误绑定后解绑&lt;/td&gt;
 &lt;td&gt;受影响身份簇可拆分并生成新版本&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;迟到登录事件到达&lt;/td&gt;
 &lt;td&gt;当前视图更新，原始事件保持不变&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="68-隐私和安全不是附加项"&gt;6.8 隐私和安全不是附加项
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;只采集业务确实需要的标识，并记录用途和同意状态。&lt;/li&gt;
&lt;li&gt;PII 与普通分析字段分层存储，使用加密、Tokenization 和最小权限。&lt;/li&gt;
&lt;li&gt;不把邮箱、手机号直接编码进 CanonicalUserId。&lt;/li&gt;
&lt;li&gt;Profile API 只允许服务端访问，避免在客户端暴露可枚举的身份查询能力。&lt;/li&gt;
&lt;li&gt;删除请求需要传播到节点、Profile、画像、导出和备份策略中。&lt;/li&gt;
&lt;li&gt;跨地区、跨产品合并前确认数据驻留和用途限制。&lt;/li&gt;
&lt;li&gt;概率匹配结果必须可解释、可申诉，不能直接用于高风险自动决策。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="7-主流平台和大规模系统的公开实现"&gt;7. 主流平台和大规模系统的公开实现
&lt;/h1&gt;&lt;p&gt;以下内容基于截至 &lt;strong&gt;2026-08-21&lt;/strong&gt; 可访问的官方文档。各平台解决的问题和术语并不完全相同，不能把某一家的实现直接当成行业标准。&lt;/p&gt;
&lt;h2 id="71-mixpanel产品分析中的事件流拼接"&gt;7.1 Mixpanel：产品分析中的事件流拼接
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://docs.mixpanel.com/docs/tracking-methods/id-management/identifying-users-simplified" target="_blank" rel="noopener"
 &gt;Mixpanel Simplified ID Merge&lt;/a&gt; 使用 &lt;code&gt;$device_id&lt;/code&gt; 和 &lt;code&gt;$user_id&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;匿名事件只有 &lt;code&gt;$device_id&lt;/code&gt; 时，以设备标识作为 &lt;code&gt;distinct_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;首次收到同时包含 &lt;code&gt;$device_id&lt;/code&gt; 与 &lt;code&gt;$user_id&lt;/code&gt; 的事件时创建身份簇。&lt;/li&gt;
&lt;li&gt;Simplified API 中 canonical &lt;code&gt;distinct_id&lt;/code&gt; 固定为 &lt;code&gt;$user_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;可以用簇内任一 ID 写入，但查询和导出使用 canonical ID。&lt;/li&gt;
&lt;li&gt;Simplified API 不允许合并两个不同的 &lt;code&gt;$user_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;官方建议在退出或认证超时时调用 &lt;code&gt;.reset()&lt;/code&gt;，避免共享设备误合并。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://docs.mixpanel.com/docs/tracking-methods/id-management/identifying-users-original" target="_blank" rel="noopener"
 &gt;Mixpanel Original ID Merge&lt;/a&gt; 则不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$identify&lt;/code&gt; 只接受 UUIDv4 匿名 ID，且该匿名 ID 不能已属于其他 identified ID。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$merge&lt;/code&gt; 可以合并任意两个 ID，但身份簇不能超过 500 个 ID。&lt;/li&gt;
&lt;li&gt;canonical &lt;code&gt;distinct_id&lt;/code&gt; 由平台从簇内选择，未必是业务 &lt;code&gt;user_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Original 文档对 &lt;code&gt;reset()&lt;/code&gt; 的建议也更偏向“明确要切换使用者时再调用”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原文将 UUIDv4、500-ID 上限、canonical 选择和 Simplified 流程写在了一起，实际上这些约束分属不同版本。&lt;/p&gt;
&lt;h2 id="72-amplitude生成内部-amplitude-id"&gt;7.2 Amplitude：生成内部 Amplitude ID
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://amplitude.com/docs/data/sources/instrument-track-unique-users" target="_blank" rel="noopener"
 &gt;Amplitude 的唯一用户文档&lt;/a&gt; 描述了三层标识：Device ID、User ID 和平台生成的 Amplitude ID。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;匿名事件先按 Device ID 获得 Amplitude ID。&lt;/li&gt;
&lt;li&gt;同一设备后来出现 User ID 时，匿名事件可与已识别用户合并。&lt;/li&gt;
&lt;li&gt;同一 User ID 出现在多个设备上时，平台优先按 User ID 归一。&lt;/li&gt;
&lt;li&gt;Amplitude 不能合并两个不同的 User ID；更换 User ID 会被视为不同用户。&lt;/li&gt;
&lt;li&gt;共享设备上的后续匿名事件默认归给最后一个已知用户，除非将 User ID 设为 &lt;code&gt;null&lt;/code&gt; 并生成新的 Device ID。&lt;/li&gt;
&lt;li&gt;合并映射会在分析查询中生效，但导出到 Redshift 的原始事件不可变，使用原始数据计算 DAU 可能与平台界面不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个例子很好地说明了“统一查询视图”和“改写原始事件”不是同一回事。&lt;/p&gt;
&lt;h2 id="73-segment-unify持久-id-加合并保护"&gt;7.3 Segment Unify：持久 ID 加合并保护
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://www.twilio.com/docs/segment/unify/identity-resolution/" target="_blank" rel="noopener"
 &gt;Twilio Segment Unify&lt;/a&gt; 将 Cookie、设备、邮箱、&lt;code&gt;userId&lt;/code&gt; 和自定义 External ID 连接到一个持久内部 ID，并公开了比较完整的治理规则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新事件匹配零个 Profile 时创建，匹配一个时追加，匹配多个时尝试合并。&lt;/li&gt;
&lt;li&gt;可为标识设置阻断值、数量限制和优先级。&lt;/li&gt;
&lt;li&gt;默认 &lt;code&gt;user_id&lt;/code&gt; 限制为一个，其他标识默认允许多个。&lt;/li&gt;
&lt;li&gt;高优先级稳定 ID 可以阻止低优先级邮箱或匿名 ID 把两个账号错误合并。&lt;/li&gt;
&lt;li&gt;Merge Protection 专门处理共享设备、公共匿名 ID 等问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Segment 不只是“收集后转发数据的管道”。它的 Connections 偏采集和路由，而 Unify 提供 Identity Resolution、Profile 和受众能力，两者要分层理解。&lt;/p&gt;
&lt;h2 id="74-adobe-experience-platform防止-graph-collapse"&gt;7.4 Adobe Experience Platform：防止 Graph Collapse
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://experienceleague.adobe.com/en/docs/experience-platform/identity/features/identity-graph-linking-rules/overview" target="_blank" rel="noopener"
 &gt;Adobe Identity Graph Linking Rules&lt;/a&gt; 将生产级保护明确抽象为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unique Namespace&lt;/strong&gt;：一个身份图中某类标识最多只能有一个，例如 CRMID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Namespace Priority&lt;/strong&gt;：冲突时稳定账号标识优先于设备或浏览器标识。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identity Optimization Algorithm&lt;/strong&gt;：违反唯一性约束时重放边，并移除导致两个 Person 合并的低优先级关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在共享平板上先后登录两个 CRMID 时，Adobe 不会简单通过共同 ECID 把两人合并，而会拆成两个图。公开文档中的默认匿名归属采用“最后一个已认证用户”逻辑，这也再次说明“匿名行为归第一个用户”不是行业通则。&lt;/p&gt;
&lt;h2 id="75-神策-id-mapping-30显式-id-key-与绑定解绑"&gt;7.5 神策 ID-Mapping 3.0：显式 ID Key 与绑定/解绑
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://manual.sensorsdata.cn/sa/docs/idm_sdk_intro/v0204" target="_blank" rel="noopener"
 &gt;神策全域用户关联文档&lt;/a&gt; 的公开机制包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;预先定义参与关联的 ID Key，明确手机号、邮箱、OpenID 等标识语义。&lt;/li&gt;
&lt;li&gt;事件包含未定义的 ID Key 时拒绝入库，避免含义不明的标识进入图谱。&lt;/li&gt;
&lt;li&gt;客户端通过 &lt;code&gt;loginWithKey&lt;/code&gt;、&lt;code&gt;bind&lt;/code&gt;、&lt;code&gt;unbind&lt;/code&gt; 建立或解除关系。&lt;/li&gt;
&lt;li&gt;客户端绑定结果会进入本地缓存，后续事件携带相关 ID 信息。&lt;/li&gt;
&lt;li&gt;服务端 SDK 发送绑定事件，但不会把绑定 ID 持久化到服务端 SDK 本地状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;神策公开的&lt;a class="link" href="https://www.sensorsdata.cn/blog/20220518" target="_blank" rel="noopener"
 &gt;全域用户关联服务&lt;/a&gt;还强调来源可信度差异、历史数据治理以及手机号等标识发生变更时的绑定和解绑。这比“一台设备的匿名行为永远给首个登录用户”更接近真实治理过程。&lt;/p&gt;
&lt;h2 id="76-aws-entity-resolution规则机器学习与匹配组"&gt;7.6 AWS Entity Resolution：规则、机器学习与匹配组
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://docs.aws.amazon.com/entityresolution/latest/userguide/what-is-service.html" target="_blank" rel="noopener"
 &gt;AWS Entity Resolution&lt;/a&gt; 更接近跨数据源实体解析，而不是客户端埋点 SDK：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对输入进行 Schema Mapping 和标准化。&lt;/li&gt;
&lt;li&gt;支持基于规则、机器学习和数据供应商的匹配流程。&lt;/li&gt;
&lt;li&gt;规则匹配输出命中的规则编号，机器学习匹配输出 0 到 1 的置信度。&lt;/li&gt;
&lt;li&gt;支持批处理、规则场景的增量处理，以及通过 &lt;code&gt;GetMatchId&lt;/code&gt; 进行近实时查找。&lt;/li&gt;
&lt;li&gt;ID Mapping Workflow 可把 Source Namespace 翻译到 Target Namespace。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它说明了当问题从“登录前后是否同一账号”扩展到“两个 CRM 记录是否属于同一客户”时，系统需要标准化、匹配规则、置信度和工作流，而不只是 &lt;code&gt;identify()&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="77-airbnb大规模关系图基础设施"&gt;7.7 Airbnb：大规模关系图基础设施
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://airbnb.tech/infrastructure/scaling-airbnbs-identity-graph-with-a-unified-knowledge-graph-infrastructure/" target="_blank" rel="noopener"
 &gt;Airbnb 公开的 Identity Graph 架构&lt;/a&gt;主要服务 Trust &amp;amp; Safety，不等同于产品分析中的 CanonicalUserId，但展示了大厂在多跳关系查询下的实现方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图中约有 70 亿节点、110 亿条边，每天增加约 500 万条边。&lt;/li&gt;
&lt;li&gt;大部分数据通过异步事件近实时写入，在线服务进行低延迟查询。&lt;/li&gt;
&lt;li&gt;存储采用 JanusGraph + DynamoDB，OpenSearch 建索引，前面还有 KV 缓存。&lt;/li&gt;
&lt;li&gt;典型查询需要 4 到 8 跳，重点处理高扇出、长尾延迟和稳定性。&lt;/li&gt;
&lt;li&gt;通过事件写入、批量加载、在线服务和复杂查询预计算等多个应用分离读写职责。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个案例的启示不是“做 CanonicalUserId 必须上 JanusGraph”，而是：当需求从单跳 ID 映射升级为账号、设备、支付工具和风险关系的多跳遍历时，图存储、缓存、预计算和查询治理才会成为核心问题。&lt;/p&gt;
&lt;h2 id="78-这些公开实现的共同模式"&gt;7.8 这些公开实现的共同模式
&lt;/h2&gt;&lt;p&gt;尽管产品不同，它们大体都在做以下几件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为标识声明类型和语义，而不是只存一个字符串。&lt;/li&gt;
&lt;li&gt;以登录、绑定、主数据或匹配结果作为关联证据。&lt;/li&gt;
&lt;li&gt;使用内部 Profile ID 或 canonical ID 隔离外部标识变化。&lt;/li&gt;
&lt;li&gt;为共享设备、公共值和异常高扇出设置合并保护。&lt;/li&gt;
&lt;li&gt;保留原始数据，通过映射层提供当前统一视图。&lt;/li&gt;
&lt;li&gt;支持冲突检测、解绑、版本或局部重算。&lt;/li&gt;
&lt;li&gt;同时服务实时 Profile 查询和离线分析。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="8-一条适合从零开始的建设路径"&gt;8. 一条适合从零开始的建设路径
&lt;/h1&gt;&lt;h2 id="81-第一阶段只解决匿名到登录"&gt;8.1 第一阶段：只解决匿名到登录
&lt;/h2&gt;&lt;p&gt;最小可用方案不需要图数据库：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;业务账号使用永不复用的数据库 ID，不用邮箱作为 &lt;code&gt;user_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Web/App 为匿名访问生成随机 &lt;code&gt;anonymous_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;每条事件保留事件发生时的 &lt;code&gt;anonymous_id&lt;/code&gt; 和可选 &lt;code&gt;account_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;只有认证成功事件可以建立二者的确定性边。&lt;/li&gt;
&lt;li&gt;数仓生成 &lt;code&gt;anonymous_id -&amp;gt; canonical_user_id&lt;/code&gt; 的当前映射。&lt;/li&gt;
&lt;li&gt;原始事件不改写，分析层按映射版本补充 CanonicalUserId。&lt;/li&gt;
&lt;li&gt;先覆盖同设备注册、跨设备登录、退出和共享设备测试。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这一阶段已经能改善注册漏斗、跨设备 AU 和留存。&lt;/p&gt;
&lt;h2 id="82-第二阶段增加多来源标识与治理"&gt;8.2 第二阶段：增加多来源标识与治理
&lt;/h2&gt;&lt;p&gt;当 CRM、小程序、门店和客服系统接入后，再增加：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Namespace 注册表和标准化规则。&lt;/li&gt;
&lt;li&gt;来源可信度、唯一性、数量和时间窗口约束。&lt;/li&gt;
&lt;li&gt;Edge Ledger、Profile Membership 和 Redirect 表。&lt;/li&gt;
&lt;li&gt;冲突隔离、解绑、局部重算和审计界面。&lt;/li&gt;
&lt;li&gt;当前视图与 As-of 历史视图。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="83-第三阶段按需要增加实时和概率能力"&gt;8.3 第三阶段：按需要增加实时和概率能力
&lt;/h2&gt;&lt;p&gt;只有在业务需要实时个性化或风控时，才把解析结果同步到 KV/Profile API；只有在缺少确定性键、确实需要跨系统客户去重时，才引入规则评分或机器学习匹配。&lt;/p&gt;
&lt;p&gt;可以用下面的决策表控制复杂度：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;当前问题&lt;/th&gt;
 &lt;th&gt;建议方案&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;产品必须登录才能使用&lt;/td&gt;
 &lt;td&gt;直接使用稳定 &lt;code&gt;user_id&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;需要分析注册前后的行为&lt;/td&gt;
 &lt;td&gt;匿名 ID + 确定性登录映射&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;多终端、多 CRM、需要解绑&lt;/td&gt;
 &lt;td&gt;版本化 Identity Graph&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;姓名地址相似但无共同 ID&lt;/td&gt;
 &lt;td&gt;Entity Resolution + 置信度&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;风控需要多跳关系查询&lt;/td&gt;
 &lt;td&gt;图数据库、缓存与预计算&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="9-对原文几个结论的集中修正"&gt;9. 对原文几个结论的集中修正
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;**CanonicalUserId 不保证对应唯一自然人。**它对应的是业务定义和规则版本下的实体，可能是账号或 Profile。&lt;/li&gt;
&lt;li&gt;**不是所有 ID 都应使用 UUIDv4。**匿名 ID 常用 UUID；业务账号可以使用稳定、不可复用的内部主键。Mixpanel Original 的 UUIDv4 是特定 API 约束。&lt;/li&gt;
&lt;li&gt;**一个 CanonicalUserId 能否包含多个 &lt;code&gt;user_id&lt;/code&gt; 取决于系统规则。**Mixpanel Simplified 不允许合并两个 &lt;code&gt;$user_id&lt;/code&gt;，Segment 等系统则可以配置不同限制。&lt;/li&gt;
&lt;li&gt;**共享设备的匿名行为没有统一行业归属。**有的平台采用最近一次认证用户，有的平台要求 reset，也可以选择保持未解析。&lt;/li&gt;
&lt;li&gt;**“匿名行为归首个登录用户”不是通用最佳实践。**它会在共享设备和账号切换中造成错误归属。&lt;/li&gt;
&lt;li&gt;**500 个 ID 的簇限制不是 CanonicalUserId 的普遍限制。**它来自 Mixpanel Original API 的具体实现。&lt;/li&gt;
&lt;li&gt;**&lt;code&gt;reset()&lt;/code&gt; 策略必须结合厂商版本和业务状态机。**Simplified、Original、Amplitude 的建议并不相同。&lt;/li&gt;
&lt;li&gt;**一张以 &lt;code&gt;canonical_user_id&lt;/code&gt; 为主键的扁平映射表不够。**生产系统还需要节点、边、有效期、来源、版本和重定向。&lt;/li&gt;
&lt;li&gt;**Segment 不只是数据管道。**其 Connections、Unify 和 Engage 分别覆盖采集路由、身份解析/Profile 与受众激活能力。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="10-总结"&gt;10. 总结
&lt;/h1&gt;&lt;p&gt;CanonicalUserId 表面上是“给多个 ID 找一个主 ID”，更深一层其实是一个数据治理问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先定义要统一的实体，而不是先挑一个字段。&lt;/li&gt;
&lt;li&gt;用 Namespace 区分标识语义，用证据边描述为什么关联。&lt;/li&gt;
&lt;li&gt;强标识和弱标识采用不同规则，宁可暂不合并，也不要错误合并。&lt;/li&gt;
&lt;li&gt;CanonicalUserId 最好与外部账号、邮箱和设备解耦。&lt;/li&gt;
&lt;li&gt;原始事件不可变，映射关系要有来源、有效期、版本和审计。&lt;/li&gt;
&lt;li&gt;合并之外还要设计冲突、解绑、拆分、回算和删除。&lt;/li&gt;
&lt;li&gt;简单 ID-Mapping 不需要图数据库，多跳关系查询才需要图基础设施。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最终，CanonicalUserId 不是一张“身份证”，而是系统在特定业务边界、证据和规则下，对“这些记录当前属于同一实体”做出的可追溯判断。&lt;/p&gt;</description></item><item><title>【工作杂谈_20260810】用户分析与身份体系: Active User：定义、计算口径与常见应用</title><link>https://eleanora-lyh.github.io/MyLearningNotes/posts/work/useranalyticsidentity/20260810_%E7%94%A8%E6%88%B7%E5%88%86%E6%9E%90%E4%B8%8E%E8%BA%AB%E4%BB%BD%E4%BD%93%E7%B3%BB_activeuser%E6%8C%87%E6%A0%87%E5%8F%A3%E5%BE%84/</link><pubDate>Mon, 10 Aug 2026 23:58:04 +0800</pubDate><guid>https://eleanora-lyh.github.io/MyLearningNotes/posts/work/useranalyticsidentity/20260810_%E7%94%A8%E6%88%B7%E5%88%86%E6%9E%90%E4%B8%8E%E8%BA%AB%E4%BB%BD%E4%BD%93%E7%B3%BB_activeuser%E6%8C%87%E6%A0%87%E5%8F%A3%E5%BE%84/</guid><description>&lt;h1 id="1-active-user-是什么"&gt;1. Active User 是什么
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;Active User，简称 AU，表示在指定时间范围内，完成了某种“有效行为”的去重用户数。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它不是一个天然统一的指标，而是由三个口径共同定义：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;口径&lt;/th&gt;
 &lt;th&gt;要回答的问题&lt;/th&gt;
 &lt;th&gt;示例&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;用户标识&lt;/td&gt;
 &lt;td&gt;“谁”算一个用户&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;UserId&lt;/code&gt;、&lt;code&gt;CookieId&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;时间窗口&lt;/td&gt;
 &lt;td&gt;在什么时间内活跃&lt;/td&gt;
 &lt;td&gt;一天Daily、一周Weekly、一个月Monthly&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;活跃行为&lt;/td&gt;
 &lt;td&gt;做了什么才算活跃&lt;/td&gt;
 &lt;td&gt;打开 App、阅读内容、观看超过 N 秒、完成购买&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;因此，一个完整定义应该是：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;DAU = 在某自然日内，至少发生一次符合活跃条件事件的去重用户数。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;通用计算形式为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHEN&lt;/span&gt; is_active_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;THEN&lt;/span&gt; user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;END&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在不同系统中，“Active”口径可能不同。例如，官方定义中，活跃用户通常强调用户在指定日期范围内发生了符合参与条件的行为，而总用户只要求触发过事件。因此，在业务数据场景中不能只写“AU”，还必须同时说明活跃事件、统计窗口和用户标识。 &lt;a class="link" href="https://support.google.com/analytics/answer/12253918?hl=en" target="_blank" rel="noopener"
 &gt;[support.google.com]&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="11-dauwaumau"&gt;1.1 DAU、WAU、MAU
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DAU&lt;/strong&gt;：Daily Active Users，日活跃用户数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WAU&lt;/strong&gt;：Weekly Active Users，周活跃用户数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MAU&lt;/strong&gt;：Monthly Active Users，月活跃用户数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;假设同一个用户：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;8 月 1 日活跃&lt;/li&gt;
&lt;li&gt;8 月 2 日活跃&lt;/li&gt;
&lt;li&gt;8 月 10 日活跃&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;8 月 1 日 DAU：计数 1&lt;/li&gt;
&lt;li&gt;8 月 2 日 DAU：计数 1&lt;/li&gt;
&lt;li&gt;8 月 1 日至 7 日 WAU：仍然只计数 1（因为这一周出现的是同一个用户）&lt;/li&gt;
&lt;li&gt;8 月 MAU：仍然只计数 1（因为这一个月出现的是同一个用户）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;WAU 不能通过七天 DAU 相加得到，MAU 也不能通过每天 DAU 相加得到。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;因为 AU 本质上是：集合中不同用户的数量，而不是事件数量。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="2-au在大数据场景中的常见应用"&gt;2. AU在大数据场景中的常见应用
&lt;/h1&gt;&lt;p&gt;以AU为基础可以扩展出&lt;strong&gt;多维分析、漏斗对比、留存计算&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多维分析&lt;/strong&gt;：如你之前所示，按市场、设备等维度拆分 AU，了解不同分群的用户活跃情况。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;漏斗对比&lt;/strong&gt;：比较不同渠道的 DAU 变化，辅助运营决策。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;留存计算&lt;/strong&gt;：基于每日 AU 计算次日/7日/30日留存率。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="21-多维分析不同分群的用户活跃情况"&gt;2.1 多维分析：不同分群的用户活跃情况
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;数字产品的用户生命周期分析框架如下&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;分析环节&lt;/th&gt;
 &lt;th&gt;核心问题&lt;/th&gt;
 &lt;th&gt;对应维度&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;用户画像&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;用户是谁？用什么设备？&lt;/td&gt;
 &lt;td&gt;用户所在地域、设备型号&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;用户获取&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;用户从哪里来？&lt;/td&gt;
 &lt;td&gt;平台、渠道&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;用户行为&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;用户在产品里做什么？&lt;/td&gt;
 &lt;td&gt;兴趣类别、内容&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;用户体验&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;用户在不同版本下的体验如何？&lt;/td&gt;
 &lt;td&gt;APP版本&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;商业表现&lt;/strong&gt;​&lt;/td&gt;
 &lt;td&gt;用户在哪些市场/区域贡献价值？&lt;/td&gt;
 &lt;td&gt;市场、国家&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;多维 AU 分析，是把整体活跃用户集合按照不同维度进行切分，观察不同用户群体、业务区域或内容类型的活跃表现。&lt;/p&gt;
&lt;p&gt;——这个思路在移动应用和广告分析领域是&lt;strong&gt;通用的分析方法&lt;/strong&gt;，各家平台都会提供类似的维度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;百度移动统计&lt;/strong&gt;的常用维度就包含：品牌、设备型号、操作系统、运营商、、渠道、地域（国家/省/市）等&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apple App Store Connect&lt;/strong&gt;​ 的分析维度包含：App Version、Platform Version、Region、Product Page 等&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Firebase / Google Mobile Ads SDK&lt;/strong&gt;​ 自动采集的用户属性包含：国家、设备品牌、设备类别、应用版本、操作系统版本、兴趣类别等&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Braze&lt;/strong&gt;​ 等用户参与平台也按设备类型、平台、内容互动情况等维度评估活跃用户&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="211-基本计算方式"&gt;2.1.1 基本计算方式
&lt;/h3&gt;&lt;p&gt;假设原始行为数据如下：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;UserId&lt;/th&gt;
 &lt;th&gt;Date&lt;/th&gt;
 &lt;th&gt;Market&lt;/th&gt;
 &lt;th&gt;Device&lt;/th&gt;
 &lt;th&gt;Content&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;U001&lt;/td&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;US&lt;/td&gt;
 &lt;td&gt;Mobile&lt;/td&gt;
 &lt;td&gt;C001&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;U001&lt;/td&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;US&lt;/td&gt;
 &lt;td&gt;PC&lt;/td&gt;
 &lt;td&gt;C002&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;U002&lt;/td&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;US&lt;/td&gt;
 &lt;td&gt;Mobile&lt;/td&gt;
 &lt;td&gt;C001&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;U003&lt;/td&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;UK&lt;/td&gt;
 &lt;td&gt;Mobile&lt;/td&gt;
 &lt;td&gt;C003&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;按 &lt;code&gt;Market + Device&lt;/code&gt; 计算 DAU：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; Date, Market, Device, &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; UserId) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; DAU
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;table&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; Date, Market, Device;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Date&lt;/th&gt;
 &lt;th&gt;Market&lt;/th&gt;
 &lt;th&gt;Device&lt;/th&gt;
 &lt;th&gt;DAU&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;US&lt;/td&gt;
 &lt;td&gt;Mobile&lt;/td&gt;
 &lt;td&gt;2&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;US&lt;/td&gt;
 &lt;td&gt;PC&lt;/td&gt;
 &lt;td&gt;1&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;UK&lt;/td&gt;
 &lt;td&gt;Mobile&lt;/td&gt;
 &lt;td&gt;1&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这里可以回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;US 市场 Mobile 用户有多少？——2个&lt;/li&gt;
&lt;li&gt;不同设备上的用户活跃分布如何？——Mobile的用户活跃度高于PC设备&lt;/li&gt;
&lt;li&gt;某个 Market 的 DAU 下跌是否集中在某种设备？——由于目前只有一天的数据，暂时看不出下跌&lt;/li&gt;
&lt;li&gt;某个 类型文章 的活跃用户增长主要来自哪个 Market？——由于目前只有一天的数据，暂时看不出下跌&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="212-多维-au-不能直接上卷"&gt;2.1.2 多维 AU 不能直接上卷
&lt;/h3&gt;&lt;p&gt;上面的三个分组不能直接相加得到整体 AU：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;US Mobile AU &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;US PC AU &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;不能推导：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;US Overall AU &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;因为 &lt;code&gt;U001&lt;/code&gt; 同时使用了 Mobile 和 PC。&lt;/p&gt;
&lt;p&gt;正确结果是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;US 用户集合：
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Mobile = {U001, U002}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PC = {U001}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;并集 = {U001, U002}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;US Overall AU = 2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;用集合表达：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AU(Mobile ∪ PC) &amp;lt;= AU(Mobile) + AU(PC)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只有在能够保证用户不会跨分组出现时，分组 AU 才能直接相加。但实际的 市场/设备/内容/供应商 场景通常不能保证这一点。&lt;/p&gt;
&lt;h3 id="213-什么时候可以直接相加"&gt;2.1.3 什么时候可以直接相加
&lt;/h3&gt;&lt;p&gt;结合着两个指标理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;浏览量PageViewCount：发生了多少次内容消费行为&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;活跃用户数PageViewAUCount：有多少个不同用户发生过内容消费行为&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Partner&lt;/th&gt;
 &lt;th&gt;Content&lt;/th&gt;
 &lt;th&gt;PageViewCount&lt;/th&gt;
 &lt;th&gt;PageViewAUCount&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Partner A&lt;/td&gt;
 &lt;td&gt;C001&lt;/td&gt;
 &lt;td&gt;10,000&lt;/td&gt;
 &lt;td&gt;2,000&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Partner A&lt;/td&gt;
 &lt;td&gt;C002&lt;/td&gt;
 &lt;td&gt;8,000&lt;/td&gt;
 &lt;td&gt;1,500&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;PageViewCount&lt;/code&gt; 可以反映内容被消费了多少次；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;PageViewAUCount&lt;/code&gt; 可以反映内容覆盖了多少不同用户。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但 Partner A 的整体 AU 不能计算为&lt;code&gt;2,000 + 1,500 = 3,500&lt;/code&gt;，因为同一个用户可能同时看过 C001 和 C002。&lt;/p&gt;
&lt;p&gt;正确方式是基于 Partner A 范围内的明细重新去重：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; date,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; partner,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; user_id) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; partner_au
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; user_event
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; is_active_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; date,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; partner;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这也解释了为什么数据模型中需要同时保存：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;叶子级别的 Content AU&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Content = All&lt;/code&gt; 的 Partner AU&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Market = All&lt;/code&gt;、&lt;code&gt;Device = All&lt;/code&gt; 等不同上卷组合的 AU&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些 &lt;code&gt;All&lt;/code&gt; 粒度的 AU 不是由叶子行求和得到的，而是针对对应维度组合重新去重计算出来的&lt;/p&gt;
&lt;h3 id="214-多维分析的业务价值"&gt;2.1.4 多维分析的业务价值
&lt;/h3&gt;&lt;p&gt;多维 AU 分析主要用于定位“整体变化来自哪里”。&lt;/p&gt;
&lt;p&gt;例如整体 DAU 下降 15%，继续拆分可能发现：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;整体 DAU -15%
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── US Market -3%
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── UK Market -2%
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── DE Market -40%
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Mobile -5%
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── PC -65%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样可以将问题进一步定位到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;特定市场&lt;/li&gt;
&lt;li&gt;特定设备&lt;/li&gt;
&lt;li&gt;特定版本&lt;/li&gt;
&lt;li&gt;特定渠道&lt;/li&gt;
&lt;li&gt;特定内容类型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 PV （浏览量）未明显下降，但 AU （活跃用户数）大幅下降，需要重点检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户标识是否缺失&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UserId&lt;/code&gt; 生成逻辑是否变化&lt;/li&gt;
&lt;li&gt;去重逻辑是否变化&lt;/li&gt;
&lt;li&gt;某些用户事件是否没有进入上游&lt;/li&gt;
&lt;li&gt;匿名用户是否被统一写成同一个默认 ID&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="22-漏斗对比不同渠道的用户转化情况"&gt;2.2 漏斗对比：不同渠道的用户转化情况
&lt;/h2&gt;&lt;p&gt;这里需要先区分两个概念：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;只比较不同渠道的 DAU 变化，严格来说属于渠道趋势对比，不是完整的漏斗分析。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;真正的漏斗要求存在一组有先后顺序的业务阶段，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;内容曝光
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;内容点击
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;开始阅读
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;有效阅读
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;订阅或购买
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="221-渠道-dau-对比"&gt;2.2.1 渠道 DAU 对比
&lt;/h3&gt;&lt;p&gt;如果只是比较渠道活跃情况，可以计算：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Date&lt;/th&gt;
 &lt;th&gt;Channel&lt;/th&gt;
 &lt;th&gt;DAU&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;Search&lt;/td&gt;
 &lt;td&gt;20,000&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;Recommendation&lt;/td&gt;
 &lt;td&gt;35,000&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;2026-08-01&lt;/td&gt;
 &lt;td&gt;Direct&lt;/td&gt;
 &lt;td&gt;10,000&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这可以回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪个渠道带来的活跃用户最多？&lt;/li&gt;
&lt;li&gt;某个渠道 DAU 是否持续增长？&lt;/li&gt;
&lt;li&gt;一次运营活动是否带来了更多活跃用户？&lt;/li&gt;
&lt;li&gt;渠道增长是新增用户增长，还是老用户回流？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但仅有 DAU 仍不能判断渠道质量。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Channel&lt;/th&gt;
 &lt;th&gt;DAU&lt;/th&gt;
 &lt;th&gt;购买用户数&lt;/th&gt;
 &lt;th&gt;购买转化率&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;A&lt;/td&gt;
 &lt;td&gt;100,000&lt;/td&gt;
 &lt;td&gt;1,000&lt;/td&gt;
 &lt;td&gt;1%&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;B&lt;/td&gt;
 &lt;td&gt;20,000&lt;/td&gt;
 &lt;td&gt;800&lt;/td&gt;
 &lt;td&gt;4%&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;A 的活跃规模更大，但购买转化率只有：1%&lt;/p&gt;
&lt;p&gt;B 的购买转化率是： 4%&lt;/p&gt;
&lt;p&gt;所以渠道评估通常需要同时看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;活跃用户规模&lt;/li&gt;
&lt;li&gt;转化用户数&lt;/li&gt;
&lt;li&gt;转化率&lt;/li&gt;
&lt;li&gt;留存率&lt;/li&gt;
&lt;li&gt;人均消费深度&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="222-真正的用户漏斗"&gt;2.2.2 真正的用户漏斗
&lt;/h3&gt;&lt;p&gt;假设定义以下阶段：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ExposureUser&lt;/code&gt;：看到内容曝光&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ClickUser&lt;/code&gt;：点击内容&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReadUser&lt;/code&gt;：开始阅读&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EffectiveReadUser&lt;/code&gt;：阅读超过 N 秒&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SubscribeUser&lt;/code&gt;：完成订阅&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;每一步都应该按照用户去重：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;曝光用户数&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; exposure_user_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;点击用户数&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; click_user_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;有效阅读用户数&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; effective_read_user_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;订阅用户数&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; subscribe_user_id)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;阶段转化率：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;点击率 = 点击用户数 / 曝光用户数
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;有效阅读率 = 有效阅读用户数 / 点击用户数
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;订阅转化率 = 订阅用户数 / 有效阅读用户数
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;整体转化率 = 订阅用户数 / 曝光用户数
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="223-漏斗必须注意用户集合约束"&gt;2.2.3 漏斗必须注意用户集合约束
&lt;/h3&gt;&lt;p&gt;漏斗中的后一步用户，原则上应该是前一步用户集合的子集：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SubscribeUser ⊆ EffectiveReadUser
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;EffectiveReadUser ⊆ ClickUser
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ClickUser ⊆ ExposureUser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实际计算时，不能简单统计每天触发各事件的所有用户，否则可能出现：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;曝光用户数：1,000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;点击用户数：1,200
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这通常说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;点击事件缺少对应曝光事件&lt;/li&gt;
&lt;li&gt;曝光事件丢失&lt;/li&gt;
&lt;li&gt;统计周期对不齐&lt;/li&gt;
&lt;li&gt;用户在统计周期之前曝光、周期内点击&lt;/li&gt;
&lt;li&gt;不同阶段用了不同的用户标识&lt;/li&gt;
&lt;li&gt;Join 条件或事件时间逻辑存在问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，严格漏斗一般需要根据 &lt;code&gt;user_id&lt;/code&gt; 和事件顺序建立用户路径。&lt;/p&gt;
&lt;h3 id="224-漏斗中的时间窗口"&gt;2.2.4 漏斗中的时间窗口
&lt;/h3&gt;&lt;p&gt;漏斗还必须定义转化窗口。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;用户曝光后 24 小时内发生点击，点击后 7 天内发生订阅。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;如果不定义窗口，一个用户 8 月 1 日曝光、8 月 20 日订阅，是否还算同一次转化就会产生歧义。&lt;/p&gt;
&lt;p&gt;因此完整漏斗口径至少包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;漏斗起始事件&lt;/li&gt;
&lt;li&gt;后续阶段事件&lt;/li&gt;
&lt;li&gt;用户标识&lt;/li&gt;
&lt;li&gt;事件先后顺序&lt;/li&gt;
&lt;li&gt;阶段间允许的时间窗口&lt;/li&gt;
&lt;li&gt;是否允许跨天&lt;/li&gt;
&lt;li&gt;是否允许同一用户多次进入漏斗&lt;/li&gt;
&lt;li&gt;用户归属哪个渠道&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="225-渠道归因问题"&gt;2.2.5 渠道归因问题
&lt;/h3&gt;&lt;p&gt;用户可能经过多个渠道：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Search 曝光
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ Direct 访问
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ Recommendation 点击
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ 完成订阅
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;此时订阅算给哪个渠道，需要提前定义归因规则，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First-touch：归因给首次渠道&lt;/li&gt;
&lt;li&gt;Last-touch：归因给最后一次渠道&lt;/li&gt;
&lt;li&gt;Conversion-touch：归因给直接促成转化的渠道&lt;/li&gt;
&lt;li&gt;多触点归因：按照规则分摊&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以“比较渠道漏斗”并不只是按 &lt;code&gt;Channel&lt;/code&gt; 做一个 &lt;code&gt;GROUP BY&lt;/code&gt;，还需要保证渠道归因规则一致。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="23-留存计算次日7-日30-日留存"&gt;2.3 留存计算：次日、7 日、30 日留存
&lt;/h2&gt;&lt;p&gt;留存用于回答：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;一批在某天活跃或首次活跃的用户，经过一段时间后，还有多少人再次活跃？&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;留存通常基于用户集合或 Cohort，也就是具有共同起始条件的一批用户进行计算。&lt;/p&gt;
&lt;h3 id="231-不能只使用每日-au-数值计算留存"&gt;2.3.1 不能只使用每日 AU 数值计算留存
&lt;/h3&gt;&lt;p&gt;假设：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 1 日 DAU = 100
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 2 日 DAU = 120
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;仅凭这两个数字，无法计算次日留存率。因为我们不知道 8 月 2 日的 120 个用户中，有多少人在 8 月 1 日也活跃。&lt;/p&gt;
&lt;p&gt;可能是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;情况 A：
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 1 日用户 = {U001 ... U100}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 2 日用户中有 80 人来自 8 月 1 日
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;次日留存率 = 80 / 100 = 80%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可能是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;情况 B：
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 2 日用户中只有 10 人来自 8 月 1 日
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;次日留存率 = 10 / 100 = 10%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以更准确的表述是：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;留存基于每日活跃用户明细集合计算，而不是基于已经聚合好的每日 AU 数值计算。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="232-留存的集合公式"&gt;2.3.2 留存的集合公式
&lt;/h3&gt;&lt;p&gt;令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A0 = 基准日用户集合
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A1 = 基准日后第 1 天的活跃用户集合
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A7 = 基准日后第 7 天的活跃用户集合
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A30 = 基准日后第 30 天的活跃用户集合
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;那么：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;次日留存用户数 = |A0 ∩ A1|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;次日留存率 = |A0 ∩ A1| / |A0|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;7 日留存用户数 = |A0 ∩ A7|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;7 日留存率 = |A0 ∩ A7| / |A0|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;30 日留存用户数 = |A0 ∩ A30|
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;30 日留存率 = |A0 ∩ A30| / |A0|
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;|A0|&lt;/code&gt; 表示集合 A0 的用户数&lt;/li&gt;
&lt;li&gt;&lt;code&gt;∩&lt;/code&gt; 表示两个用户集合的交集&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="233-新增用户留存和活跃用户留存"&gt;2.3.3 新增用户留存和活跃用户留存
&lt;/h3&gt;&lt;p&gt;这是留存分析中非常重要的口径区别。&lt;/p&gt;
&lt;h4 id="2331-新增用户留存"&gt;2.3.3.1 新增用户留存
&lt;/h4&gt;&lt;p&gt;基准用户是当天首次出现的用户：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 1 日新增用户
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ 8 月 2 日是否再次活跃
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ 8 月 8 日是否再次活跃
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ 8 月 31 日是否再次活跃
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;适合评估：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新用户质量&lt;/li&gt;
&lt;li&gt;拉新渠道质量&lt;/li&gt;
&lt;li&gt;首次体验效果&lt;/li&gt;
&lt;li&gt;新版本 onboarding 效果&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2332-活跃用户留存"&gt;2.3.3.2 活跃用户留存
&lt;/h4&gt;&lt;p&gt;基准用户是当天所有活跃用户：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8 月 1 日所有 AU
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;→ 后续是否再次活跃
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;适合评估：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整体用户黏性&lt;/li&gt;
&lt;li&gt;产品持续使用情况&lt;/li&gt;
&lt;li&gt;内容用户回访情况&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两种口径不能混用。因为新增用户集合通常只是当日所有活跃用户的一个子集。&lt;/p&gt;
&lt;h3 id="234-第-7-日留存与7-日内留存"&gt;2.3.4 “第 7 日留存”与“7 日内留存”
&lt;/h3&gt;&lt;p&gt;这两个指标也不相同。&lt;/p&gt;
&lt;h4 id="2341-第-7-日留存"&gt;2.3.4.1 第 7 日留存
&lt;/h4&gt;&lt;p&gt;用户必须在基准日后的第 7 个自然日再次活跃：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cohort_date = 8 月 1 日
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;retention_date = 8 月 8 日
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="2342-7-日内留存"&gt;2.3.4.2 7 日内留存
&lt;/h4&gt;&lt;p&gt;用户在基准日后的第 1 至第 7 日内，只要任意一天回来就算留存：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;A0 ∩ (A1 ∪ A2 ∪ ... ∪ A7)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一般来说：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;7 日内留存率 &amp;gt;= 第 7 日留存率
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;因此报表中只写“7 日留存”是不够严谨的，需要说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是第 7 日留存&lt;/li&gt;
&lt;li&gt;还是 7 日内任意一天回来&lt;/li&gt;
&lt;li&gt;还是第 7 日及以后仍有活跃&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="235-用户留存的sql-实现思路"&gt;2.3.5 用户留存的SQL 实现思路
&lt;/h3&gt;&lt;p&gt;假设先生成用户每日活跃表：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;12
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;13
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;14
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;15
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;16
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;17
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;18
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;19
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;20
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;21
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;22
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;23
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;24
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;25
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;26
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;27
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;28
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;29
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;30
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;31
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;32
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;33
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;34
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WITH&lt;/span&gt; daily_active &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; event_date,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; user_event
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; is_active_event &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cohort &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; event_date &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; cohort_date,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; daily_active
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; event_date &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;2026-08-01&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.cohort_date,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.user_id) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; cohort_users,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHEN&lt;/span&gt; DATEDIFF(d.event_date, &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.cohort_date) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;THEN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;END&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; day_1_retained_users,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHEN&lt;/span&gt; DATEDIFF(d.event_date, &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.cohort_date) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;THEN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;END&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; day_7_retained_users,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;COUNT&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;DISTINCT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;CASE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;WHEN&lt;/span&gt; DATEDIFF(d.event_date, &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.cohort_date) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;THEN&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;END&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; day_30_retained_users
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; cohort &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;LEFT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; daily_active d
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.user_id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d.user_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GROUP&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;c&lt;/span&gt;.cohort_date;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后计算：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Day 1 Retention = day_1_retained_users / cohort_users
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Day 7 Retention = day_7_retained_users / cohort_users
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Day 30 Retention = day_30_retained_users / cohort_users
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="24-三类应用之间的关系"&gt;2.4 三类应用之间的关系
&lt;/h2&gt;&lt;p&gt;可以把三类分析理解成三个不同问题：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;分析类型&lt;/th&gt;
 &lt;th&gt;要回答的问题&lt;/th&gt;
 &lt;th&gt;说人话就是&lt;/th&gt;
 &lt;th&gt;去重范围&lt;/th&gt;
 &lt;th&gt;核心运算&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;多维分析&lt;/td&gt;
 &lt;td&gt;活跃用户来自哪些分群&lt;/td&gt;
 &lt;td&gt;谁在活跃？&lt;br/&gt;来自哪个 Market、Device、Partner、Channel？&lt;/td&gt;
 &lt;td&gt;在某个维度组合内去重&lt;/td&gt;
 &lt;td&gt;分组后去重&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;漏斗分析&lt;/td&gt;
 &lt;td&gt;用户在不同业务阶段流失在哪里&lt;/td&gt;
 &lt;td&gt;用户做到了哪一步？&lt;br/&gt;曝光、点击、阅读、订阅之间在哪里流失？&lt;/td&gt;
 &lt;td&gt;在每个业务阶段内去重，并建立阶段关系&lt;/td&gt;
 &lt;td&gt;阶段集合的包含与转化&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;留存分析&lt;/td&gt;
 &lt;td&gt;同一批用户后续是否再次回来&lt;/td&gt;
 &lt;td&gt;用户以后还回来吗？&lt;br/&gt;次日、第 7 日、第 30 日是否再次活跃？&lt;/td&gt;
 &lt;td&gt;在不同日期的用户集合之间求交集&lt;/td&gt;
 &lt;td&gt;跨时间集合求交集&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="3-在数据模型中的关键设计原则"&gt;3. 在数据模型中的关键设计原则
&lt;/h1&gt;&lt;h2 id="31-保留统一的用户标识"&gt;3.1 保留统一的用户标识
&lt;/h2&gt;&lt;p&gt;如果一部分事件使用 &lt;code&gt;UserId&lt;/code&gt;，另一部分使用 &lt;code&gt;DeviceId&lt;/code&gt;，则可能出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同一个人被识别成多个用户&lt;/li&gt;
&lt;li&gt;不同漏斗阶段无法关联&lt;/li&gt;
&lt;li&gt;留存率被低估&lt;/li&gt;
&lt;li&gt;AU 被高估&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此最好建立统一的 &lt;code&gt;CanonicalUserId&lt;/code&gt; 或明确身份拼接规则。&lt;/p&gt;
&lt;h2 id="32-明确时间口径"&gt;3.2 明确时间口径
&lt;/h2&gt;&lt;p&gt;需要固定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 UTC 还是 Market Local Time&lt;/li&gt;
&lt;li&gt;自然日从几点到几点&lt;/li&gt;
&lt;li&gt;跨市场报表按哪个时区计算&lt;/li&gt;
&lt;li&gt;迟到数据如何回补&lt;/li&gt;
&lt;li&gt;回补后是否重算历史 AU 和留存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于跨 Market 的全球数据，同一个 UTC 时间可能属于不同地区的不同自然日。&lt;/p&gt;
&lt;h2 id="33-au-字段不能默认-sum"&gt;3.3 AU 字段不能默认 SUM
&lt;/h2&gt;&lt;p&gt;在 BI 或语义模型中，&lt;code&gt;AU&lt;/code&gt; 应标记为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不可加指标&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Non-additive Metric&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;禁止默认 &lt;code&gt;SUM&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为下面这些通常都是错误的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-Plain" data-lang="Plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;月 AU = 每日 AU 求和
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;整体 AU = 各 Market AU 求和
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Partner AU = 各 Content AU 求和
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;全设备 AU = 各 Device AU 求和
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果下游经常查询固定的维度组合，可以提前生成每种 &lt;code&gt;All&lt;/code&gt; 粒度的精确 AU；如果需要大量灵活的任意维度上卷，则可以考虑用户明细、Bitmap 或近似去重结构。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id="4-一句话总结"&gt;4. 一句话总结
&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;Active User 的本质是“在特定时间窗口内，满足特定活跃条件的去重用户集合大小”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因此：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多维分析&lt;/strong&gt;是在不同维度范围内分别计算这个集合。用来了解不同分群的用户活跃情况。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;漏斗分析&lt;/strong&gt;是在多个有先后关系的行为阶段之间比较用户集合。比较不同渠道的 DAU 变化，辅助运营决策。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;留存分析&lt;/strong&gt;是在不同时间点之间计算同一批用户集合的交集。基于每日 AU 计算次日/7日/30日留存率。&lt;/li&gt;
&lt;li&gt;AU 不是普通可加指标，跨日期、设备、市场、内容或渠道汇总时，通常必须重新基于用户粒度去重。&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>