本文档说明平台埋点统计系统的 表结构、分层关系、数据流向、关联键与查询口径。
与前端埋点接入指南.md(接入 API)配合使用。
文档版本:v1.0
最后更新:2026-06-17
DDL 来源:alien-entity/src/main/resources/db/migration/analytics_schema.sql(新环境)
旧环境升级:analytics_tables_dashboard_upgrade.sql
| 目标 | 实现方式 |
|---|---|
| 原始行为可追溯 | 所有 scene 落 analytics_event 流水 |
| 看板查询快 | 按自然日预聚合到 analytics_daily_summary |
| 明细分页/下钻 | 用户/商家/内容等 *_stat 明细表 |
| 当日准实时 | 埋点同步写 *_today,每小时跑批覆盖 |
| 历史可查 | 零点归档到 *_history,保留 30 天 |
核心原则:数据库层 不设外键;表之间通过 user_id、merchant_id、content_type + content_id、stat_date、event_code 等字段 逻辑关联。
共 4 张基础表 + 12 张明细表(6 组 today/history)。
| 表名 | Java 实体 | 粒度 | 说明 |
|---|---|---|---|
analytics_event |
AnalyticsEvent |
每条埋点事件 | 原始日志,所有统计的源头 |
analytics_ai_request |
AnalyticsAiRequest |
每次 AI API 调用 | 响应耗时,不写 event 表 |
analytics_daily_summary |
AnalyticsDailySummary |
每天 1 行 | 四页看板 KPI 宽表 |
analytics_stat_job_log |
AnalyticsStatJobLog |
每次跑批任务 | 运维排查用 |
| 今日表 | 历史表 | Java 实体(today / history) | 唯一键 |
|---|---|---|---|
analytics_user_stat_today |
analytics_user_stat_history |
AnalyticsUserStatToday / AnalyticsUserStat |
user_id / (stat_date, user_id) |
analytics_merchant_stat_today |
analytics_merchant_stat_history |
AnalyticsMerchantStatToday / AnalyticsMerchantStat |
merchant_id / (stat_date, merchant_id) |
analytics_content_stat_today |
analytics_content_stat_history |
AnalyticsContentStat / AnalyticsContentStatHistory |
(content_type, content_id) / (stat_date, content_type, content_id) |
analytics_category_daily_today |
analytics_category_daily_history |
AnalyticsCategoryDailyToday / AnalyticsCategoryDaily |
business_category / (stat_date, business_category) |
analytics_ai_chat_stat_today |
analytics_ai_chat_stat_history |
AnalyticsAiChatStat / AnalyticsAiChatStatHistory |
chat_id / (stat_date, chat_id) |
analytics_report_record_today |
analytics_report_record_history |
AnalyticsReportRecord / AnalyticsReportRecordHistory |
report_id / (stat_date, report_id) |
┌─────────────────────────────────────────────────────────────────┐
│ L0 接入层 POST /analytics/front/* + POST /analytics/detail/* │
└───────────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────┼───────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ analytics_event│ │ analytics_ai_ │ │ *_today 明细表 │
│ (事件流水) │ │ request │ │ (当日增量/快照) │
└───────┬───────┘ └────────┬────────┘ └────────┬─────────┘
│ │ │
│ POST /analytics/stat/calculate(定时/手动) │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ L2 汇总层 analytics_daily_summary(按 stat_date 一行 KPI) │
│ L1 明细层 *_today 覆盖/补全 + 历史日写入 *_history(补跑时) │
└───────────────────────────────┬─────────────────────────────────┘
│ 零点 analyticsArchiveDaily
▼
*_history(stat_date=昨日,保留 30 天)
│
▼
GET /analytics/*/charts、/summary(报表读层)
| 层级 | 表 | 职责 |
|---|---|---|
| L0 原始 | analytics_event、analytics_ai_request |
保留完整行为流水;支持漏斗下钻、复杂去重、cohort 留存 |
| L1 明细 | *_stat_*、*_daily_*、report_record_* |
按用户/商家/内容/品类/会话/举报预聚合,支撑明细分页与 TOP 榜 |
| L2 汇总 | analytics_daily_summary |
按自然日一行,支撑看板 KPI 卡片与趋势图 |
入口:AnalyticsTrackServiceImpl
路径:POST /analytics/front/report(及 register/login/logout/heartbeat 等专用接口)
每次成功上报的典型步骤:
scene 映射为 event_code,插入 analytics_event(event_id 幂等)*_today 表(非全部 scene 都会写明细,见下表)| scene / 接口 | event_code | 同步写明细 |
|---|---|---|
APP_LAUNCH 等通用 report |
user.launch 等 |
部分场景仅写 event |
USER_HEARTBEAT / heartbeat |
user.heartbeat |
user_stat_today(last_active_time、在线时长) |
APP_REGISTER / user/register |
user.register |
user_stat_today |
USER_LOGIN / USER_LOGOUT |
user.login / user.logout |
user_stat_today |
MERCHANT_VIEW / merchant/view |
merchant.view |
merchant_stat_today(visit_uv/pv) |
CONTENT_INTERACT |
content.interact |
content_stat_today(互动计数) |
AUDIT_* |
audit.* |
content_stat_today(审核状态) |
REPORT_SUBMIT / REPORT_HANDLE |
report.* |
report_record_today |
AI_CHAT_END |
ai.chat.end |
event + 建议 /detail/ai-chat 写 ai_chat_stat_today |
POST /analytics/front/ai-request |
— | 仅 analytics_ai_request |
POST /analytics/detail/* |
可选 | 直接 upsert 对应 *_today |
明细路由:AnalyticsDetailStoreServiceImpl 根据 statDate 是否为当天,自动选择写 *_today 或 *_history。
入口:AnalyticsStatisticsServiceImpl.calculate(statDate, scope, triggerType)
触发:
| 方式 | 接口 / 任务 |
|---|---|
| 手动 | POST /analytics/stat/calculate |
| 每小时 | XXL-JOB analyticsCalculateTodayHourly(建议 cron: 5 5 * * * ?) |
| 前日完整 | XXL-JOB analyticsCalculateYesterdayDaily(0 0 2 * * ?) |
| 次日留存 | XXL-JOB analyticsCalculateRetention(0 0 3 * * ?) |
scope 与任务对应:
| scope | 方法 | 输出表 |
|---|---|---|
USER |
calculateUserStat |
user_stat_* |
MERCHANT |
calculateMerchantStat |
merchant_stat_* |
MERCHANT |
calculateCategoryDaily |
category_daily_* |
CONTENT |
calculateContentStat |
content_stat_* |
AI_CHAT |
calculateAiChatStat |
(明细主要由 detail 接口维护) |
DAILY |
calculateDailySummary |
analytics_daily_summary |
ALL |
以上全部 | — |
跑批 以 analytics_event 为主数据源,对明细表做 覆盖/补全(非简单 +1 累加),再汇总到 daily_summary。
入口:AnalyticsArchiveServiceImpl.archiveYesterday()
任务:XXL-JOB analyticsArchiveDaily(0 0 0 * * ?)
1. INSERT *_history ← SELECT * FROM *_today(stat_date = 昨日)
2. DELETE *_history WHERE stat_date < 今天 - 30 天
3. TRUNCATE *_today
不归档的表:
analytics_event(需单独制定清理/分区策略)analytics_ai_requestanalytics_daily_summary(按 stat_date 长期保留)| 维度 | 字段 | 出现位置 |
|---|---|---|
| 用户 | user_id |
event、user_stat、ai_chat_stat、report_record |
| 商家 | merchant_id |
event、merchant_stat |
| 内容 | content_type + content_id(event 中为 target_id) |
event、content_stat、report_record |
| 自然日 | stat_date |
history 表 daily_summary |
| 经营品类 | business_category (1–7) |
event、category_daily |
| 店铺类型 | shop_type (1–3) |
event、merchant_stat |
| 举报单 | report_id(通常 = 提交时 event_id) |
report_record |
analytics_event
├─ user_id ──────────► analytics_user_stat_*.user_id
├─ merchant_id ──────► analytics_merchant_stat_*.merchant_id
├─ content_type + target_id ► analytics_content_stat_*.content_type + content_id
├─ business_category ► analytics_category_daily_*.business_category
└─ event_time 按日聚合 ► analytics_daily_summary.stat_date
analytics_ai_request.created_time 按日聚合 ► daily_summary.ai_request_count / 响应时长
analytics_report_record ◄── REPORT_SUBMIT/HANDLE(report_id 关联)
报表 Mapper 普遍使用 UNION ALL:
-- 历史段
SELECT ... FROM analytics_xxx_stat_history
WHERE stat_date >= #{startDate} AND stat_date <= #{endDate}
UNION ALL
-- 查询区间包含「今天」时追加
SELECT ... FROM analytics_xxx_stat_today
WHERE #{endDate} >= CURDATE() AND #{startDate} <= CURDATE()
含义:
*_today:当前自然日内的 累计快照(每个实体最多 1 行)*_history:每个 stat_date 一行历史快照(保留 30 天)前端传 scene,后端枚举见 AnalyticsScene,落库 event_code 见 AnalyticsEventCode。
| scene | event_code | 主要影响 |
|---|---|---|
APP_LAUNCH |
user.launch |
event → DAU、user_stat |
APP_REGISTER |
user.register |
event → 新增用户、user_stat.is_new_user |
REGISTER_PAGE |
user.register.page |
注册漏斗 |
REGISTER_PHONE |
user.register.phone |
注册漏斗 |
REGISTER_OTP |
user.register.otp |
注册漏斗 |
REGISTER_PASSWORD |
user.register.password |
注册漏斗 |
USER_LOGIN |
user.login |
event、user_stat |
USER_LOGOUT |
user.logout |
event、在线时长 |
USER_HEARTBEAT |
user.heartbeat |
event、user_stat.last_active_time、在线时长 |
| scene | event_code | 主要影响 |
|---|---|---|
MERCHANT_EXPOSE |
merchant.expose |
漏斗曝光、merchant_stat.expose_count |
MERCHANT_CLICK |
merchant.click |
漏斗点击 |
MERCHANT_DETAIL |
merchant.detail |
漏斗详情 |
MERCHANT_CONTACT |
merchant.contact |
漏斗电话/导航 |
MERCHANT_VIEW |
merchant.view |
商家 UV、merchant_stat.visit_uv/pv |
MERCHANT_VERIFY |
merchant.verify |
核销、转化率分母/分子 |
MERCHANT_REVIEW |
merchant.review |
评价率 |
PAY_SUCCESS |
pay.success |
GMV、merchant_stat.gmv、转化率 |
| scene | event_code | 主要影响 |
|---|---|---|
CONTENT_PUBLISH |
content.publish |
发布数、content_stat |
CONTENT_INTERACT |
content.interact |
互动数(eventSubtype: like/comment/share) |
AUDIT_SUBMIT |
audit.submit |
审核提交 |
AUDIT_PASS |
audit.pass |
审核通过 |
AUDIT_REJECT |
audit.reject |
审核驳回 |
REPORT_SUBMIT |
report.submit |
report_record、举报率分母 |
REPORT_HANDLE |
report.handle |
report_record.status、举报率分子 |
| scene | event_code | 主要影响 |
|---|---|---|
AI_CHAT_START |
ai.chat.start |
event |
AI_CHAT_MESSAGE |
ai.chat.message |
event |
AI_CHAT_END |
ai.chat.end |
对话次数 KPI、ai_chat_stat |
| (独立接口)ai-request | — | analytics_ai_request → 平均响应时间 |
analytics_event 字段说明| 字段 | 说明 | 典型用途 |
|---|---|---|
event_id |
幂等 UUID | 防重复上报 |
event_code |
事件编码 | 聚合分组 |
event_subtype |
子类型 | 互动 like/comment/share;审核 pass/reject;举报处理时传原 report_id |
user_id |
用户 | DAU、漏斗下钻 |
merchant_id |
商家 | 商家漏斗、GMV |
target_id |
目标 ID | 内容 ID、订单 ID |
content_type |
1动态 2打卡 3二手 | 内容维度 |
business_category |
1–7 经营品类 | 品类 GMV 分布 |
shop_type |
1–3 店铺类型 | 商家分类 |
amount |
金额(元) | GMV、客单价 |
duration_ms |
毫秒 | 心跳/会话时长 |
device_type / channel / city |
设备/渠道/城市 | 画像、地域 TOP10 |
event_time |
事件发生时间 | 划分 stat_date |
analytics_daily_summary 字段血缘每行对应一个 stat_date(自然日),由 calculateDailySummary 写入。
| 字段 | 计算口径(主要来源) |
|---|---|
dau |
COUNT(DISTINCT user_id) @ event(当日活跃) |
mau |
近 30 日 event 去重活跃 |
new_user_count |
user.register 事件数 |
register_page_view_count … register_success_count |
注册漏斗各 step 的 event 计数 |
ai_chat_count / ai_chat_user_count |
ai.chat.end 次数 / 去重用户 |
content_publish_count |
content.publish |
content_interaction_count |
content.interact |
merchant_visit_uv |
商家访问去重 UV |
merchant_expose_count … merchant_contact_count |
merchant_stat 汇总或 event |
ai_response_duration_total_ms / ai_request_count |
analytics_ai_request |
online_user_count |
跑批快照(实时在线查 user_stat_today) |
pay_user_count / today_gmv / avg_order_amount |
pay.success |
conversion_rate / today_conversion_rate |
支付用户数 / DAU |
verify_rate |
核销数 / 商家访问 UV |
merchant_review_rate |
merchant.review / merchant.verify |
audit_* / audit_pass_rate |
审核 event |
report_submit_count / report_handle_count / report_handle_rate |
举报 event |
next_day_retention_rate |
T-1 注册用户中 T 日活跃比例(写在前日行) |
last_7d_new_user_count / last_7d_active_user_count |
滑动窗口 event 去重 |
total_settled_merchant_count |
merchant_stat 入驻商家数 |
analytics_user_stat_*| 字段 | 来源 |
|---|---|
first_launch_time / last_active_time |
event 聚合 / 心跳实时更新 |
online_duration_min |
heartbeat + logout 的 duration_ms 累计 |
is_new_user |
当日是否有 user.register |
gender / age_group / channel / city |
注册或 detail 接口 |
关联:user_id;看板「当前在线」查 user_stat_today.last_active_time 近 5 分钟。
analytics_merchant_stat_*| 字段 | 来源 |
|---|---|
visit_uv / visit_pv |
merchant.view |
expose_count … contact_count |
漏斗 event |
verify_count |
merchant.verify |
review_count / review_rate |
merchant.review / verify |
gmv / pay_count / pay_user_count |
pay.success |
verify_conversion_rate |
verify / visit_uv |
settle_time / settle_status |
入驻 detail |
关联:merchant_id。
analytics_content_stat_*| 字段 | 来源 |
|---|---|
interaction_count / like_count 等 |
content.interact |
publish_time / status |
content.publish、业务状态 |
audit_status / audit_time |
audit.* event 或 detail |
关联:(content_type, content_id)。
analytics_category_daily_*按 business_category(1–7)汇总当日 GMV、支付笔数、商家 UV、内容发布/互动。
analytics_report_record_*| 字段 | 说明 |
|---|---|
report_id |
举报单号(提交时 event_id) |
content_id / content_title / report_type |
举报对象 |
status |
0 处理中 / 1 已处理 |
report_time / handle_time |
提交/处理时间 |
| 能力 | 优先读取 | 回退 / 补充 |
|---|---|---|
| 看板 8 KPI 卡片 | daily_summary + 周期对比 |
event 现场聚合 |
| 趋势图(多日) | daily_summary |
今日按小时查 event |
| 商家/注册漏斗 | merchant_stat_* / daily_summary 漏斗字段 |
event |
| 漏斗下钻明细分页 | analytics_event |
— |
| 用户/商家/内容明细分页 | *_today ∪ *_history |
— |
| 留存 cohort | event 跨日 join | daily_summary.next_day_retention_rate |
| 当前在线(TODAY) | user_stat_today.last_active_time |
— |
| 举报列表 | report_record_today ∪ report_record_history |
— |
| AI 平均响应 | daily_summary 或 analytics_ai_request |
— |
| 多日 UV 整段去重 | analytics_event |
勿简单 SUM 每日 UV |
设计原则:
daily_summary*_statanalytics_eventAPP_LAUNCH / 活跃行为
→ analytics_event (user_id, event_time)
→ calculateDailySummary → daily_summary.dau
→ GET /analytics/dashboard/summary → activeUser.value
多日周期:countActiveUsersInRange 直接扫 event 整段去重。
USER_HEARTBEAT (durationMs)
→ analytics_event
→ user_stat_today.last_active_time(实时更新)
→ countOnlineSince(5min) / summary.onlineUser
仅 period=TODAY 为实时;其他周期不展示 5 分钟窗口值。
REPORT_SUBMIT → event + report_record_today
REPORT_HANDLE → event + report_record 更新 status=1
→ daily_summary.report_handle_rate = handle / submit
→ content-report.summary.reportHandleRate
MERCHANT_REVIEW / MERCHANT_VERIFY
→ merchant_stat.review_rate(商家维度)
→ daily_summary.merchant_review_rate(平台日)
→ merchant-report.reviewRateTrend
| 职责 | 类 |
|---|---|
| 埋点写入 | AnalyticsTrackServiceImpl |
| 明细存取路由 | AnalyticsDetailStoreServiceImpl |
| 跑批统计 | AnalyticsStatisticsServiceImpl |
| 零点归档 | AnalyticsArchiveServiceImpl |
| 看板查询 | AnalyticsDashboardServiceImpl |
| 用户/内容/商家报表 | Analytics*ReportServiceImpl |
| scene / event 枚举 | AnalyticsScene、AnalyticsEventCode |
| 文件 | 用途 |
|---|---|
AnalyticsEventMapper.java |
event 聚合 SQL(@Select) |
AnalyticsDashboardMapper.xml |
看板趋势、漏斗、留存 |
AnalyticsUserReportMapper.xml |
用户报表 |
AnalyticsContentReportMapper.xml |
内容报表 |
AnalyticsMerchantReportMapper.xml |
商家报表 |
AnalyticsFunnelMapper.xml |
漏斗下钻 |
AnalyticsArchiveMapper.xml |
归档 / TRUNCATE |
| Job 名称 | 建议 Cron | 说明 |
|---|---|---|
analyticsArchiveDaily |
0 0 0 * * ? |
明细 today → history |
analyticsCalculateTodayHourly |
5 5 * * * ? |
当日准实时汇总(避开零点归档) |
analyticsCalculateYesterdayDaily |
0 0 2 * * ? |
前日完整汇总 |
analyticsCalculateRetention |
0 0 3 * * ? |
次日留存写前日行 |
analytics_schema.sqlPOST /analytics/stat/calculate 补历史日执行 analytics_tables_dashboard_upgrade.sql,必要时按脚本末尾说明将旧单表 RENAME 为 *_today。
| 现象 | 原因 | 建议 |
|---|---|---|
| 明细与 event 短暂不一致 | 实时写 today,跑批后按 event 覆盖 | 以跑批后为准 |
| 看板无数据 | 未跑 calculate 或 daily_summary 无该行 |
补跑跑批 |
| 今日与历史拼接断层 | 未跑归档或 today 已 TRUNCATE | 检查 archive 任务 |
| 多日 UV 偏大 | 误用 SUM(日 UV) | 改用 event 周期去重 |
| 接口 | 用途 |
|---|---|
POST /analytics/stat/calculate |
指定 statDate、scope 跑批 |
POST /analytics/stat/archive |
手动触发昨日归档 |
/analytics/front/* + 本文档所述表,代码在 shop.alien.store.controller.analytics 包下。@TrackEvent 注解 + POST /track/event,见 埋点接口清单.md,与 analytics 表 相互独立。| 文档 | 内容 |
|---|---|
前端埋点接入指南.md |
前端 scene、请求示例、看板 API |
埋点接口清单.md |
旧 @TrackEvent 接口列表 |
analytics_schema.sql |
完整 DDL |
analytics_tables_dashboard_upgrade.sql |
旧库增量升级 |
维护说明:表结构或跑批逻辑变更时,请同步更新本文档与 analytics_schema.sql 头部注释。