游戏开发 数据库ID设计 ID生成器

游戏开发 数据库ID设计 ID生成器游戏开发 数据库 ID 设计 ID 生成器 对于滚服游戏开发 数据库的 ID 设计非常重要 关乎到合服操作的复杂性 数据库 ID 设计得好 合服就相当简单 合服主要是数据的合并 把两个或多个单独的服务器数据合并到一个服里面 数据库表设计是游戏开发中必不可少的 通常每一张表 我们都会设计一个 ID 主键字段

大家好,我是讯享网,很高兴认识大家。

游戏开发 数据库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的结构。

欢迎您点赞 评论,您的支持是我最大的动力~

↓ 动动您的贵手 点赞 收藏 (方便您下次查阅) 谢谢~(❁´◡`❁)✲゚

小讯
上一篇 2025-03-27 07:24
下一篇 2025-01-04 22:43

相关推荐

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