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