51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在移动客户端中,需要存储用户信息和好友关系。用户表包含用户ID、昵称、头像URL、注册时间等字段;好友关系表包含用户ID和好友ID。请设计这两个表的结构,并说明索引策略、分库分表策略(如果需要),以及如何处理高并发下的查询和写入性能。

Tencent软件开发-移动客户端开发方向难度:中等

答案

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) 【追问清单】

  • 问题1:为什么用户表用UUID而不是自增ID?
    回答要点:UUID全局唯一,避免跨库ID冲突,移动端用户ID安全。
  • 问题2:好友关系表用自增ID作为主键是否合理?
    回答要点:自增ID是本地递增,跨库查询慢,但好友关系表数据量小,且用联合唯一索引保证唯一性,所以合理。
  • 问题3:分库分表的具体策略是什么?
    回答要点:用户表按用户ID范围分库(模3),分表按ID范围(模100);好友关系表按用户ID分库(与用户表一致),分表按ID范围(模100),保证关联性。
  • 问题4:如何处理高并发下的写入性能?
    回答要点:批量插入(事务批量操作)、读写分离(主库写,从库读)、缓存穿透/雪崩的应对(如布隆过滤器、限流)。
  • 问题5:缓存策略如何设计?
    回答要点:用户信息用Redis缓存(key为user_id,value为用户信息),好友关系用Redis缓存(key为user_id+friend_id,value为好友关系),设置合理的过期时间(如用户信息1小时,好友关系5分钟)。

7) 【常见坑/雷区】

  • 坑1:好友关系表用自增ID作为主键,导致跨库查询慢。
  • 坑2:索引未覆盖查询,导致全表扫描。
  • 坑3:分库分表未保证关联性。
  • 坑4:未考虑缓存策略。
  • 坑5:分库分表策略不合理(如按时间分表导致热点数据集中)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1