
1) 【一句话结论】用户表以用户ID(UUID)为主键,好友关系表用自增ID+联合主键,通过覆盖索引优化查询,分库分表按ID范围划分,结合读写分离、缓存和批量操作提升高并发下的读写性能。
2) 【原理/概念讲解】
首先解释用户表结构:用户ID是唯一标识(移动端用UUID更安全),包含昵称、头像URL、注册时间等字段。为昵称、头像URL、注册时间添加索引,因为这些都是用户查询和展示的关键字段(如按昵称搜索、展示头像、按注册时间筛选)。
好友关系表设计:使用自增ID作为主键(或联合主键),同时设置用户ID和好友ID为外键(或联合唯一索引),避免重复好友关系(如用户A和B互为好友,只存一条记录)。
索引策略:主键索引是B+树结构,查询效率极高;覆盖索引(包含查询所需的所有字段)减少I/O,提升性能(如查询用户信息时,若索引包含所有字段,无需回表)。
分库分表:用户表按用户ID范围分库(如每库存储1万用户,按ID模3分库),分表按时间或ID范围(如按注册时间分表);好友关系表按用户ID分库(与用户表一致保证关联性),分表按ID范围(如按用户ID模100分表)。
高并发处理:查询时用Redis缓存用户信息和好友关系数据(减少数据库压力);写入时用批量插入(事务批量操作)减少锁竞争;读写分离(主库写,从库读)提升读性能;热点数据(如热门用户)用分布式缓存预热(进一步优化性能)。
3) 【对比与适用场景】
| 索引类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 主键索引 | 表的唯一标识字段 | B+树结构,唯一且有序,查询效率极高 | 表的主键 | 必须唯一,不能重复 |
| 唯一索引 | 字段值唯一 | B+树,保证字段唯一性 | 需要唯一约束的字段(如昵称、邮箱) | 不能有重复值 |
| 普通索引 | 提升查询效率 | B+树,非唯一 | 频繁查询的字段(如昵称、头像URL) | 占用空间大,插入慢 |
| 策略 | 定义 | 特性 | 使用场景 | 注意点 |
| 垂直分库分表 | 按业务模块拆分表 | 每个库/表只存储部分字段 | 业务模块多,字段量大的场景 | 需要跨库关联,复杂度高 |
| 水平分库分表 | 按数据量或ID范围拆分 | 每个库/表存储完整字段 | 数据量大,单表数据多 | 需要保证关联性(如外键) |
4) 【示例】
用户表SQL:
CREATE TABLE user_info (
user_id VARCHAR(36) PRIMARY KEY, -- UUID,唯一标识
nickname VARCHAR(50) NOT NULL,
avatar_url VARCHAR(255) NOT NULL,
register_time DATETIME NOT NULL,
nickname_idx UNIQUE KEY (nickname),
avatar_url_idx INDEX (avatar_url),
register_time_idx INDEX (register_time)
) ENGINE=InnoDB;
好友关系表SQL:
CREATE TABLE friend_relation (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
friend_id VARCHAR(36) NOT NULL,
UNIQUE KEY (user_id, friend_id) -- 联合唯一索引,避免重复好友关系
) ENGINE=InnoDB;
分库分表逻辑(假设分库分表工具):
user_id % 3分库(库0-2),分表:按user_id % 100分表(表0-99)。user_id % 3分库(与用户表一致保证关联性),分表:按user_id % 100分表(与用户表一致)。5) 【面试口播版答案】
面试官您好,针对移动客户端的用户信息和好友关系存储需求,我的设计思路如下:首先设计用户表,以用户ID(UUID)为主键,包含昵称、头像URL、注册时间等字段,为昵称、头像URL、注册时间添加索引,因为这些都是用户查询和展示的关键字段。然后设计好友关系表,使用自增ID作为主键,同时设置用户ID和好友ID为联合主键(或唯一索引),避免重复好友关系。索引策略上,主键索引保证高效查询,覆盖索引(如用户表包含查询所需的所有字段)减少I/O,提升性能。分库分表方面,用户表按用户ID范围分库(比如每库存储1万用户,按ID模3分库),分表按时间或ID范围(如按注册时间分表);好友关系表按用户ID分库(与用户表一致保证关联性),分表按ID范围。高并发处理上,查询时用Redis缓存用户信息和好友关系数据,减少数据库压力;写入时用批量插入(如事务批量操作)减少锁竞争;读写分离(主库写,从库读)提升读性能;热点数据(如热门用户)用分布式缓存预热,进一步优化性能。
6) 【追问清单】
7) 【常见坑/雷区】