单一世界十万在线webgame的设计思路(四)-- 玩家数据的数据库设计
数据库的划分
在游戏里数据交互最频繁的还是玩家的数据,他的访问量是一台服务器所不能解决的,因此我们考虑将这部分数据分担到多台服务器里。分担的方法还是做水平切割,但这次不使用数据库自身的切割功能,而是在应用逻辑层上对数据库进行切割。根据用户的ID取模后写入对应的服务器里。
服务器1 用户ID % 服务器数量 = 0 |
服务器2 用户ID % 服务器数量 = 1 |
……
预计每台服务器能提供6k~8k的在线用户访问,预计一共需要16台服务器。考虑到服务器的进一步扩容问题,在初期规划时,建议规划为32个数据库,每台服务器可以先放3~5个数据库,等服务器用户人数上来后,再将数据库拆分到不同的服务器里。
用户数据库各个模块的设计
玩家基地里的建筑物,资源,物品,英雄等相关表,基本上都是玩家独立拥有的,不存在和其他玩家交互的情况,因此这些表的设计继续沿用之前的设计就可以了。
军事模块
军事模块分为部队表,部队创建事件表和战斗事件表。部队表和部队创建事件都是玩家自己内部的事情,把相关的数据和玩家其他数据放在一个数据库里就行了,但是战斗事件表则会设计到两位或者多为玩家则会比较复杂一些。
战斗事件表通常记录的是A玩家(城池)对B玩家(城池)的攻击,里面有攻击部队,到达时间等信息。这个条记录和A放在一起,那么B在查询自己被攻击的记录时,就需要访问32个数据库,反之,和B放在一起,这A查询自己部队的攻击情况时,就需要遍历32个数据库。如果和用户表一样单独把这张表拿出来,用单独的一个服务器来处理,则会导致表过大,查询会变慢以及战斗服务器的压力过大。
在之前的项目,战斗服务器处理每场战斗大约是100ms,也就是每秒能处理10场战斗。当然你也许说可以用多线程来进行,但是使用多线程后,战斗事件的顺序可能会点到,影响用户的战术安排。
在这里,我设想,将一个表设计改为2个表:攻击事件表和被攻击事件表。这两个表的结构一样。加入A玩家发起对B玩家的攻击,那么将攻击事件加入A玩家所在服务器里的攻击事件表,在B玩家服务器里,将数据插入被攻击事件表。然后每个数据库对应一个战斗服务器程序,这个程序在已被攻击事件表为依据,进行攻击计算。在计算完成后,在同时删除2个表里的数据。
好友模块
好友表本身就可以分为2个表,已某位玩家ID为主键和对应玩家放在同一个数据库里。但是好友申请则需要另外考虑了。如果申请的申请方不可见自己发出的申请,则只需把申请记录和被申请玩家放在一个数据里。但如果需要可见,则会麻烦一些,一种方法是参考战斗表的设计思路,分为申请表和被申请表。还有一种方法就是把申请表独立出来,所用用户的申请都放在这张表里。作为我个人,我倾向于后面的一种方法。
用户邮件表设计
用户邮件虽然是属于2位用户之间的交互数据,但从整个系统的角度上来说,用单一的一张表放在单独的服务器里会更简单一些。因为邮件表的内容基本为只读内容,只存在插入和读取功能,并且用户访问的频率不是很高,可以很方便的在逻辑层和web层作缓存。