内存存储排序映射

*此内容使用人工智能(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:GetSizeAsync()获取排序映射中的项目数量。

添加或覆盖数据

要添加新键或覆盖排序映射中键的值或排序键,请调用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("设置成功。")
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("设置成功。")
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`是用于对映射中项进行排序的sortKey
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("设置成功。")
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")
-- 初始下限为nil,从第一个项目开始刷新
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

获取大小

要获取排序映射中的项目数,请调用 MemoryStoreSortedMap:GetSizeAsync()

获取排序映射的大小

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("设置成功。")
end
local size
local success, sizError = pcall(function()
size = sortedMap:GetSizeAsync()
end)
if success then
print(size)
else
warn(sizeError)
end
©2026 Roblox Corporation、Roblox、Roblox 标志及 Powering Imagination 是我们在美国及其他国家或地区的注册与未注册商标。