noSQL-它是基于Web的游戏的有效选择吗?[关闭]


20

出于机会和无聊,我和一个朋友决定制作一个基于网络的游戏。这是我将要制作的第一个“游戏”,因为通常我会在Django中编写Web应用程序。

我选择在游戏中使用相同的框架,但由于无法预见未来的需求和与数据库相关的问题,因此我对数据存储并不完全确定。最近,noSQL运动逐渐兴起,我想探索这一领域。

因此,我有以下问题:

  • noSQL数据存储(基于文档,例如MongoDB)是否适合基于Web的游戏?
  • 使用传统的RDBMS(例如MySQL)可能会出现什么问题?
  • 如何在玩游戏或定时事件(例如cron作业)期间,确保使用MongoDB的用户之间的数据一致性?

游戏概述:典型的冒险游戏,玩家与怪物战斗并获得物品等。

  • 所有玩家的一些数据都是静态的:物品,武器,药水,地图等。
  • 与玩家相关的一些数据:清单,指标(统计数据),进度等。
  • 一个玩家可能需要知道另一个玩家的状态和状态
  • 计划任务将在特定时间间隔运行


1
某些noSQL数据库的问题在于,它们无法对“大型”数据集(如事件日志)快速进行“设计”时无法预测的查询:gamedev.stackexchange.com/q/4465/450 请记住,noSQL数据库需要相同的查询与普通数据库相比,针对查询注入的技术更为正常。
亨德里克·布鲁默曼

1
@nhnb:重申观点的一种好方法是“将关系数据库用于关系数据,并将对象/文档数据库用于对象/文档数据”。不幸的是,我认为大多数人都没有经验或花很多时间在建模上,这会导致不良的设计,无论他们选择哪种设计。

2
在回答您的问题“ NoSQL是基于Web的游戏的有效选择吗?” 我相信答案是肯定的。NoSQL数据库以前曾用于基于Web的游戏(例如FarmVille),并提供了很大的灵活性。该问题的主要争论点似乎是“哪个更好(NoSQL或SQL)?”。每个系统都有优点和缺点,但两者都是完全合法的选择。如果要查找一个系统相对于另一个系统的优点的详细列表,则可能需要向程序员StackExchange支付一定的费用。:)
阿里·帕特里克

Answers:


21

noSQL数据库适合基于Web的游戏吗?

绝对!一般而言,非关系数据库(例如MongoDB)对于游戏来说要好得多,因为它们在数据建模方面更加灵活,同时比关系数据库(例如SQL)更高效-使它们“双赢”选择。

使用常规RDBMS可能会出现什么问题?

使用关系数据库有两个主要缺点:

  • 数据建模方式缺乏灵活性
  • 性能

数据建模方式缺乏灵活性是一个主要缺点,因为使用关系数据库会迫使您对数据进行建模以适应数据库的需求,而不是数据库能够适应模型的需求。例如,考虑您正在创建用于使用关系数据库在游戏中存储物品的模型,并决定采用以下模型:

weapon_type_id | weapon_type
1 | sharp

weapon_id | weapon| weapon_type_id | damage
1 | Short Sword | 1 | 5

potion_type_id | potion_type
1 | HP
2 | Mana

potion_id | potion| potion_type_id | modifier
1 | Healing Elixer | 1| 5
2 | Mana Drainer | 2| -5

现在考虑如何修改模型以满足以下要求:

  • 新增项目类型
  • 创建具有多种武器类型的武器
  • 创建一个可以用作武器的药水

当然,所有这些动作都是可行的,但是当您执行这些动作时,您将不是最快乐的人,并且您可能会想:“是否有更好的解决方案来解决我想做的事情?”,在非关系数据库中设计一个更加灵活的模型。

注意:如果您不熟悉基于文档的数据库如何存储信息,请在继续之前检查此链接。下面介绍的模型旨在使用与前述文章中介绍的逻辑类似的逻辑。

db.itemTypes

name: Weapon
types: Sharp

name: Potion
types: HP, Mana

db.items

name: Short Sword
weapon
    type: Sharp (db.itemTypes reference)
    damage: 5

name: Healing Elixer
potion
    type:  HP (db.itemTypes reference)
    modifier: 5

name: Mana Drainer
potion
    type:  Mana (db.itemTypes reference)
    modifier: -5  

name:  Healing Potion Sword
potion
    type: HP (db.itemTypes reference)
    modifier: 10
weapon
    type: Sharp (db.itemTypes reference)
    damage: 15

关于NoSQL和SQL数据库的性能,有很多不错的文章,但是这里提供了一些应用程序示例,因此您可以执行自己的测试:MongoDB与SQL Server 2008 Performance Showdown

如何使用MongoDB确保用户之间的数据一致性?

MongoDB支持对单个数据实体(文档)进行读/写原子操作,因此来自MongoDB的查询结果应始终与数据库中存储的内容保持准确。

编辑:提供了NoSQL示例数据库的项目


在您使用sql编写的示例中,您将如何使用nosql进行高层建模?

4
-1,您的答案仅显示静态数据。有关游戏数据库的SQL与NoSQL的整个争论涉及高度动态的数据。最好的办法是显示一个NoSQL事务,该事务在两个玩家之间进行交易-这是很常见的情况,大多数游戏都会出错,无论他们选择哪种类型。

3
@Ari:还有更多的静态数据,但是没有人关心写入的吞吐量,因为没有人写入它-没有写入,没有事务,没有ACID,没有真实的数据库问题,即使您碰巧存储了它在一个。该问题易于回答-只需将其保存在内存中即可。当然是“我们怎样才能更快地加载静态数据?” 这是一个有趣的问题,但我认为这与SQL与NoSQL根本无关。-对于多文档操作,这是否意味着您的数据库将包含一个文档,例如其中包含所有播放器?

2
@Ari:请不要混淆NoSQL和MongoDB,后者是一个主意,而MongoDB是一个特定的数据库。在我的上一份工作中,我们在NoSQL数据库上发布了两款游戏,并以低延迟获得了出色的并发性。但是我们的NoSQL数据库还支持具有字段级锁定的多文档事务。NoSQL不是像SQL那样的单一“事物”,它仅指的是不使用SQL(通常不使用关系方案)的任何数据库。

5
只是我的$ .02,但“不是高性能”并不是RDBMS的缺点。将非关系数据存储在RDBMS中,不调整RDBMS,不了解SQL的工作方式,不建立索引等是一个缺点。如果您有关系数据,则会发现RDBMS的优化程度令人难以置信。
罗比

19

几个词确实可以保护SQL数据库。

1-如果您拥有SQL数据库,则不仅可以使用主键来处理数据。MMO中的大多数查询都是通过PK进行的,但是当您需要查找所有级别大于30的用户时,您将在NoSQL世界中做什么?

2-如果您使用SQL语言,则可以创建“修补程序”来修复损坏的数据。例如:“更新player_items设置标志= 0,其中item_type_id = 100”。如何在NoSQL中解决此问题?我认为您必须制作一个脚本来解析所有数据...

3-SQL数据库并没有您想象的那么慢。我的同事创建了基于Web的MMO游戏,在MySQL中每秒进行5000次交易。这还不够吗?如果没有,则可以使用分片扩展数据库。

4-SQL具有外键约束和类似的好东西,可以帮助您查找代码中的错误。

NoSQL不是灵丹妙药。它仅解决了几个问题,并带来了许多新问题。所以我的建议-在选择NoSQL之前请三思。


1
这些都是避免NoSQL的重要原因,直到您真正需要它为止。特别是#3。除非您已经有成千上万的用户(并且拒绝分片),否则使用MySQL可能会提高工作效率。
ojrac

5
1.您将使用:“ for db.user.find({” level“:{” $ gt“:30}}))” 2.从技术上讲,您编写的也是脚本,因此不太清楚你的意思是。3.非常有可能使用SQL来制作MMO,实际上,许多MMO都是使用该技术开发的。NoSQL技术是相当新的技术,其性能和灵活性已被Amazon,Google和Facebook等服务所采用。4.在NoSQL中,您需要编写自己的约束,但这仅仅是增加灵活性的代价。
阿里·帕特里克

2
我同意你的三思而后行的说法。这就是我在这里对这个问题所做的部分工作:)
Pran

10
SQL不是灵丹妙药。NoSQL不是灵丹妙药。使用任何技术之前请三思。
stonemetal

5
关于3,问题不仅仅在于SQL ,而在于SQL 落后。一般来说,SQL数据库以延迟为代价获得了出色的吞吐量。对于基于网络的游戏,这可能就是您想要的!对于实时网络游戏而言,可能并非如此,大多数使用SQL的“类似WoW”的MMO都在其前面使用了一个缓存层,这消除了SQL的大部分优点,这就是为什么NoSQL迈出了一大步他们。

18

答案是肯定的,这是一个有效的选择,但是不,这可能不是一个好主意

在游戏方面,NoSQL尝试解决SQL的两个主要问题。

第一个是延迟或延迟。从某种意义上说,SQL数据库的速度非常快,可以在十分之一秒内处理数千个事务或更多事务。从另一种意义上说,它们的运行速度非常慢,因为仅处理少量事务可能花费相同的时间。对于大多数数据库使用而言,这无关紧要,但是游戏具有实时组件,因此,它不仅与您每秒可以执行的事务数量有关,还与响应数据库事务所需的平均时间有关。

此延迟是实时游戏的主要问题。许多需要大型数据库(通常用于MMO)的开发人员会在数据库和游戏服务器之间建立一个缓存层,以避免这些停顿,然后定期刷新缓存。问题?您只是抛出了使用数据库的主要原因- 原子性,一致性,隔离性和持久性

但是这个问题不适用于网页游戏。您已经在播放器和游戏之间建立了高延迟连接,因此您也可能会获得SQL提供的吞吐量以及成熟的知名软件的好处。

但是,第二个问题确实适用于您,那就是对象关系阻抗不匹配。游戏处理对象,数据库处理行。如果幸运的话,只需列出对象的字段即可将其划分为一行,但是大多数情况下对象是分层的,因此您必须以某种方式将它们展平以使其成行。

基于文档的数据库(例如CouchDB和MongoDB)通过将文档提升为顶级对象而不是行(在这种情况下,“文档”是“对象”的同义词)来解决此问题。但是这样做会失去SQL数据库的许多好处。吞吐量要低得多,并且锁定算法变得更加复杂。

好消息是,已经有很多对象关系映射(ORM)工具可用于您使用的任何语言。它们使您可以相当透明地在内存中的对象与数据库中的行之间进行转换。这些工具通常不适合大型实时游戏,因为它们会表现出SQL和NoSQL数据库性能最差的方面。但这对于网络游戏来说很好-最坏的情况是,当您遇到性能问题时,可以回到老式的交易方式。延迟问题并没有伤害您,增加的吞吐量可以帮助您。

最后,要掩饰我在其他地方提出的观点这与静态游戏数据无关。我不是在这里谈论您的物品说明或武器损坏或精灵或其他任何东西。我的意思是真实,易变的游戏数据,例如玩家库存中的数据或他们的统计数据。您需要的静态数据就是数据存储。也许事实证明,最简单的方法是使用与数据存储相同的数据库,因为您的ORM很好。也许您只需要文件系统。这是两个单独的问题,一个答案不需要(也可能不会)适合两种情况。


1
+1感谢两个选项的比较。此外,您可以说静态数据不应位于数据库中,这是一个很好的观点。

1
+1但是,我认为您忽略了No SQL的主要优点之一(取决于角度,是赞成还是反对),这是因为它没有架构,可以存储高度动态的数据。实际上,在我当前的项目中,我将结合使用PostgreSQL与适合关系模型的东西,而将Mongo与半静态的东西结合在一起。(例如,可以用来生成重播的日志,在关系上,我必须有一个存储许多其他表之一的PK的列,或者具有通用列名的表,例如param1 param2)
Davy8

1
@ Davy88:noSQL不一定不需要架构,而拥有“高度动态”数据库并不是真正的优势。如果您只有数据汤,就无法进行索引编制,也无法进行字段级锁定,甚至简单的查询都充满了关于如果不存在键会发生什么的问题。

@ user744,您提到的那些东西完成了什么?
expiredninja 2014年

5
  • noSQL数据存储(基于文档,例如MongoDB)是否适合基于Web的游戏?

我建议看一看couchdb

它的界面基于javascript,因此可以与基于HTML5 / javascript的游戏完美融合。

它还可以“脱机”工作(制作数据库的本地副本),然后稍后与服务器进行同步(例如,您可以将其用于实例地下城)。

  • 使用传统的RDBMS(例如MySQL)可能会出现什么问题?

主要的问题是,无SQL数据库与关系数据库的处理方式大不相同。进行心理转换可能很困难。

例如,看一下在ouchdb 中如何执行“ 查询 ”。一切都在javascript中完成。

  • 如何在玩游戏或定时事件(例如cron作业)期间,确保使用MongoDB的用户之间的数据一致性?

“同步”数据库的过程在沙发数据库的术语中称为复制。您还将经常看到术语一致性。有几种内置服务可处理复制和一致性。例如,请参见增量复制过程。


是的,我也听说过couchdb,实际上,即使在mongodb的网站上,他们通常也会对此进行比较。我认为我需要研究沙发床vs mongodb。

2

根据您游戏中的物品,您可能最终会同时使用这两者,并通过游戏中的模型将它们连接起来。例如,播放器可以并且应该位于RDB(登录信息)中,但是播放器库存/变量存储可以转到noSQL,因此播放器模块可以login()使用RDB并fetchInventory()通过主键使用noSQL。

例如,最好将地图保存在NoSQL中(例如,coordinates =>不同对象的数组),我无法想象保存RDB中包含的区域(除了需要完全反序列化才能读取?更多CPU的某些部分的序列化字符串之外)并且浪费了RAM!)您仍然可以在RDB中保存区域,例如,区域“ city X”包含以下坐标/块([3,4],[8,7] ...)

您可以并且可能应该同时使用两者,并查看您可能需要的易失性存储(如内存缓存)或一些临时数据(肯定会比使用硬盘快!并且可以节省大量CPU,但不能节省RAM)

所以最后>

这取决于您想要在游戏中拥有什么!啦啦队


您认为哪些功能会让您更喜欢NoSQL或持久层,就像我想的那样?
expiredninja 2014年

1
如果您的游戏是基于GPS的,则可能是坐标系,这可能需要高级搜索。基本上,如果您对MySQL很好,然后坚持使用它,是否也可以将它用作nosql
Ronan Dejhero 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.