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