游戏开发 数据库ID设计 ID生成器
对于滚服游戏开发,数据库的ID设计非常重要,关乎到合服操作的复杂性。数据库ID设计得好,合服就相当简单。合服主要是数据的合并。把两个或多个单独的服务器数据合并到一个服里面。
数据库表设计是游戏开发中必不可少的,通常每一张表,我们都会设计一个ID主键字段,关于表ID的生成方式。这里我们选择根据区服ID及玩家数量自增,其他同学喜欢用UUID那就另说。
ID结构: 自增序列+四位区服号。
这里我们以区服ID作为基数,个位到千位是区服号,万位以上是玩家ID自增ID开始。如1区服即0001, 2区服是0002.
以玩家基础数据表的ID设计为例,如果以区服1为示例,那么ID结构是这样的:玩家自增序列+0001。即1区服的第1号玩家ID是:10001;1区服的第19876号玩家ID是:。2区服的第1号玩家ID是:10002;2区服的第19876号玩家ID是:。
这里说明一下,ID区服段为什么是个位到千位,而不是到万位呢?通常滚服开服区服数量不会太多,除非非常爆款的游戏。一般开到上千服已经很不错了。所以这里设计区服区间为1-9999个服。即ID基数是:0001-9999。
下面是实现这种结构ID设计的实例
以JAVA代码示例。
1. ID生成管理类 IdManager.java
初始化ID和生成新ID的实现。
@Service public class IdManager {
private static final Logger logger = LogManager.getLogger(IdManager.class); @Resource private GameDBConfiguration gameServerConfiguration; private final Map<String, Long> ids = new ConcurrentHashMap<>(); public void init() {
logger.info("id生成器开始。"); try {
Field[] declaredFields = TableNameConstant.class.getDeclaredFields(); for (Field f : declaredFields) {
String tableName = f.get(TableNameConstant.class).toString(); long maxId = gameServerConfiguration.getMaxId(tableName); if (maxId == 0) {
if (tableName.equals(TableNameConstant.T_PLAYER)) {
ids.put(tableName, IdMaxConstant.ROLE); } else {
ids.put(tableName, IdMaxConstant.COMMON); } } else {
ids.put(tableName, maxId); } } } catch (Exception e) {
logger.error(e.getMessage(), e); } logger.info("id生成器结束。"); } / * 创建并获取新的id */ public Long createNewId(String tableName) {
synchronized (tableName) {
Long maxId = ids.get(tableName); if (maxId == null) {
logger.error("id生成规则出错,tableName={}", tableName); return null; } long newId = 0; int serverId = ServerHelper.getServerId();//获取当前区服ID。 newId = (maxId / IdMaxConstant.SERVER_BASE_VALUE + 1) * IdMaxConstant.SERVER_BASE_VALUE + serverId; /*if(tableName.equalsIgnoreCase(TableNameConstant.T_PLAYER)){ newId = (maxId / IdMaxConstant.SERVER_BASE_VALUE + 1) * IdMaxConstant.SERVER_BASE_VALUE + serverId; }else{ newId = maxId + 1; }*/ ids.put(tableName, newId); return newId; } } }
讯享网
2. 获取数据库表最大ID方法 getMaxId()
从数据库中查询当前表格最大的ID序号。
讯享网 public long getMaxId(String tableName) {
String sql = "select max(id) from " + tableName; Long maxId = jdbcTemplate.queryForObject(sql, Long.class); return maxId == null ? 0 : maxId; }
3. 表格常量类 TableNameConstant.java
存放需要管理ID的表格名称。
public class TableNameConstant {
public static final String T_PLAYER = "t_player"; public static final String T_PLAYER_GOODS = "t_player_goods"; //... }
4. 常量类 IdMaxConstant.java
讯享网public class IdMaxConstant {
/ * role表id起始值 */ public static final long ROLE = 0L; / * 通用表id起始值 */ public static final long COMMON = 0L; }
5. 使用示例
long playerId = idManager.createNewId(TableNameConstant.T_PLAYER); Player player = new Player(); player.setPlayerId(playerId); player.setUsername(username); player.setGameSite(gameSite); player.setNickname(nickname.trim()); player.setCreateTime(new Date()); //...
至此,一波操作完成。
实际应用中根据具体项目可以修改 IdMaxConstant.java 起始值来改变ID的结构。
欢迎您点赞 评论,您的支持是我最大的动力~
↓ 动动您的贵手 点赞 收藏 (方便您下次查阅) 谢谢~(❁´◡`❁)✲゚

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/35724.html