03 | 直播间最大在线人数


目录

一、问题定义与业务场景

二、数据准备与建表语句

2.1 建表语句

2.2 样例数据

三、SQL解决方案

3.1 核心思路

3.2 完整代码

3.3 执行步骤详解

四、边界情况与优化

4.1 边界场景处理

4.2 性能优化方案

4.3 变体问题扩展

五、总结


一、问题定义与业务场景

目标:统计每个直播间在任意时刻的最大同时在线人数
数据特征

  • 用户进入直播间时记录in_datetime,离开时记录out_datetime
  • 同一用户可能多次进出同一直播间(需独立计算)。

应用场景:直播流量监控、服务器资源分配、主播绩效评估。


二、数据准备与建表语句

2.1 建表语句

CREATE TABLE live_events (
    user_id BIGINT COMMENT '用户ID',
    live_id INT COMMENT '直播间ID',
    in_datetime DATETIME COMMENT '进入时间',
    out_datetime DATETIME COMMENT '离开时间'
) COMMENT '直播间访问记录表';

2.2 样例数据

INSERT INTO live_events VALUES
(100, 1, '2025-06-01 19:05:00', '2025-06-01 19:25:00'),
(100, 1, '2025-06-01 19:30:00', '2025-06-01 19:53:00'),
(101, 1, '2025-06-01 19:15:00', '2025-06-01 20:30:00'),
(102, 1, '2025-06-01 19:20:00', '2025-06-01 19:40:00'),
(103, 2, '2025-06-01 21:01:00', '2025-06-01 22:00:00'),
(104, 2, '2025-06-01 21:05:00', '2025-06-01 21:30:00');

三、SQL解决方案

3.1 核心思路

  1. 事件标记:将进入记为+1,离开记为-1,合并为统一时间线。
  2. 累积求和:按直播间分区,按时间排序,实时计算在线人数。
  3. 峰值提取:取每个直播间的累积人数最大值。

3.2 完整代码

SELECT
    live_id,
    MAX(online_count) AS max_user_count
FROM (
    SELECT
        live_id,
        event_time,
        SUM(user_change) OVER (
            PARTITION BY live_id 
            ORDER BY event_time, user_change DESC
        ) AS online_count
    FROM (
        -- 进入事件(标记+1)
        SELECT 
            user_id, 
            live_id, 
            in_datetime AS event_time, 
            1 AS user_change
        FROM live_events
        UNION ALL
        -- 离开事件(标记-1)
        SELECT 
            user_id, 
            live_id, 
            out_datetime AS event_time, 
            -1 AS user_change
        FROM live_events
    ) combined_events
) cumulative_sum
GROUP BY live_id;

计算结果:

3.3 执行步骤详解

步骤

关键操作

作用

示例数据(live_id=1)

1. 合并事件

UNION ALL 合并进出记录

生成统一时间序列

(in, 19:05:00, +1) → 进入

(out, 19:25:00, -1) → 离开

2. 累积求和

SUM() OVER(PARTITION BY live_id)

实时计算每个时间点在线人数

19:15:00:累计2人(连续进入)

3. 峰值提取

MAX(online_count)

取直播间内累积人数的最大值

直播间1的峰值:3人


四、边界情况与优化

4.1 边界场景处理

  • 同时发生事件
    • 若同一毫秒既有进入也有离开,需确保离开事件优先计算(通过ORDER BY event_time, user_change DESC实现)。
    • 例如:19:30:00同时进入1人离开1人,优先计算-1避免虚高。

4.2 性能优化方案

  • 索引设计(MySQL/PostgreSQL):
CREATE INDEX idx_live_time ON live_events(live_id, in_datetime, out_datetime);
  • 数据倾斜处理(超大直播间): 对于不同查询引擎,设置相应的参数
SET spark.sql.shuffle.partitions=200;  -- 增加Shuffle分区数

4.3 变体问题扩展

  • 全局最大在线人数(不分直播间):
SELECT MAX(online_count) 
FROM cumulative_sum; 

五、总结

  • 核心方法UNION ALL合并事件 + SUM() OVER()累积计算是最高效的解法。
  • 面试陷阱
    • 事件同时性处理;
    • 用户快速进出时的去重逻辑(样例数据中user_id=100在直播间1进出两次)。
  • 真题参考:字节跳动、阿里等大厂高频考题,扩展问题常涉及“实时在线人数曲线”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走过冬季

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值