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

在社交应用中,如何设计用户关系图谱(好友关系、关注关系)的数据库表结构?请考虑索引设计、查询性能以及如何支持实时更新(如好友添加)。

Tencent软件开发-测试开发方向难度:中等

答案

1) 【一句话结论】采用以用户为中心的多表关联设计(用户表、好友表、关注表),通过联合主键优化查询,结合索引和消息队列实现高效查询与实时更新。

2) 【原理/概念讲解】同学们,设计用户关系图谱时,核心是处理“用户-关系-用户”的关联。常见模式是星型架构——以用户表为核心,通过好友表(记录双向好友关系)和关注表(单向关注关系)扩展。比如,用户A关注用户B,在关注表中存A->B的记录。表结构上,用户表用自增ID,关系表用(用户ID1, 用户ID2)作为联合主键(唯一标识关系),避免重复。索引方面,主键自增ID天然有序,关系表的主键索引能加速查找;同时为用户ID字段建索引,支持按用户ID筛选关系。实时更新时,新增好友后,通过消息队列(如Kafka)通知相关表更新,再触发缓存刷新,保证数据一致性。

3) 【对比与适用场景】

设计方式定义特性使用场景注意点
单表存储将所有关系存入一张表(如user_relations,字段:user_id1, user_id2, relation_type, created_at)数据冗余(如A-B和B-A重复),查询时需去重小型应用,关系简单查询性能差,扩展性弱
多表关联用户表 + 好友表(双向,user_id1, user_id2)+ 关注表(单向,follower_id, followee_id)结构清晰,无冗余,支持复杂查询大型社交应用,关系复杂需处理多表关联查询,索引设计关键

4) 【示例】

-- 创建用户表
CREATE TABLE users (
    user_id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 创建好友表(双向,无冗余)
CREATE TABLE friendships (
    user_id1 INT NOT NULL,
    user_id2 INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (user_id1, user_id2),
    FOREIGN KEY (user_id1) REFERENCES users(user_id),
    FOREIGN KEY (user_id2) REFERENCES users(user_id)
);

-- 创建关注表(单向)
CREATE TABLE follows (
    follower_id INT NOT NULL,
    followee_id INT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (follower_id, followee_id),
    FOREIGN KEY (follower_id) REFERENCES users(user_id),
    FOREIGN KEY (followee_id) REFERENCES users(user_id)
);

-- 插入数据示例
INSERT INTO users (username) VALUES ('Alice'), ('Bob'), ('Charlie');

-- 添加好友(Alice和Bob互加好友)
INSERT INTO friendships (user_id1, user_id2) VALUES (1, 2), (2, 1);

-- Alice关注Charlie
INSERT INTO follows (follower_id, followee_id) VALUES (1, 3);

-- 查询Alice的好友
SELECT u.username FROM users u JOIN friendships f ON u.user_id = f.user_id2 WHERE f.user_id1 = 1;

-- 查询Alice的关注列表
SELECT u.username FROM users u JOIN follows f ON u.user_id = f.followee_id WHERE f.follower_id = 1;

5) 【面试口播版答案】面试官您好,针对社交应用的用户关系图谱设计,我的核心思路是采用以用户为中心的多表关联模式。具体来说,我会设计用户表存储用户基本信息,然后通过好友表(双向关系,用联合主键避免冗余)和关注表(单向关系)来记录连接。索引方面,好友表和关注表的主键(联合主键)天然支持高效查询,同时为用户ID字段建索引,加速按用户ID筛选关系。对于实时更新,比如好友添加,我会通过消息队列(如Kafka)接收新增事件,触发数据库更新后同步缓存,确保查询性能和实时性。这样既能保证数据结构清晰,又能优化查询和实时更新能力。

6) 【追问清单】

  • 问题1:如果关系类型不止好友和关注,比如群组、共同好友,如何扩展设计?回答要点:新增关系类型表,存储关系类型ID和描述,在好友/关注表中增加type_id字段,通过外键关联。
  • 问题2:如果需要查询“共同好友”或“关注链”,如何优化查询性能?回答要点:使用连接查询(JOIN)结合索引,或者预计算共同好友表(定期更新),或者利用图数据库(如Neo4j)的图遍历优化。
  • 问题3:如果用户数据量极大(千万级),如何保证索引性能?回答要点:分库分表,按用户ID哈希分片,或者使用覆盖索引(索引包含查询所需的所有字段)。

7) 【常见坑/雷区】

  • 坑1:单表存储导致数据冗余和查询性能下降,容易忽略多表关联的优势。
  • 雷区2:索引设计错误,比如只建单字段索引,而联合主键未建索引,导致多表关联查询慢。
  • 坑3:实时更新未考虑并发和消息队列,直接数据库更新可能导致数据不一致或延迟。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1