跳到主要内容

事件模型

问题

什么是事件模型?如何设计事件的数据结构?

答案

事件模型三要素

事件模型(Event Model)是用户行为数据的标准表示方式:

要素说明示例
Who谁触发的user_id、device_id
When什么时候event_time
What做了什么、附带什么信息event_name + properties
{
"event": "add_to_cart",
"user_id": "u_12345",
"device_id": "d_abcde",
"timestamp": "2024-01-15T10:30:00Z",
"properties": {
"product_id": "p_001",
"product_name": "无线耳机",
"category": "数码",
"price": 299.0,
"quantity": 1
},
"context": {
"platform": "iOS",
"app_version": "3.2.1",
"os_version": "17.2",
"network": "WiFi",
"ip": "1.2.3.4"
}
}

属性分类

类型说明示例
事件属性描述本次事件product_id、price、position
用户属性描述用户自身gender、age、vip_level
设备属性设备信息(自动采集)platform、os、screen_size
会话属性本次访问的信息session_id、referrer、utm_source

数据表结构

-- 事件明细表(DWD 层)
CREATE TABLE dwd.event_log (
event_id STRING, -- 事件唯一 ID(去重用)
event_name STRING, -- 事件名
user_id BIGINT, -- 用户 ID
device_id STRING, -- 设备 ID
event_time TIMESTAMP, -- 事件发生时间
-- 通用属性
platform STRING, -- iOS / Android / Web
app_version STRING,
page_url STRING,
-- 事件自定义属性(灵活扩展)
properties MAP<STRING, STRING>,
-- 分区
dt STRING
)
PARTITIONED BY (dt);
属性设计注意事项
  • 属性名用 snake_case,避免中文
  • 属性值尽量用枚举值而非自由文本
  • 价格等数值要明确单位(元 vs 分)
  • 预留 properties MAP 字段应对非标需求

常见面试问题

Q1: user_id 和 device_id 有什么区别?

答案

  • device_id:设备唯一标识,用户未登录时也能追踪
  • user_id:登录后的用户标识
  • 需要做 ID Mapping(关联同一用户不同设备的 device_id)

Q2: 事件属性为什么用 MAP 而不是固定列?

答案

  • 不同事件携带的属性不同(加购有 product_id,页面浏览有 page_url)
  • MAP 类型灵活扩展,新增属性不需要改表结构
  • 但 MAP 查询性能较差,高频查询的属性建议提取为独立列

相关链接