在关系数据库中存储播放器背包等数据的最佳方法是什么?
让我们说,我想将玩家背包存放在数据库中。
表的数据库模型" eq"看起来像:
playerId | slot | itemId | amount
现在让我们说,我在数据库中有这一行:
1 | 10 | 20 | 99
这意味着,具有Id 1的玩家在第10个插槽中有99个id为20的项目。将这些数据读取到游戏中很容易(如果带有插槽Y的行不存在,则意味着它是空的),但保存这些数据有点棘手。为什么?因为如果玩家使用99项id 20,他的背包将在RAM中为空,但数据库中仍然会有行。当玩家将项目移动到另一个插槽时,如何知道何时删除数据库中的插槽?
这是我的两个想法,看起来很糟糕:
当玩家注册新帐户时,我可以将X空行添加到" eq"表,带有他的id和后面的插槽(1,2,3,4 ...),然后保存只是迭代播放器eq并更新属于播放器的每个行
保存程序开始时,删除所有" eq"属于播放器的行,然后插入数据库仅此行,其中是项目(留空插槽)
答案 0 :(得分:1)
如果您的背包是固定尺寸或很少更换,而且不是太大,那么在注册期间为所有插槽创建行可能会有好处。我认为这意味着只有在添加或删除玩家时才会更新索引,优化程序使用的统计信息应保持稳定有效。在这样的表上使用INSERT ... ON DUPLICATE KEY UPDATE ...
查询以确保在意外删除行的情况下进行自我修复可能是个好主意。它不应该只比UPDATE
您还应该能够进行单独的插槽更新。每当玩家使用背包中的物品时,UPDATE
该插槽的内容。如果添加了新项,请发送INSERT
命令。如果使用了插槽中的最后一项,请改为发送DELETE
命令。移动项目时,您只需UPDATE
行即可更改插槽编号。您应该在内存中有足够的上下文来确定要做什么,并且任何时候只有一个玩家可以登录到一个帐户,对吗?如果您预先创建广告位,则只需执行合适的UPDATE
命令,而不是INSERT
/ DELETE
命令。
如果由于某种原因您无法更新各个插槽,则可以将整个背包保存在两个查询中。我会发送一个INSERT ... ON DUPLICATE KEY UPDATE ...
命令,其中包含每个包含项目的插槽的值。然后我会发送一个DELETE FROM eq WHERE playerId = ...
查询,如果背包没有空,请在AND slot NOT IN (...)
附加填充的插槽列表。这样,您就不会删除并创建不必要的行,这应该更有效。使用预先创建的插槽,您可以在一个查询中执行此操作。