MATRIX

行为原子拆解

一个原子=每人每天一个简单数值 · ← 引擎架构总图

0 / 13 条 SQL 已确认覆盖字段 0 / 56
三张表:rpt.rpt_user_monitor_user_day_sd(主键 user_id, day) + room_day(主键 room_id, day)+ family_day(主键 family_id, day) 全部为当日值,窗口与比率在读表时算
13 条 SQL 已于 2026-08-31 在数仓逐条实跑过,结果见下方「建表交接」。
← 点左边任意一个字段
建表交接 · 研发照这个做就行

2026-08-31 把上面 13 条 SQL 逐条丢进数仓跑过(业务日 2026-08-30,全站不加名单过滤)。下面三块是跑完之后补的:实跑结果、建表语句、三条调度约定。

一、13 条实跑结果

批次目标表结果说明
A1~A11user_day11/11 通过全部正常出数。A4 / A6 / A8 / A11 当天该字段无数据,返回空行,不是报错
B1room_day原来跑不起来 → 已修报错 '=' cannot be applied to varchar, bigint dw_soc_chatroom_user_sd.room_idbigint,而 json_extract_scalar(ext,'$.roomId')gift.scene_target_id 都是 varchar,三张表两种类型直接 join 必挂。
已在 SQL 里加 cast(room_id AS varchar),改完重跑正常出数。之前标着「已经在跑」,实际这条 SQL 从来没跑通过。
B2family_day通过全站跑通。THIÊN ĐÌNH 累计经验跑出 1,220,333,和业务侧报的数一字不差

二、建表语句

类型是从 08-30 真实数据里看出来的,不是猜的。金额一律 decimal(18,2),经验和计数用 bigintday 做分区键。

/* 表二:房间 x 天 */
CREATE TABLE IF NOT EXISTS rpt.rpt_user_monitor_room_day_sd (
  room_id          varchar,        /* ★ 用 varchar 不用 bigint:源表三张,两种类型,
                                       json_extract_scalar 和 scene_target_id 都是 varchar */
  rm_uniq_n        bigint,         /* 当天进过这个房间的去重人数 */
  rm_bigr_n        bigint,         /* 其中荣耀用户数 */
  rm_mic_n         bigint,         /* 上麦动作总数 */
  rm_gift_val      decimal(18,2),  /* 礼物总面值 */
  rm_gift_from_n   bigint          /* 送过礼的去重人数 */
) WITH (partitioned_by = ARRAY['day']);

/* 表三:家族 x 天 */
CREATE TABLE IF NOT EXISTS rpt.rpt_user_monitor_family_day_sd (
  family_id        bigint,
  fam_name         varchar,        /* 家族名。大量特殊字符和 emoji,别做长度截断 */
  fam_level        int,            /* 家族等级 */
  fam_owner_id     bigint,         /* 族长 uid */
  fam_area         int,            /* 区域码 */
  fam_member_n     bigint,         /* 在册成员数 */
  fam_exp_day      bigint,         /* 当日家族经验 */
  fam_exp_gift     bigint,         /* 其中送礼来的 source=2 */
  fam_exp_task     bigint,         /* 其中任务来的 source=1 */
  fam_exp_month    bigint,         /* 本月累计 */
  fam_exp_cum      bigint,         /* 建族至今累计。实测最大 4,959 万,bigint 够 */
  fam_inner_val    decimal(18,2),  /* 族内互送金额 */
  fam_gift_val     decimal(18,2),  /* 族内礼物总额 */
  fam_gift_pair_n  bigint,         /* 互送的人对数 */
  fam_bigr_n       bigint,         /* 族内开通过荣耀的人数 */
  fam_bigr_live    bigint          /* 其中现在还在有效期内的 */
) WITH (partitioned_by = ARRAY['day']);

user_day 用现有的 rpt.rpt_user_monitor_user_day_sd,上面 A1~A11 是往里加列,不是新建表。

三、三条调度约定 —— SQL 里写不进去,必须在调度侧定

约定为什么
1. 快照类的历史重跑,拿不回当时的值 fam_level / rel_fam_id / rel_honor_level 这些来自 _ad 快照表, 一个分区就是那一天的一份全量,跑历史某天只能读那天的分区。分区一旦过了保留期被清掉,这一天的等级就永久拿不回来了。
所以这三张表要从建好那天起每天跑,断了的那几天只能空着,不要事后补 —— 补出来的是「今天的状态」贴上「那天的日期」,是假数据。 (流水类的 fam_exp_* / 充值 / 礼物不受影响,那些是全历史累积表,随时能回溯。)
2. 状态量当天没变动,要沿用昨天,不能写 0 rel_fam_id(在哪个家族)、rel_cp_exist(有没有 CP)、rel_honor_level(荣耀等级)这类是状态不是流量。 今天没有任何变动,值应该等于昨天,不是 0。
写成 0 会让「他退族了」「CP 没了」「荣耀掉了」这三个判断全部误报,而这三个恰好是大R流失的高危信号。
3. 空值语义要统一:0 和 NULL 不是一回事 0 = 有这个人 / 这个家族,但当天这项是零NULL = 这个维度对他不适用(没家族的人 fam_* 全 NULL,没 CP 的人 cp_value 是 NULL 不是 0)。
现在 SQL 里已经按这个写了(coalesce(...,0) 只加在「有家族但当天没送礼」这类上),落表时别再统一填 0。
还有一条不是给研发的,是跑数通道的坑

公司跑数网关只认首词是 SELECT / WITHSQL 开头那段 /* 说明 */ 会被直接拒掉(报 Only SELECT/WITH/SHOW/DESCRIBE/EXPLAIN queries are allowed)。 研发在自己的客户端里粘贴没这个问题;要从跑数通道验的话,先把开头那段注释剥掉。
另外行注释 -- 一律不能用——通道会把 SQL 压成一行,-- 会把后面整段吃掉。上面 13 条全部只用 /* */

按官方表清单重排 · 133 个原子 + 6 类原文素材 + 10 个 AI 解读维度

每天在跑 53 · 官方表清单带来的 46 · 派生(读表时算,不落)10 · 原文素材 6
2026-08-31 补:家族容器 6 列(等级/经验/互送对数)· 2026-09-02 补:玩法维度 14 列(场景明细/宝箱/竞价/房间玩法)+ 活动 4 列(掉落/种类数/礼包笔数与金额,并把「活动参与」从「拿不到的」移出来)+ SVIP 保级 3 列 + CP 等级 1 列

一个原子=每人每天一个简单数值。比率、跨天、argmax 不落表,在读表的时候算。
分节顺序=官方表清单《Matrix 原子数据补充》的六个分节;第七节是清单里没有、但每天在跑的。

「每天在跑」和「每天还没跑」是什么意思
指的是每日跑数那批 SQL——每天跑完写进 TOS 桶 data/{cc}/atom/d/{day}/{批次}.jsonl,现在 18 个批次(A · B1 · B2 · C1 · C2 · D1 · D2 · E · F1–F6 · G1 · G2 · G3 · G4)。
「每天还没跑」= 桶里没有这个字段,要用只能当场写 SQL 去数仓捞一次,跑完就没了,明天要用还得再跑。
这和另外两个东西没关系:大R宽表是数据侧单独跑的;rpt.rpt_user_monitor_user_day_sd 是以后想让研发建的正式数仓表,现在还不存在。
普通原子 本次新增 · 官方表清单带来的 ✓ 大R 宽表已有,直接读 开整理模式后点原子=勾选删除
整理模式 批量勾选 只显示保留的,已删的要开整理模式才看得到0 个保留 · 0 个已删
原子库(存量)
每人每天一行
存原始值,不存判断
智能 AI 组合判断
任意时间跨度的原子曲线
找原子之间的关系
① 发现异常
主动指出需要关注的对象
② 为什么
具体到玩法、关系、日期
③ 洞察
上升成可复用规则
④ 建议
指到人、日期、玩法
⑤ 预警
提前判断
← 点左边任意一个原子。

底部有黄线的是比率/跨天/argmax,不是一个简单数值,落表前要拆或者降级。

数据源地图 · 一个数该去哪张表拿

来源:《Matrix 原子数据补充》官方表清单 + 对齐过的自有口径。
下面每个实测数字都在 111 人名单上跑过,日期 2026-08-26。
要一个数,先在这一页找表。这一页找不到,才轮到说「数仓里没有」。
反过来也成立——这一页写了「有」的,不要再临时去别处挖。

先记两条分区规则,错了会直接算错

后缀是什么怎么限制
_adallday 全量表 day 分区里是历史全量,每天重写一整份。必须锁死一个最近分区 day = cast(date_add('day',-1,current_date) as varchar), 再用 substr(ctime,1,10) / create_time 切业务日。
按 day 范围拉 _ad 表 = 把历史重复累加,数字会翻好几倍。
_sdsingleday 单日表day 就是业务日,可以按 day 范围直接拉。

① 用户信息

状态拿得到什么 · 实测
dw.dw_user_basic_info_ad
用户基础信息
新增可用 111 / 111 全覆盖。一张表拿完画像,不用再单查 ods_user_profile_ad
register_days 注册天数(实测 13 ~ 1057)、nicknamegenderageage_rangebirthdaybiocity_name(实测 40 个城市)、device_osmedia_sourcecampaign(实测 6 种买量渠道)、state 1-正常 0-注销、languagearea
「注册第几天就冲上榜」这种话,以后直接读 register_days,不要再拿 ctime 减。
ods.ods_user_level_ad
SVIP 等级
新增可用 ⚠️ 荣耀等级也叫 level,值域 0~2;SVIP 值域 0~7。两张表,别混。
实测 111 人 SVIP level 分布 0 ~ 7,和荣耀等级是两把独立的梯子: SVIP5×荣耀1 有 29 人、SVIP5×荣耀2 有 12 人、SVIP7×荣耀2 只有 3 人。
字段:levellevel_modelevel_expiry_day_time_time_tsstay_timevalidtimezone
ods.ods_com_wealth_level_ad
荣耀等级
在跑 G3 监控池名单本身就是从这张表出的。level_mode 0-普通 1-保级 2-保级成功。
valid=1 不代表还在有效期内——实测有人 level_expiry_day 过期 413 天,valid 仍是 1。判「现在算不算荣耀」必须自己比日期。
ods.ods_com_user_wealth_level_stay_info_ad
保级进度
最该补的一张 「他这个月保级差多少分」是可以直接读出来的,不需要推算。
score 当前保级分 · pass_score 达标线 · status INIT-待完成/FINISH-完成 · month
08-25 实测(valid=1month='2026-08'):本月有保级任务的 31 人 —— 已完成 23 人,未完成 8 人。 荣耀 1 级达标线 16,800 ~ 23,800,2 级 42,000 ~ 67,200。
那 8 个人的缺口(全部在 2026-08-31 23:59:59 到期):1,798 · 2,450 · 2,966 · 8,258 · 9,426 · 12,726 · 13,536 · 14,047。 最前面两个离达标线只差两千出头。
valid 有 0 也有 1,历史保级任务会被置 0,必须加 valid=1
这是「为什么突然开始冲/为什么冲到某个数就停」最硬的一条外部解释。
ods.ods_user_device_info_ad
设备
有但没用 device_iddevice_nameext
os 字段官方注明「不准,以 ext 中切分为准」。多设备/小号排查时才用得上。

② 钱:充值 · 金币 · 礼物 · 钻石 · 背包

状态拿得到什么 · 实测
ods.ods_com_cash_order_ad
充值订单
在跑 A 成功充值=status=1finish_time 非空。currency_typecurrency_value原币
type 1-收入 0-支出(08-25 全站实测只有 type=1,不用过滤)· commodity_codecommodity_name 充值档位 · pay_channel 支付渠道 · channel_idsub_channel_id 三方渠道 · pay_credential 支付凭证 · ctimefinish_timemtime · area
commodity_name 能看出「他今天为什么充」。08-25 名单实测除了通用的 coin_detail_charge,还有 Limited_Time_Coins_TitleLarge_Recharge_Discount_TitleLarge_Coin_Limited_Title_3000Glory_Limited_Time_Gift_Pack3Lucky_Bag_TitleLimited_Recharge_180 这些限时/折扣包 —— 配上 E 批已有的 DISCOUNT_COUPON_TRIGGER 就是一条完整链路。
status 官方只写了 0-待支付 1-支付成功,但实测有第三档 2,而且是最大的一档 ——08-25 全站 status=2 有 7,401 单 / 4,405 人,比成功的 4,590 单还多。文档没有它。 这一档分不出「渠道挂了」还是「用户根本不想付」,不要拿它下结论
day 分区是累计回 2023-05-30 的,只能锁一个分区再按时间切。
ods.ods_com_coin_bill_ad
金币流水
在跑 B1 B2 B3 coin_num(不叫 coin)=虚拟币、recharge_coin 充值币、give_coin 赠送币,三个不可混用。
type 1-收入 0-支出 · scene_id 场景 · commodity_name · target_user_id
day 分区同样是累计的,单人单分区能到 70 万行。
ods.ods_com_gift_receive_bill_ad
送礼收礼
在跑 C1 C2 礼物只能查这张表。99.4% 的礼物走 gift_way='BACK_PACK'(另一种是 COIN-直购),根本不经过金币账单—— 拿金币账单算礼物,实测差 188 倍。
方向是显式的:user_id 送礼人 → target_user_id 收礼人。
金额=item_pay_price × quantityitem_origin_price 的单位是「分」 ——以前记的「原价是支付价的 100 倍」,根子在这里,不是什么倍数关系。
时间字段是 create_time 不是 ctime、场景字段是 scene 不是 scene_id、必须 valid=1
gift_type 1-普通礼物 2-守护挂件,做送礼分析必须锁 1 ——实测还跑出 3 和 10 两档,文档里没有。10 只有 4 笔,但值 24.5 万币。
scene_target_id:群聊场景装的是房间 ID,帖子场景装的是帖子 ID。 08-25 名单实测 scene=5 的 6,516 笔礼物指向 428 个 target, 428 个全部能在 ods_soc_chat_room_ad 里匹配上房间(100%)。 所以每一笔礼物都能落到具体哪个房间 —— 「他昨天把钱砸在哪个房间」是可以算的。 scene 另有 8(22 笔)和 51(1 笔),这两档 scene_target_id 匹配不上房间,语义未确认。
lucky_strike_count 连击礼物数(08-25 名单全是 0)· commodity_name_lang_keycommodity_icon_urlbill_no
ods.ods_com_user_point_account_bill_ad
钻石(表里叫 point)流水
新增可用 二级货币,不能充值,靠收礼返利/签到/活动拿。
bill_type 1-新增 2-扣减 · source 来源 · change_amount · available_balance 当前余额 · gift_receive_type 0-未记录 1-自己送礼 2-他人送礼。
08-25 实测:兑换(source=2)676 笔 / 71 人 / 50.7 万钻;收礼(source=1)2,235 笔 / 53 人 / 15.1 万。
PDF 只写了 source 1-收礼 2-兑换 3-过期,实测跑出 13 种(1,2,6,7,17,18,60,64,65,66,75,76,77)。枚举不全,用之前先跑一遍分布。
ods.ods_com_user_backpack_record_log_ad
背包流水
最该补的一张 这是「概率游戏开出什么 → 送给了谁」中间缺的那一段账。 以前只能拿「抽奖支出」和「背包送礼额」两头对,中间过程是黑的。
bill_type 1-冻结 2-解冻并还原 3-解冻并扣减 4-新增 · source 来源 · target_user_id 赠送人 · item_pay_price · balance 剩余 · expired_time 过期时间。
08-25 实测来源分布:LOTTERY 新增 8,711 笔 / 72 人;GIFT 扣减 6,585 笔 / 96 人; 另有 GROUP_OWNER_LADDER、AirdropHunt、GROUP_OWNER_CHALLENGE、AUCTION_TOKEN、FAMILY_CHEST、GROUP_CHAT_PK、Collect_WuFu 等十几种。
expired_time 能看出「他背包里的东西快过期了」——这是一条我们从来没用过的冲动来源。
2026-08-26 跑通:抽奖 → 背包 → 送给谁 → 打在哪个房间,整条链路是闭的。
以前只能拿「抽奖支出」和「背包送礼额」两个总数对,中间过程是黑的。两个 join key 实测都是 100% 命中:

直购礼物 gift_receive_bill.gift_way_bill_no = coin_bill.bill_no  416 / 416
背包礼物 gift_receive_bill.order_no = backpack_record_log.order_nosource='GIFT')  6,123 / 6,123
东西哪来的 同一张背包表里 source='LOTTERY'bill_type=4 的新增行
打在哪 gift_receive_bill.scene_target_id = chat_room_ad.room_idscene=5)  428 / 428

试过但不成立的:gift_way_bill_no 对背包礼物指向背包表(order_no 和 backpack_id 都是 0 命中)。 它只在直购礼物上有意义。

③ 聊天原文

状态拿得到什么 · 实测
ods.ods_soc_chat_msg_v1_sd
私聊消息
在跑 D1 D2 H1 H2 f_uid 发/t_uid 收 · msg_ts · messagecontent · messagetype · session_id
messagetype IS NULL 才是纯文本。必须双向读——只读他发出的,会漏掉别人对他说了什么。
我们自己加的限制:每人每天截断 100 条(按时间倒序)。这不是数仓口径。
ods.ods_flw_log_message_sd · CHAT_ROOM_MESSAGE
群聊公屏原文
在跑但只数了条数 原文在 ext.content,房间在 ext.roomId
08-25 实测:名单 111 人发了 16,768 条公屏,99 人有发言
现在 E 批只 count 了条数,原文一条都没落。判断情绪时是临时去捞的 —— 该进每日原文。
rt.rt_log_message_sd 不用切 PDF 推荐用这张取公屏。实测同一天同一批人,两张表完全一样(都是 16,768 条 / 99 人)。继续用 ods_flw_log_message_sd 就行。

④ 房间行为

事件状态08-25 实测(111 人)说明
ROOM_STAY在跑61,945 条 / 98 人房内停留心跳
CHAT_ROOM_MESSAGE只数条数16,768 条 / 99 人公屏发言,原文没落
EXIT_ROOM已取3,510 条 / 100 人2026-08-26 起已放进 E 批事件白名单,每天在跑。时长在 ext.roomUsageDuration 里,只有 EXIT_ROOM 带,进房事件没有。
JOIN_ROOM在跑3,454 条 / 101 人进房
OPEN_MICRO在跑2,349 条 / 100 人上麦
GIVE_UP_MICRO已取1,639 条 / 98 人2026-08-26 起已放进白名单,每天在跑。两个事件都是真事件,直接取、直接配对算在麦时长,不用任何推算。(要推算的只有「被抱上麦」——服务端没这个事件,只能拿上麦次数减主动申请。)
白名单不能省。不过滤 event_name 直接扫,60.3 秒超时返空;加上白名单 4.4 秒出结果,差 14 倍。 原因是 AB_EXPERIMENT 单个事件就 59,127 行。
另:uid 是 varchar,join 前必须 cast。

⑤ 关系

状态拿得到什么 · 实测
ods.ods_com_couple_value_stat_record_ad
CP 关系
在跑 G1 字段是 current_uid(申请人)/friend_uid,不是 user_id。
cp_type 1-cp 2-兄弟 3-闺蜜 4-知己 —— 我们现在没分,四种当一种在用。「CP 换人」的判断因此可能把兄弟当成 CP。
当前 CP 取 update_time 最新的那条,不是 cp_value 最大的那条。valid=1
ods.ods_com_couple_privilege_ad
CP 等级与特权 · 09-01 新接
P0 必接 这是解释「大R 为什么突然单日爆量」的关键表,比 couple_value_stat 有用得多。
字段:level CP 等级、cp_value 亲密值、level_failed_count 保级失败次数、refresh_level_dayend_time
必须 cp_type=1 AND state=1 AND valid=1state 0-未使用 1-使用中 2-禁用。
等级门槛是指数的:CP1 需 99、CP5 需 15,291、CP10 需 92,479、CP15 需 389,428、CP20 需 1,153,771。升到 CP5 只要 +8,090,升到 CP20 要 +249,804,差 31 倍。
只升不降end_time 写在 2053 年。所以它不是周期性收入,是一次性冲刺。
坑:2026-07-01、07-05~07-09 这几个分区被重复加载过,count(*)count(DISTINCT id) 的两倍。做趋势必须先按 id 去重,否则会看出一个不存在的「7 月腰斩」。
09-01 实测:越南 223 对在册,≥12 级 16 对、≥15 级 8 对;≥15 级的对数 6 月 20 日到 8 月 22 日一直是 2~3 对,08-23 起十天翻到 8 对。
ods.ods_com_family_member_ad
家族成员
在跑 G2 status 是 1-正常 2-退出,不是 0/1。不加 status=1 差 7,100 倍。
quit_timequit_reason(leave|kickout)/quit_by 退出操作人 —— 能直接看出「谁被谁踢的」role 0-成员 1-副族长 2-族长、contribution_value 贡献分、invite_by 邀请人。
08-25 实测:95 人在册、分布在 67 个家族;另有 80 人留下 203 条历史退出记录。
ods.ods_com_family_info_ad
家族信息
P0 必接 name 家族名、level 家族等级member_cntowner_id 族长、 status 0-待审核 1-正常 2-解散、announcement 公告。
2026-08-31 实测:status=1 全站 2,949 个家族(Lv1 2,792 / Lv2 115 / Lv3 22 / Lv4 15 / Lv5 1 / Lv7 2 / Lv9 1 / Lv10 1)。
原来这一行写的是「有但没用 —— 接上才有名字」,那是把它看小了。 家族等级只存在这张表里,而且是按天全量快照,逐日 diff 就是升降级事件。 不接这张表,「这个家族在冲级还是在保级」这类问题一条都答不了。
ods.ods_com_family_user_exp_record_ad
家族贡献流水
新增可用 family_id · user_id · incr_family_exp_value 家族经验 · incr_user_exp_value 个人贡献 · source 1-任务 2-送礼 · 现成的 month(yyyy-MM)和 week · create_time
08-25 实测:送礼 1,291 笔 / 68 人 / 44.3 万经验;任务 225 笔 / 66 人 / 4,505。
member 表只有累计贡献分,这张才是按天的,能看出「他今天为家族花了多少」。
两个 exp 列不是同一个数:2026-08 全站家族经验 2,941 万、个人贡献 2,747 万,差 7%。判断等级要用 incr_family_exp_value
累计经验 = 在一个分区里按 family_id 全量求和(这张 _ad 表一个分区就是全历史), 但 day=X 的分区里装着 X+1 号的记录,必须再卡 create_time <= day,否则多算一天。
dm.dm_soc_chat_session_msg_v1_sd
私聊会话(对话框维度)
用过但没进原子 session_round_cnt 会话轮数 · is_initiater 是否主动发起 · send_cnt 当天发送条数 · retain_1retain_7 · is_new_session · last_msg_ts · related_post_id 来源帖子。
08-25 实测:761 行 / 92 人 / 745 个会话,最深 319 轮
channel = 这段对话是从哪来的,实测 12 种: chatroom 420 · followlist 85 · default 82 · homepage 56 · bell 39 · textmatch 29 · fateradar 11 · onlineuser 10 · newuserdefault 9 · square 2 · voicematch 1 · Vistor_Page 1。
「他最近在跟谁聊、这段关系是怎么开始的」这一层,现在完全没进原子。
家族等级到底怎么走的 · 2026-08-31 在数仓里跑出来的

起因是业务侧报了两个越南家族在 08-24 之后集中互送、把等级从 Lv3 顶到 Lv4,问天网能不能把这种异动抓出来。下面四条都跑过。

结论性质怎么验的
业务侧那两个数能一分不差复现Fact 家族 35784378 截至 08-23 累计经验 1,063,212、家族 40209452 截至 08-30 1,220,333, 和业务侧报的数字完全一致。说明「累计家族经验」这个口径是通的,不用等谁确认。
家族等级会掉,按月结算Fact 07-30 → 07-31 一夜之间:Lv2 122 → 81、Lv3 28 → 9、Lv5 5 → 3。 07-01 → 08-01 全量 diff,160 个家族掉级(2→1 有 102 · 3→2 有 36 · 4→3 有 10 · 5→4 有 10 · 7→6 有 2)。 而 08-01 到 08-30 整整一个月,零掉级
所以「是不是在保级」这个假设成立,而且压力全在月末那两三天。
异动全在「送礼」这条来源上Fact 35784378 08-17 ~ 08-30,任务经验(source=1)每天 790 ~ 2,570,几乎是常数; 送礼经验(source=2)从 35,024 拉到 205,124。两个来源混在一起报,异动会被稀释。
门槛不能自己反推,要拿产品文档 Lv2 掉级组 7 月经验最高 29,940、保住组最低 33,007,看着像一条 3 万的线; 但 Lv3 / Lv4 两组完全重叠(Lv4 掉级组最高 354,342,保住组最低 0),单一阈值解释不了。 另有家族 14299827 累计经验 703 万却还是 Lv1(2024-12 建族,近半年月均只剩几百经验)。
意思是等级规则不只看经验一个量。门槛表当常量配在读表侧,从产品文档拿,别在数仓里反推。

落表侧要做的就一件事:把 fam_level / fam_exp_day / fam_exp_gift / fam_exp_cum / fam_exp_month 每天落进 family_day。 「谁在冲级、谁在保级、差多少、几天内会到」全是读表时的事,不要在落表阶段算。

⑥ 房间与玩法

状态拿得到什么 · 实测
ods.ods_soc_chat_room_ad
群聊房间
有但没用 topic 房间名 · owner_id 群主 · creator_id · state 1-正常 2-隐藏 3-解散 · disband_type 1-房主退房 2-管理员解散 · disband_time · classify_code_id 类目。
08-25 实测:名单里 100 人当过房主,累计 1,272 个房间,其中 1,257 个已解散(day 分区是累计的,这是全历史)。
现在报房间只有 roomId,接上这张表才知道房间叫什么、是谁的、什么时候散的。
ods.ods_com_gift_receive_bill_adext
房间玩法识别 · 09-01 新接
P0 必接 数仓里没有「房间玩法」这张表,玩法只能从礼物流水的 ext 里取。
json_extract_scalar(ext,'$.ext.roomPlayType'):0-无玩法 1-PK 2-Ludo 3-Battle 5-拍拍(đấu giá 竞价)
地区也在 ext 里:CAST(json_extract_scalar(ext,'$.area') AS integer)
代价:没产生过礼物消费的房间完全统计不到。所以「拍拍房间数」严格说是「产生过普通礼物消费的拍拍房数」。
09-01 实测:越南 08-24~31 共 567 个拍拍房、183 个房主、342 万金币。
ods.ods_group_chat_auction_ad
ods.ods_auction_score_bill_ad
竞价主表 + 出价流水
P0 必接 竞价是麦位功能:出价流水的 ext{"microIndex":"11"},microIndex 就是麦位序号。
竞价不扣金币,所以扫 coin_bill 的商品名永远找不到它。它的成本载体是背包里的 source='AUCTION_TOKEN'
主表 105,541 行(越南 8,496)。purposestatus 的枚举含义未知,这是最该问运营的一个字典
⚠️ 出价流水表最新分区只到 2026-07-24,主表到 08-31,疑似停止同步一个多月。做金额分析前先确认它还活着。
ods.ods_com_user_backpack_record_log_ad
宝箱与掉落
P0 必接 宝箱不是扣币商品,是掉落物,所以它天然不在 coin_bill 里。任何「扫商品名找玩法」的做法都会系统性漏掉全部掉落型机制。
三套宝箱:GroupChat_Chest0~6(群聊)、Family_Chest_Level_1~10(家族)、GroupChat_PartyCollectChest1~6(活动)。
sourceGROUP_OWNER_LADDER 房主阶梯(Chest4/5/6)、FAMILY_CHEST 家族宝箱。群聊高等级宝箱挂在房主阶梯上,不挂个人消费 —— 全房花钱推的是房主的进度条,这解释了公屏上「大家一起救宝箱」的集体感。
价值陡增:Chest4 是 490~1,900、Chest5 是 1,900~6,000、Chest6 是 6,000;家族箱 Level_1 是 4,000、Level_10 是 5,000,000。
bill_type=4 新增、target_user_id=0 —— 系统凭空发放,是平台成本不是房间消费切分。
时间列是 create_time 不是 ctime房主阶梯的阈值配置表数仓里没有,「还差多少掉箱」算不出来。
ods.ods_com_user_level_stay_info_ad
SVIP 保级进度 · 09-01 新接
P0 必接 前面接的 ods_com_user_wealth_level_stay_info_ad 是荣耀那把梯子(0~2 级),只有几十人;SVIP 那把梯子(0~7 级)在这张表,覆盖面大得多。
字段:score 本周期已得分、pass_score 门槛、level_mode(1 保级中 2 本周期已完成)、status(INIT / FINISH)、pre_expiry_daylevel_expiry_time。锁 business_type=1 AND valid=1
SVIP 是七天一续,不是月结。09-01 实测越南 SVIP1~6 共 1,767 人,到期日只有七个值(09-01 到 09-07)均匀铺开;已掉级的 SVIP0 有 338 种到期日。
门槛:SVIP1 是 64、往上 350 / 1,500 / 6,000 / 25,000、SVIP6 是 100,000。
09-01 实测:183 个拍拍房主全部在这张表里,97 人本周期已达标,其中 32 人超出门槛不到 1%,4 人一分不多(1500/1500、6000/6000、350/350、64/64)。门槛设在哪,消费就停在哪。
ods.ods_com_lucky_game_level_user_ad
概率游戏等级
新增可用 levelexp。08-25 实测 110 / 111 有等级,level 跨度 0 ~ 38,exp 最高 1,238 万。
玩法:lucky777 · luckyfruit · luckyslot。

PDF 里没有、我们自己跑出来的口径

这些不是从哪张表直接读的字段,是我们自己定的算法或对齐过的口径。都不是推测,是跑过数对上的。
口径怎么来的 · 核过没有
全站充值口径 cash_order 不加任何过滤、按 finish_time 切天,= 大盘表的总收入。
08-16 ~ 08-25 十天里八天一分不差(08-20 差 0.6%、08-21 差 0.08%,是晚结算的订单)。
08-25:全站 ¥81,903 / 2,372 人 / 4,586 笔;名单 111 人 ¥24,244,占付费人数 2.2%、占收入 29.6%。
16 币种汇率 PDF 完全没提汇率。cash_order 里只有原币金额,跨国比大小必须先换算: 1=×7.26、2 VND=×0.0003、3 PHP=×0.13、5 IDR=×0.0005,共 16 种。
原子表里存的是原币,大R 宽表里存的是人民币。两边不能直接比。
名单口径 每日滚动的当月充值 Top20 × 7 国(Lai 的口径)。桶里另存了一条反推出来的下限门槛, 那条门槛只在桶里,对外一律只说「每国取前 20」。
玩法看净流水 玩法排序看 out_coin − in_coin,不看流水总额。Lucky777 返奖率 97.4%、群聊抽奖 0% —— 按流水排和按净流水排,两个榜几乎相反。PDF 里没有这个概念。
社区侧四张表 PDF 一张都没提,但我们每天在跑:ods.ods_cot_post_ad 发帖(F1)、 ods.ods_cot_user_like_ad 点赞双向(F2 / F3)、 ods.ods_soc_user_follow_ad 关注双向(F4 / F5)、 ods.ods_cot_comment_ad 评论(F6)。
其中 F2 的「主动触达人数」是判断「他还在不在找人」的核心原子。
背包送礼占比 99.4% 的礼物走背包,不经过金币账单。由此定的原子「背包送出率 = 背包送礼价值 ÷ 概率游戏支出」—— 分母必须是抽奖支出,用总送礼额当分母实测全员 0.98、没有区分度。
充值切天用 finish_time 2026-09-01 改。A 批次(充值)原来按 ctime 切天,已改成 finish_time
起因:名单构建(roster.py)一直用 finish_time,A2 充值档位也用 finish_time,只有 A 用 ctime —— 同一张表三处口径不一致
实测影响:8 月 38,363 笔订单里有 3,117 笔(8.1%)两个时间不在同一天,八天窗口内总额只差 0.036%,总量可忽略,但单日会错位。跨零点的订单在「一晚一场」这种夜间为单位的分析里会被切到另一天。
02-atoms.sql md5 随之更新为 f9ac0a7400465d93207d735dbf8e7908(上一版 df0f9bd5…)。09-01 之前的历史原子是旧口径,跨这个日期比较单日充值要留意。
房间当天建当天散=零区分度 09-01 实测:08-30 创建的房间到次日分区全部 state=3,五个地区都是 100%(印尼 102,971/102,971、菲律宾 46,032/46,033、越南 13,583/13,583、阿语 11,088/11,088、泰国 5,112/5,112)。
这是平台默认的房间生命周期,不是「临时局」的特征。拿它当证据没有任何区分度。
真正有区分度的替代指标是同一房主反复建房GROUP BY owner_id 看建房频次和房名重复度。带序号的房名(Cứu Rương 56)说明房主在连续复用同一个局。
⚠️ 另一条相反的说法(「ods_soc_chat_room_ad 是累积快照,单分区含全部历史」)09-01 实测不成立:三个分区 × 五个地区,全部只装 day-3 到 day+1,2026 年之前创建的房间一条都没有。分区是滚动窗口,不是累积。
拍拍房口径 roomPlayType=5area=84scene=5gift_type=1,金币 = item_pay_price × quantity
必须剔 user_id = target_user_id 的自购行 —— 家族宝箱一笔 210 万金币,不剔会把「这批房间占全站房间礼物」从 3.1% 顶到 38.8%。
房主要跨多个 day 分区关联房间表取 max(owner_id)ods_soc_chat_room_ad 的 day 分区不是累计的,只装前后约四天创建的房间,单分区匹配会丢掉大半。09-01 实测这样取 567/567 全覆盖。
scene_target_id 是 varchar,IN 里不加引号会静默返回空表且不报错。第一版因此得出过「这些房间当天没有礼物」。
大R 单日爆量先查 CP 09-01 越南拍拍专题跑出来的判据。大R 单日散出五万金币以上时,先看他的 CP 等级当天跳没跳。
实测:08-24~31 每一场 ≥5 万的单人散礼,都对应一次 CP 跳级 —— Lý Thất Dạ 08-25 散 246,320 金币,CP 从 14 跳到 17;Phở 08-29~31 连做三场,CP 从 4 冲到 15;Bo đêy 08-28 一场,CP 从 2 跳到 8。亲密值和两人当天互送的金币大致等量。
机制:SVIP 要求「礼物送出去才算分」,CP 要求「送给同一个人才涨亲密值」。两条规则在同一个动作上重叠,所以最优解是把钱全砸在一个固定对象身上再让对方砸回来。这解释了为什么大R 的钱不是散开的。
CP 等级有实物奖励(公屏原话:13 级房子、16 级楼房、18 级戒指),门槛玩家之间互相报(「Cp 13. 300k điểm」)。
两把梯子别混 荣耀(ods_com_wealth_level_ad,0~2 级,月度到期)和 SVIP(ods_user_level_ad,0~7 级,七天到期)是两套独立体系,刻度不同,不能互相换算。加上 CP 等级(只升不降)一共三把梯子。
09-01 实测越南:持荣耀 1 级以上的只有 63 人,其中 38 人在开拍拍房;持 SVIP 1 级以上的 1,767 人。SVIP6 全越南 8 人,8 人全在开拍拍房。
玩法不在 coin_bill 里 08-24 那张卡判错的根因。宝箱、竞价、掉落类机制都不扣币,所以扫 coin_bill.commodity_name 找玩法必然漏掉它们。宝箱在背包流水,竞价在自己的独立表。
连带的一条:看消费要 SUM(ABS(coin_num)),不能只看 recharge_coin(只覆盖 11.4%)。全平台 give_coin 占消费 88.6%,任何用「币消费」当收入代理的指标都严重失真。
读原文的上限 私聊每人每天 100 条、群聊 200 条。这是我们自己定的 token 上限,不是数仓限制。 超了会截断,截了谁 run log 里有记录。
官方 PDF 里 ods_com_gift_receive_bill_adods_com_cash_order_ad 两张截图是空的,字段说明已按补充材料写进上面对应两行。
这两张表最容易漏的三点:充值的 commodity_name 档位名、礼物的 scene_target_id 能落到房间、gift_type 必须锁 1。
数仓绝对只读。这一页列的所有表,只发 SELECT / SHOW / DESCRIBE。 需要落表的一律只交 SQL 给研发执行。

宽表字段清单

目标表 rpt.rpt_user_monitor_user_day_sd(主键 user_id, day),全部是当日值。这一页只回答一件事:每一列怎么算、从哪张表来、会在哪里算错。

三条原则
  1. 一列 = 当天数得出来的一个数。比率、差值、argmax、跨天,全部读表时算,不落表。
  2. 字段名要让第一次看见的人知道怎么算。做不到就说明它是两步操作,该落明细而不是落结论。
  3. 粒度只有三种:人×天(这张宽表)、房间×天、家族×天。跨粒度的不要往宽表里塞,会重复计数。
A · 身份

静态,跑一次不用每天重跑。源表 ods_user_profile_base_adods_user_info_ad

字段是什么怎么算状态坑 / 为什么要它
nickname昵称nickname,读一个分区已有大量特殊字符,没人手打得出来,检索一律支持 UID
gender性别0 未知 1 男 2 女已有
age年龄由 birthday 推算已有自填不可靠,实测有 1928 年和 2011 年的生日。只能粗分层,不能进结论
user_ctime注册时间ctime已有
area区域码62 印尼 63 菲 66 泰 84 越 90 土 96 阿已有country ≠ area。阿语区要用 area=96 再拆埃及 20/伊拉克 964/沙特 966
city_name media_source device_os城市/买量渠道/系统已有
state账号状态1 正常 0 注销P1 要加有了这一列才分得出「查不到这个人」是注销了还是不在池里
B · 充值

源表 ods_com_cash_order_ad整组共同的坑:day 分区是累计的 —— 只读最新一个分区,再用 substr(finish_time,1,10) 开窗;拉多个分区会重复计数。currency_value 是 varchar,要 cast(… AS decimal(18,2))

字段是什么怎么算状态坑 / 为什么要它
recharge_cnt充值笔数status=1 的订单数已有
recharge_amt充值金额(原币)sum(currency_value)已有原币,没折人民币。卢比和比索直接相加没有意义
recharge_cny充值金额(人民币)按 currency_type 逐币种乘固定汇率,16 种币种P0 要加必须剔内部白名单ods_opr_admin_whitelist_ad,valid=1 且 group_id IN (6,8,9,10,12,13,14,15,16,18,19)
currency_type币种原样落一列P0 要加如果不想在 SQL 里折算,至少要有这一列,否则下游谁都折不了
order_all下单笔数(全状态)当天全部订单,不加 status 过滤P1 要加「今天没充值」有三种:主动不买了/想买但付不进去/还有货不用买。只查 status=1 分不出来
order_fail失败订单数status <> 1 的订单数(0 待支付 1 成功 2 取消或失败)P1 要加实测 36989322 近一个月 167 单只成 101 单,08-03 那天 36 单只成 13 单。这是「想付没付成」的唯一入口
pay_channel支付渠道1 Google 2 Apple 3 Airwallex 4 Payermax 5 CodaP1 要加越南实测成功率:渠道1 26.6%、渠道2 24.4%、渠道4 58.3%。换渠道本身就是信号
recharge_max单笔最大充值max(currency_value)P2 可选
C · 消费与余额

源表 ods_com_coin_bill_ad(消费)/ods_com_coin_account_ad(余额快照)。coin_bill 的 day 分区也是累计的,同样只读一个分区 + ctime 开窗,单人单分区可达 70 万行。

字段是什么怎么算状态坑 / 为什么要它
coin_out金币消费总额type=0,sum(coin_num)已有
coin_recharge_out充值币消耗type=0,sum(recharge_coin)P0 要加这一列才是真钱。和总消耗差 6.9 倍 —— 实测有人某天真钱为 0,但总消耗 934,090、操作 22,983 次。只看总消耗会把「在花赢回来的币」当成在花钱
coin_give_out赠送币消耗type=0,sum(give_coin)P0 要加平台发的免费币。概率玩法里大量消耗是赢回来的币在体内循环,真钱降但这一列升=策略切换,不是流失
coin_in金币获得type=1,sum(coin_num)P1 要加
ops消费操作次数type=0 的记录条数P1 要加和金额一起看才分得出「下注变大」还是「玩得更久」
bal_recharge收盘充值币余额当日快照的 recharge_coinP1 要加自己花钱买来、还没花掉的那部分
bal_give收盘赠送币余额当日快照的 give_coinP1 要加没有余额就会误判。「今天没充值但还在花」本身完全正常 —— 可能是前几天充的还没花完
D · 玩法 ★最大的一个缺口

现在 41 个场景只拆了 3 列,其余 38 个全塞进 other_coin净流水最大的「群聊抽奖」就埋在里面,拿宽表算玩法结构会直接算错。
建议不要拆 41 列,落一张明细表 —— 加新玩法不用改表结构。

字段是什么怎么算状态坑 / 为什么要它
▸ 新表 user_scene_day玩法明细(人 × 天 × 场景)主键 user_id, day, scene_id;三个值 out_c(type=0)、in_c(type=1)、opsP0 要加一人一天一个场景一行。41 个场景不用拆列,以后加玩法也不用改表
lucky777_coin lucky_fruit_coin lucky_slot_coin other_coin现有四列维持不动已有别的地方在用,不要动。新表是补充,不是替换
coin_prob_out概率玩法合计scene_id IN (11,14,32,35,46,61) 的 out_c 合计P0 要加
coin_groupdraw_out群聊抽奖scene_id = 10 的 out_cP0 要加它是净流水第一(半年 2,939 万,不返币),但在流水榜上不显眼。现在完全看不见
E · 礼物 ★缺口

源表 ods_com_gift_receive_bill_adday 分区同样是累计的必须加 gift_type=1,不加会差几个量级。现在宽表只有一个 gift_coin 汇总,答不了「礼给了谁、是真花钱还是背包」。

字段是什么怎么算状态坑 / 为什么要它
gift_coin_amt礼物直购金额gift_way='COIN' 的金额P0 要加这才是真花钱那部分。礼物九成九走背包,送礼额涨不等于花钱涨
gift_bp_amt背包送出金额gift_way='BACK_PACK' 的金额P0 要加
gift_amt送礼总价值sum(item_pay_price × quantity)P0 要加必须从礼物表算,不能从金币账单算,两个口径对不上
gift_n送礼次数valid=1 的送出记录条数P1 要加
gift_out_n送礼对象数distinct 接收方 uidP1 要加
gift_in_amt gift_in_n收礼价值/来源数同口径,按接收方统计P1 要加
▸ 新表 user_gift_pair_day礼物逐对明细(人 × 天 × 对象)主键 user_id, day, target_user_id;两个值 amt、nP1 要加「送得最多的是谁」不要落成一列 —— 那要先按对象聚合再取最大,是两步。落明细,最大值读表时自己排
F · 私聊

源表 dm_soc_chat_session_msg_v1_sd

字段是什么怎么算状态坑 / 为什么要它
private_msg_cnt私聊消息数当天收发总条数已有
active_session_cnt活跃会话数已有
chat_partner_n对话对象数distinct 对端 uidP1 要加和活跃会话数不完全等价
chat_rounds对话轮数round_cntP1 要加是当天轮数,不是累计
chat_new新建对话数当日新建的会话数P2 可选
G · 群聊与房间 ★缺口

源表 ods_flw_log_message_sddw_soc_chatroom_user_sd整组共同的坑:事件列是 event_name 不是 eventts 是日期字符串不是 epoch 毫秒,cast(ts AS bigint)静默返回空、不报错

字段是什么怎么算状态坑 / 为什么要它
room_dur_min micro_dur_min在房时长/在麦时长已有duration 单位是毫秒
room_msg_cnt群聊消息数event_name='CHAT_ROOM_MESSAGE' 的条数,和私聊分开P0 要加公屏是大R谈玩法、谈活动的主场。实测 110 个大R一天公屏 16,864 条,同一天全池私聊只有 9,308 条 —— 现在宽表里一条都看不到
room_join_cnt进房次数event_name='JOIN_ROOM'P1 要加
room_exit_cnt退房次数event_name='EXIT_ROOM'P1 要加
room_5min有没有 5 分钟停留当天有没有过单次 EXIT_ROOM 的 duration ≥ 300000msP1 要加是「单次」,不是当天累计。这两个口径差很多
mic_cnt上麦次数event_name='OPEN_MICRO'P1 要加
mic_off_cnt下麦次数event_name='GIVE_UP_MICRO'P2 可选
mic_req_cnt主动申请上麦GroupChatDetail_MicRequest_Click 点击数P1 要加和 mic_cnt 一起看才分得出「自己上的麦」和「被抱上去的」—— 被抱上麦没有服务端事件,只能这么反推
H · 广场

源表 ods_cot_post_adods_cot_user_like_adods_cot_comment_ad。整块现在宽表里都没有。

字段是什么怎么算状态坑 / 为什么要它
post_n发帖数valid=1 的条数,type 区分图文/视频P1 要加
like_n comment_n点赞/评论次数当日条数P1 要加
vote_n投票次数当日参与帖子投票的条数P2 可选
follow_out_n follow_in_n当日新增关注/被关注user_id 是本人/target_user_id 是本人P2 可选
I · 关系与等级

源表 ods_com_couple_privilege_adods_com_family_member_adods_com_wealth_level_ad

字段是什么怎么算状态坑 / 为什么要它
cp_status cp_uid cp_nickname cp_changeCP 现状与变更已有
cp_levelCP 等级当前 CP 的 levelP1 要加
cp_value本周亲密值cp_valueP1 要加这张表按周记录,每周日清零重算。不能拿两天直接比,跨周比是错的 —— 落表要带上是哪一周
family_id family_role family_change家族现状与变更role:0 成员 1 管理员 2 族长已有status=1 才是在册。该表存全历史,一人多行
family_contrib家族贡献值contribution_valueP2 可选
wealth_level wealth_expire_day荣耀等级与到期日level_mode:0 未达标 1 升级成功 2 保级成功已有valid=1 不代表在有效期内 —— 实测有人过期 413 天 valid 仍是 1。判断「现在是不是荣耀」必须比到期日。另:到期即 level 归 0,但记录不删
wealth_first_time第一次拿到荣耀的时间create_timeP1 要加一个 uid 一行,create_time 就是首次开通,不用做分区差集。「表里有这个 uid」=这辈子开通过;level>0=当前在册。8 月全平台 78 人第一次拿到荣耀
svip_level svip_expire_daySVIP已有SVIP 和荣耀是两条线,别混
J · 这些不要落表,读表时算
例子为什么
比率概率玩法占比、背包送出率、送礼集中度、自充率换个时间窗就要重算,落死了反而不能用
差值净消耗(获得 − 消费)、净流水(out − in)两个数都在表里,读的时候减一下就行
argmax主玩法、送得最多给谁、谁送他最多要先排序才能得到,不是一个数。落明细表,排序读表时做
跨天7 日均值、环比、连续零操作天数要读历史。宽表只存当日值
K · 这几个原来的说法太抽象,别照着落

这一节不产生字段,它是黑名单。四条全部不落表,列在这里是为了防止有人照着旧说法又提一遍。
判据:字段名念一遍,知不知道怎么算。不知道就是抽象。
2026-08-31 复核:四条的处置状态写在最右一列。

原来的说法问题在哪改成怎么落现在的状态
最大供养者到期日要先排序找出「最大供养者」,再去另一张表查他的到期日,两步;而且「供养」不是数仓里的词,第一次看见的人不知道指什么落家族礼物明细,谁最大、他哪天到期,读表时自己接已执行 · 没落
新建的 family_day 里没有这一列。② 口径拆解里的 fam_top1_expire 也已标为建议删除,改用 usr_stay_gapusr_stay_expiry
族内大R数 / 其中当前在册「当前在册」要比到期日,但说不清是哪一天的当前 —— 落表那天?读表那天?落「族内持有过荣耀的人数」这一个数就够,有效性读表时比到期日已改判 · 两列都落
原来这条批的是「当前」说不清哪一天。family_day 里把口径写死成落表那天level_expiry_day >= day),歧义就没有了,所以 fam_bigr_nfam_bigr_live 两列都留。
理由是实测差得很大:家族 26470215 开通过 12 人、当天还有效的只有 6 人。只落一个数,读表的人要自己去 join wealth_level 再比到期日,而这张表是给非技术同学直接看的
净消耗光看字段名,不知道是「获得减消费」还是「消费减获得」,符号方向要猜不落。两个数都在表里已执行 · 没落
A2 里只有 txn_coin_intxn_coin_out,没有净消耗这一列
主玩法现在只有四类 coin 列,选出来的永远不可能是群聊抽奖 —— 而它才是净流水第一落 user_scene_day 明细,主玩法读表时取还没执行
user_scene_day 这张明细表还没建,41 个场景里 38 个仍然塞在 other_coin 里。这是玩法那块唯一还欠的一件事
M · family_day 字段清单 · 家族 × 天 ★ 这次要建的表

主键 family_id, day,全站家族全量,不要只落名单里那 109 个人所在的家族。 08-30 实测全站 status=1 家族只有 2,949 个(Lv1 2,792 / Lv2 115 / Lv3 22 / Lv4 15 / Lv5 1 / Lv7 2 / Lv9 1 / Lv10 1), 一天不到三千行,全站落表的成本可以忽略。

字段是什么怎么算状态坑 / 为什么要它
family_id day主键P0
fam_name fam_owner_id fam_area fam_status家族名/族长/区域/状态ods_com_family_info_ad 同名字段,锁一个最近分区P0status 0-待审核 1-正常 2-解散,只算 1。现在报家族只有 18 位 family_id,没名字没人看得懂
fam_level家族等级ods_com_family_info_ad.level,当日快照P0 · 最关键这一列不落,就永远答不了「他们在冲级还是在保级」。这张表按天全量快照,落进来以后逐日 diff 就能拿到升降级事件,不用另外埋点
fam_member_n在册成员数family_memberstatus=1 的人数;或直接取 family_info.member_cntP0不加 status=1 会把全历史算进来,差 7,100 倍
fam_exp_day当日家族经验sum(incr_family_exp_value)create_time 切当天P0incr_user_exp_value(个人贡献)不是同一个数 —— 2026-08 全站家族经验 2,941 万、个人贡献 2,747 万,差 7%。判断等级要用家族口径那一列
fam_exp_gift fam_exp_task其中送礼 / 任务来的同上按 source 拆:1-任务 2-送礼P0这两列就是「刷」和「正常活跃」的分界线。实测 📀Tiệm Đĩa💿🎼 08-29 送礼来的经验 205,124、任务来的只有 1,200 —— 任务那条几乎是常数,异动全在送礼这一列
fam_exp_cum累计家族经验建族至今 sum(incr_family_exp_value)截至当天P0「离下一级还差多少」全靠这一列。⚠️ 见下面那条分区坑,不卡 create_time 会多算一天
fam_exp_month本月家族经验表里已有现成的 month(yyyy-MM)和 week 列,直接按它聚合P0降级是按月结算的(见下),所以「保级压力」看的是本月这一列,不是累计那一列
fam_inner_val fam_gift_val族内互送 / 族内送礼总额送收双方同 family_id 的当日金额;族内成员送给任何人的当日金额P0必须 gift_type=1。互送是分子、总额是分母,两个都要落,比率读表时算
fam_gift_pair_n互送的人对数当日族内互送去重 (user_id, target_user_id) 对数P1金额一样,2 个人对刷和 40 个人互动是两回事。没有这一列,「集中互刷」和「全族活跃」分不开
fam_recharge_cny fam_recharge_uv成员充值额 / 充值人数在册成员当日充值,按币种折人民币P1剔内部白名单。经验涨了但充值没涨 = 在花存量币,不是新进钱
fam_active_uv fam_gift_uv活跃人数 / 送礼人数当日有行为 / 有送礼记录的在册成员数P1对齐日报口径
fam_level_change升 / 降级事件昨天的 fam_level 和今天比不落表跨天,读表时算。只要 fam_level 每天落了,这个是一句 lag() 的事
离下一级还差多少门槛 − fam_exp_cum不落表门槛是配置不是数仓字段,数仓里没有这张字典表。拿产品文档里的等级表当常量配在读表侧,改了只用改一处
⚠️ 落 fam_exp_cum 之前必须知道的一个坑(2026-08-31 实测)

ods_com_family_user_exp_record_adday=X 分区里,装着 X+1 号的记录—— day='2026-08-30' 的分区里能查到 create_time 是 08-31 的行(ETL 是次日凌晨跑的)。 所以 把整个分区加起来 ≠ 截至当天的累计,必须自己再卡一层 create_time <= day
这不是纸上谈兵:家族 40209452 整个分区加起来是 1,280,807,卡掉 08-31 那部分之后是 1,220,333, 和业务侧报的数一分不差。差的那 60,474 就是 08-31 半天的量。

L · 另外两张表(粒度不同,不要塞进宽表)
粒度放什么现状
room_dayroom_id × 天当天去重人数 · 房内大R数 · 上麦人次 · 房内礼物额 · 送礼人数批次 B1 已经在跑
family_dayfamily_id × 天在册成员数 · 族内互送金额 · 族内礼物总额 · + 等级 / 经验 / 保级(见下面 M)P0 · 这次要建的就是它