NoSQL 方案选型
概述
MySQL 承载玩家核心数据,但游戏里还有一类数据它并不擅长:结构灵活、量级极大、或需要嵌入式高性能。本文对比三类 NoSQL 方案在游戏中的应用:MongoDB(文档模型存玩家数据)、LevelDB/RocksDB(本地嵌入式存储)、TiDB(分布式数据库),并给出选型依据。
一、什么时候需要 NoSQL
1.1 MySQL 不擅长什么
高频写、超大单表(日志、行为数据)
字段频繁变化(玩法迭代改结构)
本地嵌入式需求(缓存、KV)
超大规模水平扩展(千万级并发写)游戏中的候选数据:
玩家文档型数据(结构松散的玩法数据)
行为日志(海量追加写)
会话/缓存(KV 结构)
排名/时间序列(特定结构)1.2 选型决策框架
决策顺序:
1. 数据模型:结构化固定 → MySQL;松散文档 → MongoDB
2. 量级:海量追加 → 列式/日志存储;大表 → TiDB
3. 部署形态:进程内 → RocksDB/LevelDB
4. 一致性要求:强一致事务 → MySQL/TiDB| 场景 | 推荐 |
|---|---|
| 玩家核心数据 | MySQL(分表) |
| 松散玩法数据 | MongoDB |
| 进程内 KV | RocksDB |
| 海量日志 | Kafka + 存储引擎 |
| 大表强一致 | TiDB |
二、MongoDB:文档模型
2.1 核心特性
文档模型(BSON):
一条玩家记录 = 一个 JSON 文档
字段随意增减,无 DDL 约束
内嵌数组与子文档(背包、任务直接内嵌)
适用:结构多变、需要快速迭代的数据游戏应用示例:
{
"_id": 10001,
"nickname": "小明",
"level": 12,
"bag": [ { "itemId": 1001, "count": 5 } ],
"quest": { "daily": { "questId": 1, "progress": 3 } },
"createdAt": ISODate("2026-08-06T10:00:00Z")
}2.2 MongoDB vs MySQL(玩家数据)
| 维度 | MySQL | MongoDB |
|---|---|---|
| 结构 | 固定表结构 | 灵活文档 |
| 变更 | 需要 DDL | 直接加字段 |
| 事务 | 成熟 | 4.0 起支持多文档事务 |
| 扩展 | 分库分表(ShardingSphere) | 原生分片 |
| 团队熟悉度 | 高 | 中 |
结论:
玩家核心数据用 MySQL(团队熟、事务稳)
MongoDB 用于:
结构频繁变化的玩法数据
快速原型/灰度验证
日志类文档存储2.3 MongoDB 实践要点
分片:
按 _id / playerId 分片(hash 或 range)
索引:查询字段建索引
内存:工作集(热数据)放内存,冷数据落盘
备份:mongodump / 副本集三、LevelDB / RocksDB:嵌入式存储
3.1 为什么需要嵌入式
嵌入式 = 直接嵌入应用进程,不走网络
优点:零网络开销、极致低延迟
缺点:单机数据、进程内共享需加锁
游戏场景:
进程内缓存(会话、热数据)
帧同步/对局的临时状态
本地数据库(独立小游戏服)3.2 LevelDB vs RocksDB
| 维度 | LevelDB | RocksDB |
|---|---|---|
| 维护 | Google 原始 | Facebook 维护 |
| 写优化 | 基础 LSM | 高级 LSM(合并、压缩调优) |
| 特性 | 简洁 | 列族、TTL、Bloom 过滤等丰富 |
| 性能 | 好 | 更好(可调参) |
LSM-Tree 特性:
顺序写 + 内存表 → 落盘 SSTable
写性能远超 B+Tree(游戏高频写友好)
读可能需要查多层(配合 Bloom 过滤)3.3 游戏中的应用
应用一:Session/热数据本地缓存
进程内 RocksDB 存最近 N 天玩家快照
崩溃恢复更快(不必全量从 MySQL 拉)
应用二:单机小游戏服
独立服的玩家数据本地存储
定期上传/同步到中心库
注意事项:
进程内共享 → 单写者模式或加锁
不是网络服务 → 不跨节点共享
数据要备份/同步,不能当唯一存储四、TiDB:分布式数据库
4.1 是什么
TiDB 特性:
MySQL 协议兼容(可当 MySQL 用)
分布式:存算分离,水平扩展
强一致:Raft 多副本
事务:完整 ACID
对应用透明(JDBC 直连)
定位:MySQL 的水平扩展替代方案4.2 TiDB vs MySQL 分库分表
| 维度 | MySQL + ShardingSphere | TiDB |
|---|---|---|
| 扩展 | 手动分片、迁移复杂 | 自动扩缩容 |
| 事务 | 跨分片事务受限 | 全局分布式事务 |
| 运维 | 分片管理成本高 | 集群托管简单 |
| 延迟 | 单机低 | 略高(跨节点 Raft) |
游戏场景判断:
玩家数据量大、要全局事务 → TiDB 省心
追求极致单机延迟 → MySQL 分片
中小规模 → MySQL 分片足够
大厂休闲游戏常选 TiDB 做玩家库4.3 TiDB 实践要点
接入:
JDBC 直连,SQL 与 MySQL 基本一致
分片由 TiDB 自动处理(无需应用分片)
玩家表仍按 playerId 做主键(本地性)
注意:
网络开销略高,热数据仍建议 Redis/内存
冷热分离、归档策略依然适用五、选型总表
| 数据 | 推荐方案 | 理由 |
|---|---|---|
| 玩家核心数据(货币/等级) | MySQL 分片 | 事务稳、团队熟 |
| 玩法松散数据 | MongoDB | 灵活、迭代快 |
| 进程内 KV/缓存 | RocksDB | 低延迟、嵌入 |
| 海量行为日志 | 消息队列 + 存储 | 追加写、可扩展 |
| 超大玩家库(强一致) | TiDB | 透明分布式 |
| 排行榜/计数 | Redis | 数据结构原生 |
| 全文搜索 | Elasticsearch | 检索能力 |
组合方案(休闲游戏主流):
MySQL(玩家核心)+ Redis(在线/排行)+ MongoDB(玩法数据,可选)
量级上来后:MySQL → TiDB 或保留分片
所有方案统一走"内存 → 共享存储 → 持久库"三层六、常见问题
| 问题 | 处理 |
|---|---|
| 文档数据库数据一致性 | 关键字段仍放 MySQL |
| 嵌入式存储数据丢失 | 定期同步/备份 |
| TiDB 延迟偏高 | 热数据走 Redis 缓存 |
| NoSQL 运维成本 | 只引入真正需要的 |
| 迁移成本 | 灰度双写 + 校验 |
七、小结
NoSQL 不是取代 MySQL,而是补齐它不擅长的场景:MongoDB 用文档模型承接结构松散的玩法数据,迭代期无需 DDL;LevelDB/RocksDB 以嵌入式 LSM 引擎提供进程内极致读写,适合会话缓存与单机服;TiDB 以 MySQL 协议提供透明分布式扩展,适合体量上亿的玩家库。选型始终围绕"数据模型、量级、部署形态、一致性"四个问题展开。对休闲小游戏,理性组合是:MySQL 打底、Redis 加速、必要时引入 MongoDB/TiDB,避免为用而用。