内存存储排序地图

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

排序地图 数据结构的内存存储允许您存储频繁的内存数据为键-值对,带有可选排序键,并根据排序键和键保持特定的顺序。与队列不同,进入地图的键的顺序不会决定处理顺序,使排序的地图对排序基于数据组织实现在体验中的实体有用,例如排行榜和跨服务器拍卖。

限制

除了 数据结构大小限制 外,排序地图还有 128 个字符的键大小限制、 32 KB 的值大小限制和 128 个字符的排序键大小限制。

如果需要存储超出此限制对您的体验的数据,您可以采用碎片技术将其分割并通过 键前缀 分配到多个数据结构。碎片化内存存储也可以帮助提高系统的可扩展性。

获取排序的地图

要获得排序的地图,请调用 MemoryStoreService:GetSortedMap() 并将 名称 传给地图,您想为地图定义的。名称在体验中是全球的,因此您可以使用名称访问任何脚本的相同排序地图。

获取排序地图

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")

在你得到排序的地图后,调用以下任意函数来在其中读取或写入数据:

函数行动
MemoryStoreSortedMap:SetAsync()添加 新的键或覆盖值并/或排序键,如果键已存在。
MemoryStoreSortedMap:GetAsync()阅读 特定的键。
MemoryStoreSortedMap:GetRangeAsync()阅读所有现有的键或特定范围的它们。
MemoryStoreSortedMap:UpdateAsync()更新 将键值和/或排序键从排序地图中恢复后的值。
MemoryStoreSortedMap:RemoveAsync()移除 从排序地图中删除一个键。

添加或覆盖数据

要添加新的键或覆盖排序地图中键的值或排序键的值,请使用 MemoryStoreSortedMap:SetAsync()名称 、其 、秒内的 过期时间 和一个 可选排序键 。一旦钥匙过期,内存会自动清理。最大有效期为 3,888,000 秒(45 天)。如果提供,排序键必须是有效数字(整数或浮点)或字符串。

在你的钥匙排序顺序中,排序键在键之前占有优先权。例如,当按升序排序时,数字排序键首先排序,然后是字符串排序键,然后是没有排序键的项目。所有具有数字排序键的项目按排序键排序,如果两个项目的排序键相同,则按键排序。同样,所有带有字符串排序键的项目都按排序键排序,如果两个项目的排序键相等,它们按键排序。所有没有排序键的项目只按键排序。

排序在上升顺序的一些数据的示例 -


{Key: "player1", Value: someValue1, SortKey: -1}
{Key: "player2", Value: someValue2, SortKey: 0}
{Key: "player4", Value: someValue3, SortKey: 1}
{Key: "player5", Value: someValue4, SortKey: 1}
{Key: "player3", Value: someValue5, SortKey: 3.14}
{Key: "player6", Value: someValue6, SortKey: "someString"}
{Key: "player0", Value: someValue7}
{Key: "player7", Value: someValue8}

注意如何 player0 排序所有具有排序键的键。player6排序所有具有数字排序键的键后。player4player5 拥有相同的排序键,因此它们按键排序在上升顺序。

将数据添加到排序地图

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, 3.14152)
end)
if setSuccess then
print("Set succeeded.")
end

获取数据

您可以获得与特定键相关的数据值和排序键,或获得范围内键的多个值和排序键。

使用一个键获取数据

要从排序地图中获得一个关键所属的值和排序键,请调用 MemoryStoreSortedMap:GetAsync() 与关键 名称

从排序地图中获取特定键

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, 3.14152)
end)
if setSuccess then
print("Set succeeded.")
end
local item
local getSuccess, getError = pcall(function()
item = sortedMap:GetAsync("User_1234")
end)
if getSuccess then
print(item)
else
warn(getError)
end

使用多个钥匙获取数据

要将多个键的数据从排序地图作为单个操作获取,请调用 MemoryStoreSortedMap:GetRangeAsync() 。此函数默认列出所有现有键,但您可以设置键范围的上限和下限。例如,以下代码示例可以检索到最多 20 个物品,从排序地图的开始始终以键大于或等于 10 、排序键大于或等于 100 和键小于或等于 50 排序,键小于或等于 500 排序。

从排序地图获取一系列键

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local lowerBound = {}
lowerBound["key"] = "10"
lowerBound["sortKey"] = 100
local upperBound = {}
upperBound["key"] = "50"
upperBound["sortKey"] = 500
-- 从一开始就获得最多 20 个物品
local getSuccess, items = pcall(function()
return sortedMap:GetRangeAsync(
Enum.SortDirection.Ascending, 20, lowerBound, upperBound)
end)
if getSuccess then
for _, item in items do
print(item.key)
print(item.sortKey)
end
end

更新数据

要从排序后的地图中恢复值和排序键的值并更新它,请使用 MemoryStoreSortedMap:UpdateAsync()名称 调用 回调函数 来更新该键的值和排序键,并在秒内设置 过期时间 。最大有效期为 3,888,000 秒(45 天)。

对于大多数体验,多个服务器可以同时更新相同的键并更改值。由于 UpdateAsync() 总是在更新前修改最新值,您应该使用它来阅读最新值作为调用函数的输入。

例如,以下代码示例更新了游戏中玩家的排行榜分数。得分计算为击杀/死亡。UpdateAsync() 确保多个游戏服务器同时更新相同物品,即使最新值更新,击杀和死亡也会更新到最新值。玩家的击杀和死亡是一致增加的值,因此只能在会话中增加价值。

在排序地图中更新玩家的排行榜分数

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("Leaderboard")
local function updateLeaderboard(itemKey, killsToAdd, deathsToAdd)
local success, newStats, newScore = pcall(function()
return sortedMap:UpdateAsync(itemKey, function(playerStats, playerScore)
playerStats = playerStats or { kills = 0, deaths = 0 }
playerStats.kills += killsToAdd
playerStats.deaths += deathsToAdd
if playerStats then
-- `playerScore` 是用于在地图中排序项目的排序键
playerScore = playerStats.kills / math.max(playerStats.deaths, 1)
return playerStats, playerScore
end
return nil
end, 30)
end)
if success then
print(newStats)
print(newScore)
end
end

UpdateAsync() 的延迟与 GetAsync()SetAsync() 相似,除非存在竞争。

当竞争发生时,系统会自动重试操作,直到其中一个三者之一发生:操作成功,回调函数返回 nil 或最大重试次数达到。如果系统达到最大重试次数,它将返回冲突。

删除数据

您可以使用 MemoryStoreSortedMap:RemoveAsync() 来从排序地图中删除一个键和从内存存储排序地图中删除所有数据。

删除钥键

要从排序地图中删除钥匙,请调用 MemoryStoreSortedMap:RemoveAsync() 并将键名称 输入

从排序地图中删除一个键

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, "someStringSortKey")
end)
if setSuccess then
print("Set succeeded.")
end
local removeSuccess, removeError = pcall(function()
sortedMap:RemoveAsync("User_1234")
end)
if not removeSuccess then
warn(removeError)
end

删除所有数据

要删除排序的地图中的内存,列出所有的键,使用 MemoryStoreSortedMap:GetRangeAsync() 将它们移除,然后使用 MemoryStoreSortedMap:RemoveAsync() 移除它们。

在排序地图中删除内存

local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
-- 初始零值下限从第一个物品开始刷新
local exclusiveLowerBound = nil
while true do
-- 从当前最低限度开始,获得最多一百个项目
local getRangeSuccess, items = pcall(function()
return sortedMap:GetRangeAsync(Enum.SortDirection.Ascending, 100, exclusiveLowerBound)
end)
if getRangeSuccess then
local removeSuccess = true
local removeError = nil
for _, item in items do
removeSuccess, removeError = pcall(function()
sortedMap:RemoveAsync(item.key)
end)
end
-- 如果删除物品时出错,请使用相同的专用最低限度再试一次
if not removeSuccess then
warn(removeError)
-- 如果范围小于一百个项目,地图边缘已达到
elseif #items < 100 then
break
else
-- 最后一个被检索的键是下一轮的独家下限
exclusiveLowerBound = {}
exclusiveLowerBound["key"] = items[#items].key
exclusiveLowerBound["sortKey"] = items[#items].sortKey
end
end
end