2019独角兽企业重金招聘Python工程师标准>>>

先说明我比较喜欢的服务端的数据存储的设计是把玩家数据分成两部分,一部分是玩家的个人数据,这种数据只会被玩家自己更新,比如装备系统,任务系统等;另一部分是玩家的交互数据,这部分数据在自己不在线时,也可被其他的操作更新。个人数据由统一的个人数据管理模块管理,交互数据由不同的玩法模块管理,该模块会根据需要从数据库拉取数据,并把内存的数据落地到数据库。下面说的内容是针对交互数据。

处理交互数据时,有时会需要批量更新玩家信息。这里总结一些情况下的处理,通过逻辑避免批量的 sql 操作,数据库可以使用 MySQL 或者 MongoDB 。通常情况下,一个游戏进程支撑的在线人数是一定的,并且注册玩家的数量也是一定的。我经历的几款普通的游戏都是一个服的注册玩家最多几万人,最多同时在线人数也就是开服前三天,其实人数最多时也就几百人。所以在这个量级下,某次操作批量更新几百个玩家完全不是问题。但是总要有一点追求吧,万一后面进了项目组游戏会上微信,这个玩家数量就很大了。所以写逻辑时还是保持些追求,有一些追求,就会先在逻辑上避免批量的 sql 。
写避免批量 sql 逻辑的另一个直观的原因是不需要同时更新这些玩家数据。

全服邮件

最常见的就是全服邮件逻辑。全服邮件是运营人员只发一封邮件,然后程序通过逻辑让每个玩家都可以领取到这封邮件。如下是最直接一种实现方式,模块接收到包后解析 GlobalMail 数据,然后再插入到每个玩家的邮件数据表中。

          +----> Player1Mail+----> Player2Mail
GlobalMail+----->Player3Mail+----->....

其实没有必要此刻插入的。玩家打开邮箱收取邮件,完全可以在玩家打开客户端邮箱时才处理。这样就把批量更新邮件数据分散到不同的玩家的操作中。每次打开界面时客户端发送查询邮件的数据包,服务端处理此协议时,检查已经处理过全服邮件,如果未处理此时为玩家添加此邮件。

OpenMailUI++-->GlobalMail+--->Player1Mail|            |
OpenMailUI +           +--->Player2Mail

排行榜奖励

排行榜类型的玩法通常是活动期间大家参与活动,积分越高排名也就越高,然后在结算时间内发送排行榜奖励。发送排行榜奖励时,一种直接的做法就是遍历排行榜上的玩家,然后给每个玩家发送一封奖励邮件。假如排行榜上有 10000 名玩家,但就会需要发送 10000 封奖励邮件。但是仔细观察一下,人数很多时的排行榜奖励是分类的,可能前 10 名是 10 种奖励,然后 11 到 99 是一种,100 到 199 是一种,越往后越是很多人的奖励是相同的,总的来说差不多就是几十种不同的奖励。
因此如下所示,把不同的奖励邮件分类,每种类型的奖励邮件对应一个玩家列表,列表中可以有一个或者多个玩家。这种归类的邮件有点类似于全服邮件,可以把全服邮件也看成是这种类型的邮件,只是全服的邮件的玩家列表针对的是全服玩家。所以全服邮件的邮件数据中不需要记录玩家的 id ,但是这种归类的邮件需要记录列表中的玩家 id ,这样才知道列表中有哪些玩家。
这种归类后的邮件处理方式也与全服邮件类似,不批量更新玩家数据,而是分流的把领取邮件分散到不同的玩家打开客户端邮箱界面的行为中去。所以服务端收到客户端发送来的邮件查询包后,此时需要检查玩家是否领取过全服邮件,玩家是否有一些归类邮件还未领取。

MailKind1 - PlayerList
MailKind2 - PlayerList
...
MailKindn - PlayerList

结算后,把某字段清 0

比如还是排行类玩法,现在根据玩家积分产生的排行榜,结算后需要把玩家的积分清 0 。这个和该玩法的实现有关。有一种实现是排行榜上所有玩家数据都被保存在一个字段中,结算后直接清除这个字段即可,简单而且一条 sql 就搞定了。还有一种实现活动中每个玩家的数据稍微复杂,而且有些字段会更新比较频繁,数据存储就分玩家来存,每个玩家一条记录,这样结算时,需要清除其中的积分字段时,直接的方式就是通过批量 sql 更新来清除积分字段。其实这时的批量更新也是可以通过逻辑绕开的。方法与上面一致,在需要时才更新
所以如下所示。在获取玩家数据时(若此时不在内存,则先从 db 加载)根据上次刷新时间RefreshTime 判断玩家数据是否过期,如果过期则执行 Clear 操作清除一些过期字段,比如积分。然后再返回玩家数据,如果已经清除了,则在玩家数据中记录当前清除的时间,这样玩家的清除时间大于或者等于刷新时间,之后再获取时数据就未过期,直接返回即可。

GetPlayerData+-->RefreshTime+--------->PlayerData|       +-^+->Clear+

总结

避免批量 sql 的思想就是玩家的数据此时并不需要被更新,可以在需要时才更新,这样就把更新操作分散到每个玩家的某次操作中。所以选择合适的操作来进行更新,就可以达到很好的分散效果,逻辑也不会太复杂。

转载于:https://my.oschina.net/iirecord/blog/1524521

避免游戏中的批量 sql相关推荐

  1. 从excel表中生成批量SQL,将数据录入到数据库中

    excel表格中有许多数据,需要将数据导入数据库中,又不能一个一个手工录入,可以生成SQL,来批量操作.     1.首先在第二行的H列,插入函数:=CONCATENATE("INSERT ...

  2. mysql 命令行批量sql_命令行中执行批量SQL的方法

    基础信息介绍 测试库:test: 测试表:user: user表定义: CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nam ...

  3. oracle中执行动态sql语句吗,oracle中有没有可动态执行sql语句的函数

    oracle中有没有可动态执行sql语句的函数 关注:233  答案:2  手机版 解决时间 2021-03-05 15:53 提问者祗剩寂寞 2021-03-04 22:38 oracle中有没有可 ...

  4. Entity Framework Core 5中实现批量更新、删除

    本文介绍了一个在EntityFramework Core 5中不需要预先加载数据而使用一句SQL语句批量更新.删除数据的开发包,并且分析了其实现原理,并且与其他实现方案做了比较. 一.背景 随着微软全 ...

  5. sql limit 子句_Java 8流中的常见SQL子句及其等效项

    sql limit 子句 功能编程允许使用通用语言进行准声明性编程 . 通过使用功能强大的流畅API(例如Java 8的Stream API )或jOOλ的顺序Stream扩展Seq或更复杂的库(例如 ...

  6. Java 8流中的常见SQL子句及其等效项

    功能编程允许使用通用语言进行准声明性编程 . 通过使用功能强大的流畅API(例如Java 8的Stream API )或jOOλ的顺序Stream扩展Seq或更复杂的库(例如javaslang或fun ...

  7. ef执行原生sql语句_EF Core中执行原生SQL语句

    一.课程介绍之所以今天录制这个系列文章的主要原因是,想在快速帮助到大家上手在ASP.NET Core WebAPI中结合EF Core来操作我们的数据库.EF Core的基础文章和基础课程实在是太多了 ...

  8. 游戏中的Decal(贴花)

    在游戏中,decal是一种非常常见的效果,常用来实现弹孔,血迹,涂鸦等效果.最近研究了下Decal在游戏引擎中的实现方式,大致总结了一下: 1.基于面片实现: 直接用一个Quat的mesh,加上一张贴 ...

  9. 牛鞭效应matlab代码,牛鞭效应在啤酒游戏中的运用.doc

    ____________________________________________________________________________________________________ ...

最新文章

  1. 最新综述:推荐系统的Bias问题和Debias方法
  2. 个人微信订阅号自定义菜单空白
  3. Unity性能优化-遮挡剔除
  4. socket多线程方式案例
  5. c语言如何赋值星期到字母,C语言程序设计课程教案.doc
  6. redis 字符串数据(string)
  7. 转载系列之一:浅析Hadoop文件格式
  8. 乌鲁木齐大雾弥漫 局地能见度不足200米
  9. 常用c语言代码大全,C语言的一些常用代码
  10. 软件测试流程(完整版)
  11. 思科服务器如何进入网站,思科路由器怎么进入设置网站
  12. ocr初始化失败怎么办_应用程序正常初始化失败
  13. 领导力提升的科学:如何提升领导力?
  14. jdbc操作数据库实现查询产品、增加产品库存量例子
  15. 计算机卡驱动版本过低,显卡驱动版本过低怎么办?
  16. 角速度的相似变换定理的证明
  17. 中小型网络系统总体规划与设计方法(二 )
  18. java中什么是外层实例,ew MyAsyncTask(); 报错
  19. 添加VBA控件按钮及操作提示框
  20. android 9.0 toast不显示,9.0 toast定位+WebDriverWait显示等待

热门文章

  1. 百练_4123 马走日(深搜)
  2. 使IE6支持PNG透明图片的JS插件
  3. android开发GPS定位测试(附效果图和示例)【转】
  4. Linux之time命令
  5. 用Intellij Idea创建一个普通的Java工程并用JDBC连接数据库
  6. spring加载classpath与classpath*的区别别
  7. POJ 1703 Find them, Catch them 并查集
  8. Custom Sharepoint Lookup Field
  9. opengl 教程(15) 摄像机控制(2)
  10. 该内存不能为read解决办法