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

设计游戏用户数据(如用户信息、角色属性)和交易数据的存储方案,请说明数据库选择、表结构设计、索引策略及分库分表策略。

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

答案

1) 【一句话结论】:针对游戏用户数据(用户信息、角色属性)和交易数据,采用MySQL InnoDB存储核心结构化数据(支持强事务、行级锁),结合Redis缓存热点数据;通过垂直分库(按业务模块)与水平分片(按ID范围/时间)实现分库分表,针对角色属性动态字段使用JSONB存储并配置GIN索引,事务隔离级别根据业务需求调整(需评估性能),跨库查询通过预聚合或缓存JOIN优化,缓存更新采用消息队列结合幂等性设计,同时优化连接池配置应对分库分表后的资源需求。

2) 【原理/概念讲解】:
首先讲数据库选择逻辑:用户信息、角色属性这类需要强事务一致性、复杂业务逻辑的场景,选MySQL InnoDB,因为其ACID特性、行级锁支持并发控制,还能调整事务隔离级别(如从RR到SERIALIZABLE)。交易数据高并发写入,用Redis缓存热点数据(如用户余额、最近交易记录),降低数据库压力。
表结构设计遵循第三范式,减少冗余。比如用户表存储基础信息(user_id、username等),角色表用JSONB存储动态属性(技能、装备),JSONB支持灵活查询(通过GIN索引)。
索引策略上,针对高频查询字段(如user_id、transaction_time)创建B+树索引,比如交易表用(user_id, created_at)联合索引,提升查询效率。
分库分表策略:垂直分库按业务模块拆分(用户库、角色库、交易库),水平分片按ID范围(用户表按user_id连续分片,如user_0存储1-1M,user_1存储1M-2M)或时间(交易表按月分表,如transaction_202401),分片键选范围分片避免热点(哈希分片可能导致数据倾斜)。
跨库查询优化:预聚合(如物化视图缓存用户角色关联表)或缓存JOIN(如Redis缓存用户角色表),减少跨库开销。
事务隔离级别调整:默认RR可能不满足强一致性(如角色属性实时更新),需评估SERIALIZABLE的性能影响(通过压力测试工具模拟高并发,记录CPU、内存、QPS)。
JSONB存储大小限制:设置字段最大长度(如100KB),或分片存储(将大JSONB拆分为多个字段),避免索引性能下降。
缓存更新机制:消息队列(如Kafka)发布交易成功消息,缓存服务消费并更新Redis,幂等性设计用消息唯一标识(如消息ID+业务ID)+重试机制(检查标识是否已处理)。
类比:分库分表就像把一个大仓库(单库)拆成多个小仓库(分库),每个小仓库再按商品类别(分表)分类,方便快速找数据;JSONB存储动态字段就像给商品贴灵活标签,GIN索引像给标签建索引,快速查询。

3) 【对比与适用场景】

对比维度关系型数据库(MySQL InnoDB)NoSQL(如Redis)分库分表策略(垂直/水平)
定义结构化数据,强事务一致性,支持复杂查询非结构化/半结构化,高并发读写,灵活数据模型按业务模块拆分(垂直)或按ID/时间拆分(水平)
特性ACID事务,行级锁,支持事务隔离级别调整高并发读写,内存存储,支持缓存提升并发,扩展存储,需跨库查询优化
使用场景用户信息、角色属性(需事务)热点数据缓存(如余额、交易记录)用户数据量增长,单库性能瓶颈
注意点连接数限制,分表后跨库查询复杂缓存击穿/雪崩风险分表策略不合理导致数据倾斜

4) 【示例】

  • 用户表(user):
    CREATE TABLE user (
        user_id BIGINT PRIMARY KEY,
        username VARCHAR(50) NOT NULL,
        password VARCHAR(100) NOT NULL,
        role_id BIGINT,  -- 外键关联角色表
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    
  • 角色表(role):
    CREATE TABLE role (
        role_id BIGINT PRIMARY KEY,
        role_name VARCHAR(20) NOT NULL,
        permissions JSONB  -- 动态字段存储角色权限
    );
    CREATE INDEX idx_role_permissions ON role USING GIN(permissions);  -- GIN索引支持JSON字段查询
    
  • 交易表(transaction):
    CREATE TABLE transaction (
        transaction_id BIGINT PRIMARY KEY,
        user_id BIGINT,
        role_id BIGINT,
        amount DECIMAL(10, 2),
        type VARCHAR(20),
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_user_time (user_id, created_at)  -- 联合索引优化查询
    );
    
  • 分库分表示例:
    用户表按user_id范围水平分片(如user_0存储user_id 1-1M,user_1存储1M-2M);
    角色表按role_id范围分片(如role_0, role_1, ...);
    交易表按时间分片(如transaction_202401, transaction_202402, ...)。

5) 【面试口播版答案】:
“面试官您好,针对游戏用户数据(用户信息、角色属性)和交易数据的存储方案,我的思路是:首先,用户信息、角色属性这类需要强事务一致性的结构化数据,选择MySQL InnoDB,通过规范化设计(如第三范式)减少冗余,比如用户表存储基础信息,角色表用JSONB存储动态属性(如技能、装备),并设置GIN索引支持灵活查询。然后,针对高频访问的热点数据(如用户余额、最近交易记录),用Redis缓存,降低数据库压力。索引策略上,针对常用查询字段(如用户ID、交易时间)创建B+树索引,比如交易表用(user_id, created_at)联合索引,提升查询效率。分库分表方面,垂直分库按业务模块拆分(用户库、角色库、交易库),水平分片按ID范围(用户表)或时间(交易表)分片,解决单库连接数和存储容量限制,确保高并发下的性能。对于角色属性动态字段,采用JSONB存储并设置GIN索引,支持灵活查询;事务隔离级别根据需求调整为SERIALIZABLE(需评估性能影响);缓存更新通过消息队列(如Kafka)结合幂等性设计,确保一致性;连接池配置调整以应对分库分表后的连接数需求。总结来说,通过关系型数据库存储核心数据、Redis缓存热点数据,结合索引优化和分库分表策略,既能保证数据一致性,又能提升系统可扩展性和性能。”

6) 【追问清单】

  • 问:分片键选择时,为什么优先范围分片而非哈希分片?
    答:范围分片(如按ID连续分片)避免热点(所有新用户集中到某分片),而哈希分片可能导致数据倾斜(如ID哈希后分布不均)。
  • 问:如何优化跨库查询(如查询用户角色信息需要关联用户表和角色表)?
    答:通过预聚合(如物化视图缓存用户角色关联表)或缓存JOIN结果(如Redis缓存用户角色表),减少跨库查询开销。
  • 问:交易数据的高并发写入如何保证?
    答:使用MySQL InnoDB的事务机制(行级锁)结合批量插入(如批量提交),同时Redis缓存交易记录,异步写入数据库。

7) 【常见坑/雷区】

  • 数据倾斜:如用户ID范围分片时,部分分表数据量远大于其他,导致查询性能不均。
  • 索引选择不当:如只创建单字段索引,导致联合查询效率低,或过度索引增加写入开销。
  • 缓存击穿/雪崩:未设置缓存过期策略或分布式锁,导致热点数据失效时大量请求冲击数据库。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1