
1) 【一句话结论】:采用时间分片(按天拆分表)与用户分片(按用户ID哈希分库)结合的策略,通过时间范围、用户ID、事件类型多维度索引,并按天清理数据,支撑数亿级日志的实时查询与聚合统计。
2) 【原理/概念讲解】:分库分表是水平拆分数据,提升存储与查询能力。时间分片:按日志时间(如天/小时)拆分表,比如每天一个表(log_20240101),适合按时间范围查询(如最近7天行为分析);用户分片:按用户ID哈希或范围分库,每个库存储部分用户数据,适合按用户聚合(如异常行为检测)。索引设计:时间范围索引(如时间戳范围)用于实时查询,用户ID索引用于聚合统计,事件类型索引用于分类分析。数据生命周期:根据业务需求(如保留30天),过期日志按天批量删除,避免存储膨胀。
3) 【对比与适用场景】:
| 策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 时间分片 | 按日志时间(如天/小时)拆分表 | 查询时需指定时间范围,表数量随时间增长 | 实时查询(按时间范围分析)、聚合统计(如日活跃用户) | 表数量过多可能影响元数据管理,需定期合并 |
| 用户分片 | 按用户ID哈希/范围分库 | 查询时需指定用户范围,库数量固定 | 按用户聚合(如异常行为检测)、用户画像分析 | 哈希分片可能导致热点用户数据集中,需结合范围分片 |
4) 【示例】:表结构设计(伪代码):
-- 分库分表后的表结构(以时间分片+用户分片为例)
-- 库:根据用户ID哈希到库,比如库名为 db_user_hash_1, db_user_hash_2...
-- 表:按天分表,表名为 log_20240101, log_20240102...
CREATE TABLE log_user_hash_1.log_20240101 (
id BIGINT PRIMARY KEY,
user_id BIGINT,
event_type VARCHAR(50),
event_time TIMESTAMP,
event_data JSON,
INDEX idx_user_id (user_id),
INDEX idx_event_time (event_time),
INDEX idx_event_type (event_type)
);
查询示例(实时查询):
-- 查询2024年1月1日10点-11点,用户ID为1001的日志
SELECT * FROM log_user_hash_1.log_20240101
WHERE user_id = 1001 AND event_time BETWEEN '2024-01-01 10:00:00' AND '2024-01-01 11:00:00';
聚合统计(异常行为检测):
-- 查询用户ID为1001,事件类型为"安装"的异常行为(如短时间内多次安装)
SELECT user_id, event_type, COUNT(*) as count, MIN(event_time) as first_time
FROM log_user_hash_1.log_20240101
WHERE user_id = 1001 AND event_type = 'install'
GROUP BY user_id, event_type
HAVING COUNT(*) > 5 AND MIN(event_time) BETWEEN '2024-01-01 10:00:00' AND '2024-01-01 11:00:00';
数据生命周期管理(清理过期数据):
-- 删除2024年1月1日之前的日志
DELETE FROM log_user_hash_1.log_20240101 WHERE event_time < '2024-01-01';
5) 【面试口播版答案】:各位面试官好,针对360安全卫士数亿级用户行为日志的数据库设计,我的核心思路是采用时间分片+用户分片结合的策略,通过多维度索引支撑实时查询与聚合统计,并实施数据生命周期管理。具体来说:首先,分库分表方面,按用户ID哈希分库(如每个库存储部分用户数据),按日志时间(天)分表(每天一个表,如log_20240101),这样既解决了用户数据集中问题,又便于按时间范围查询。然后,索引设计上,为时间范围查询创建时间戳范围索引(如event_time),为用户聚合统计创建用户ID索引(如user_id),为事件类型分析创建事件类型索引(如event_type),确保查询效率。数据生命周期方面,根据业务需求(如保留30天),按天批量删除过期日志,避免存储膨胀。这样设计能支撑数亿条日志的实时查询(如用户行为分析)和聚合统计(如异常行为检测)。
6) 【追问清单】:
7) 【常见坑/雷区】: