路桥贝斯特做网站好吗,个人网站推广 公司,创意家装设计公司,技术支持公司做的网站怎么查1、分布式id
游戏服务器里的大部分数据都是要求全局唯一的#xff0c;例如玩家id#xff0c;道具id。之所以有这种要求#xff0c;是因为运营业务上需要进行合服操作#xff0c;保证不同服的数据在进行合服之后#xff0c;也能保证id不冲突。如果采用关系型数据库#x…1、分布式id
游戏服务器里的大部分数据都是要求全局唯一的例如玩家id道具id。之所以有这种要求是因为运营业务上需要进行合服操作保证不同服的数据在进行合服之后也能保证id不冲突。如果采用关系型数据库例如mysql常见的分布式id算法有以下方法。
分段步长把long型数字的前N位标记为区服id剩余的后面所有位用作计算器自增长并把最大的id进行持久化。雪花算法变种将雪花算法与游戏区服、系统时间戳、计算器结合起来。
详情可参考 游戏服务器框架之分布式id生成器
如果选择mongodb由于其内置一个非常简单高效的分布式id生成算法可以直接使用。不用业务代码自行设计。
详情可参考 Mongodb分布式id
2、数据库ddl自动化
目前很多orm框架都不支持自动建表加字段(原生的mybaticsmybatics-plus均不支持hibernate支持)因为要实现这个功能需要应用层使用jpa或者其他注解显示表明哪些字段是需要持久化以及对应的类型。
而mongodb。甚至支持在同一个文档里有不同的文档结果。不过这种支持在应用层通常不会这么做容易造成业务代码混乱。试想一下把数据库的全部表数据全部打包到单独一个数据表这种设计绝对是个噩梦。 自动创建集合在 MongoDB 中当你尝试向尚不存在的集合中插入一个文档时MongoDB 会自动创建该集合。例如如果你有一个文档并尝试将其保存到数据库中而该集合不存在MongoDB 将自动创建它。 db.mycollection.insertOne({name: example, value: data}) 自动添加字段当你插入一个新文档或更新现有文档时如果文档中包含集合中其他文档不存在的字段MongoDB 会自动将这些字段添加到文档中。例如 db.mycollection.updateOne({}, {$set: {newField: value}}, {upsert: true}) 这个命令会为集合中的每个文档添加 newField 字段如果文档中已经存在该字段则会更新它的值。 使用 $set 操作符$set 操作符可以用来为文档添加新字段或更新现有字段的值。如果指定的字段不存在它会被添加。 db.mycollection.updateMany({}, {$set: {newField: defaultValue}}, {multi: true})
3、嵌套数据处理
使用关系型数据当我们需要保存用户某一个模块的内容比如vip数据我们一般会在Player类加一个嵌套bean例如叫VipRight。这个嵌套的bean映射到MySQL可以表示为一个字段。针对一个javabean到一个mysql字段的转换通常有两种方法。
第一种同时申明一个bean对象以及这个对象对应的json字符串类似下面的定义
Data
public class Player {private String id;private VipRight vipRight;private String vipRightJson;}
其中VipRight又是另外一个javabean定义如下
Data
public class VipRight {private int level;private int exp;
}当我们从数据库里读取记录时需要先将json进行反序列化为对应的javabean当我们写入数据库的时候则将javabean序列化为json再持久化到数据库。这种方法写起来非常啰嗦。
另外一种方式则是通过自定义的orm工具通过特定的注解程序自动将json与bean进行转换。例如jforgame-orm工具就是采用这种方式。
Data
public class PlayerEnt implements BaseEntityLong {IdColumnprivate long playerId;/*** 所属账号id*/Columnprivate long accountId;Columnprivate String name;Columnprivate int level;ColumnConvert(converter JpaObjectConverter.class)private VipRight vipRight;
}
如果采用Mongodb则这种问题不复存在。Mongodb天生支持嵌套文档springdata mongodb自动会对其进行转换如下代码
Data
Document(player)
public class Player {Idprivate String id;Fieldprivate VipRight vipRight;}
4、对嵌套bean数据的查询
还是以上边的例子如果程序需要在启服的时候捞取vip等级前50的数据作为排行榜如果采用mysql的话由于mysql查询不支持json子查询我们不得不在player类增加一个冗余字段额外保存vip等级例如下面的代码。在更新的时候需要两个位置一起更新非常麻烦。
Data
public class Player {private String id;private VipRight vipRight;private String vipRightJson;//冗余vip等级字段private int vipLevel;}采用mongodb的话由于其支持嵌套子查询直接一个子bean搞定在springdata mongodb里插入与查询只需如下代码 PlayerRepository bean SpringContext.getBean(PlayerRepository.class);Player demo new Player();VipRight vipRight new VipRight();vipRight.setExp(111);vipRight.setLevel(100);demo.setVipRight(vipRight);bean.insert(demo);ListPlayer byVipRight bean.findByVipRight(100);System.out.println(byVipRight.size());
其中嵌套文档查询需要用自定义的行为
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import org.tea.editor.domain.Player;import java.util.List;Repository
public interface PlayerRepository extends MongoRepositoryPlayer, String {Query({vipRight.level:?0})ListPlayer findByVipRight(int level);
}如果使用mongosh查询的话查询语句如下 db.player.find({vipRight.level:100})
//输出结果
[{_id: ObjectId(664ac4453b9f7f0308a03f2a),vipRight: { level: 100, exp: 111 },_class: org.jforgame.Player}
]
5、水平拓展
水平扩展意味着单个游戏服务器能够存储更多的玩家例如大世界架构的服务器需要存储大容量的游戏数据。然而目前流行的手游或者小游戏大部分基于“滚服模式”本身也不要求数据库存储大量的游戏数据而是将游戏拆分成一个一个相对独立较小容量的区服。因此水平扩展对于大部分游戏架构的吸引力不强。
MongoDB 水平扩展
MongoDB 支持通过分片集群实现数据的水平扩展。分片是一种将数据分布到多个服务器或集群上的技术通过将数据分成多个片段并存储在多个服务器上MongoDB 能够提高数据库的存储容量和吞吐量。分片集群包含两个主要概念
分片将数据分割成多个片段每个片段存储在集群中的一台服务器上。副本集副本集是分片集群中的一种数据冗余技术通过在多个服务器上保存同一份数据的副本来确保数据的可靠性和可用性。
分片集群的优点包括
读写水平扩展MongoDB 可以将读写负载分布到集群中的不同分片上提高吞吐量并在高并发情况下保持高性能。数据冗余和可用性副本集提供数据冗余和可用性保障即使某个服务器发生故障也能快速切换到其他可用服务器上。
MySQL 水平扩展
MySQL 的水平扩展能力相对有限通常需要通过分库分表的方式来实现。水平拆分是通过某种策略将数据分片存储每片数据分散到不同的MySQL表或库达到分布式的效果。MySQL的水平扩展主要包括
表分区MySQL 支持表分区这是一种简单的水平拆分用户需要在建表时加上分区参数对应用是透明的无需修改代码。读写分离通过主从复制可以实现读写分离提高数据库的读取性能。分库分表通过将数据分布到不同的MySQL实例实现水平扩展。
MySQL 水平扩展的策略可能涉及
垂直拆分根据数据库内数据表的相关性进行拆分。水平拆分通过某种策略将数据分片存储每片数据分散到不同的MySQL表或库。
水平扩展策略的选择需要考虑数据的增长模式、访问模式、分片关联性问题以及分片扩容问题。每种策略都有其优缺点需要根据具体的业务需求和场景来决定最合适的扩展方案。