4. 行为事件建模:事件模型设计、用户画像标签与实体-行为-属性模型

好,我们进入第四章。前面几章我们把实时管道、数据采集和消息队列都聊透了,现在终于要碰最核心的东西——事件模型。

说白了,事件模型就是你对用户行为的「翻译器」。用户点了个按钮,你把它翻译成一条结构化的数据;用户下单,你把它拆成几个关键字段。翻译得好不好,直接决定了后面所有分析、画像、推荐的质量。

我个人习惯,在设计事件模型之前,先想清楚三个问题:

  • 这个行为「是谁」做的?
  • 「做了什么」?
  • 「在什么上下文」下做的?

这三个问题,对应到模型里就是实体、行为和属性。我们一个一个拆开讲。

4.1 事件模型设计(Event Schema)

事件模型,我更喜欢叫它事件骨架。它定义了每一条用户行为日志长什么样。

先看一个最简版本:

{
  "event_id": "uuid-xxxx",
  "event_time": 1712345678000,
  "event_type": "page_view",
  "user_id": "user_12345",
  "device_id": "device_abc",
  "properties": {
    "page_url": "/product/123",
    "referrer": "/search?q=shoes",
    "duration_ms": 3200
  }
}

这个结构看起来简单,但坑不少。我踩过最大的坑就是事件类型命名混乱。曾经有个项目,iOS 端叫 click_buy,Android 端叫 purchase_click,Web 端叫 buy_now_click。三个名字,同一个行为。你说这怎么分析?

我曾经犯过的错: 事件类型命名没有统一规范,导致后期清洗数据花了整整两周。后来我强制团队使用「动词_名词」的 snake_case 格式,比如 product_add_to_cart、order_submit,才彻底解决。

所以,我建议你从一开始就定好事件命名规范:

规范项 要求 示例
命名格式 动词_名词,全小写 snake_case product_view
动词选择 使用统一动词表 view、click、submit、share
名词选择 使用业务实体名 product、order、cart
禁止行为 不要带版本号、不要带平台名 ❌ click_buy_v2、ios_purchase

4.2 实体-行为-属性模型

这是事件建模的「三驾马车」。我画了一张图,帮你理解它们的关系:

实体-行为-属性模型 实体 (Entity) 行为 (Action) 属性 (Property) 谁(实体) + 做了什么(行为) + 在什么条件下(属性) = 一条完整的事件 示例:用户浏览商品详情页 实体 user_id: user_123 device_id: device_abc 行为 event_type: product_view event_time: 1712345678000 属性 page_url: /product/123 duration_ms: 3200

你看,实体是「谁」,行为是「做了什么」,属性是「在什么条件下做的」。三者缺一不可。

我遇到过不少团队,只关注行为,忽略了实体和属性。结果就是:知道有人点了按钮,但不知道是谁点的,也不知道在哪个页面点的。这种数据,基本等于废的。

4.3 用户画像标签

事件模型是「过程数据」,用户画像标签是「状态数据」。两者相辅相成。

画像标签,说白了就是给用户打上的静态或动态的标记。比如:

  • 基础标签:性别、年龄、注册渠道
  • 行为标签:近7天活跃、高价值用户、流失预警
  • 预测标签:购买意向高、复购概率大

这些标签怎么来的?从事件模型里算出来的。你想想看,如果没有规范的事件模型,你怎么算「近7天活跃」?你连用户哪天登录了都不知道。

我的经验: 画像标签不要贪多。我见过一个项目打了 500 多个标签,结果 80% 从来没被用过。我建议你从业务最关心的 10-20 个核心标签开始,跑通了再扩展。

标签的存储,我推荐用宽表 + Redis的组合:

-- 用户画像宽表示例
CREATE TABLE user_profile (
    user_id         STRING PRIMARY KEY,
    gender          STRING,
    age_group       STRING,
    register_channel STRING,
    last_active_dt  STRING,
    active_7d_cnt   INT,
    is_high_value   BOOLEAN,
    purchase_intent FLOAT,
    update_time     TIMESTAMP
);

实时场景下,标签更新频率很高。我习惯用 Flink 消费事件流,实时计算标签,然后写入 Redis。查询时直接读 Redis,毫秒级响应。

4.4 事件模型与画像标签的联动

这两者不是孤立的。事件模型是「原料」,画像标签是「成品」。没有好的原料,做不出好的成品。

我举个例子:

  1. 用户浏览商品 → 事件模型记录 product_view
  2. Flink 消费这个事件,更新用户的「最近浏览商品ID」标签
  3. 用户再次访问时,推荐系统读取这个标签,推荐相关商品

你看,整个链路是通的。事件模型的质量,直接决定了画像标签的准确度。

核心原则: 事件模型要「全」——覆盖所有关键行为;画像标签要「精」——只保留有业务价值的标签。两者配合,才能支撑起实时推荐、实时风控、实时运营等场景。