事件模型
问题
什么是事件模型?如何设计事件的数据结构?
答案
事件模型三要素
事件模型(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 分)
- 预留
propertiesMAP 字段应对非标需求
常见面试问题
Q1: user_id 和 device_id 有什么区别?
答案:
device_id:设备唯一标识,用户未登录时也能追踪user_id:登录后的用户标识- 需要做 ID Mapping(关联同一用户不同设备的 device_id)
Q2: 事件属性为什么用 MAP 而不是固定列?
答案:
- 不同事件携带的属性不同(加购有 product_id,页面浏览有 page_url)
- MAP 类型灵活扩展,新增属性不需要改表结构
- 但 MAP 查询性能较差,高频查询的属性建议提取为独立列