ソートされたメモリストア のデータ構造では、オプションのソートキーを使用して、頻繁にメモリ内のデータをキー-値ペアとして保存し、ソートキーとキーに基づいて特定の順序を維持できます。キューとは異なり、マップに入るキーの順序は処理の順序を決定しないため、ソートされたマップは、ランキングベースのデータ組織を実装するために、リーダーボードやクロスサーバーオークションのようなエンゲージメントに使用できる排序基準のデータ組織を有用にします。
制限
データ構造サイズ制限に加えて、ソートマップには、128文字のキーサイズ制限、32KBの値サイズ制限、および128文字のソートキーサイズ制限があります。
エクスペリエンスにこの制限を超えるデータを保存する必要がある場合は、 キープレフィックス を通じて複数のデータ構造に分割して配布するためのシャーディング技術を採用できます。シャーディングメモリストアも、システムのスケーラビリティを向上させるのに役立ちます。
ソートされたマップを取得
ソートされたマップを取得するには、MemoryStoreService:GetSortedMap() に 名前 を指定して、マップに定義したい名前を呼び出します。名前はエクスペリエンス内でグローバルなので、名前を使用して任意のスクリプトで同じソートマップにアクセスできます。
ソートされたマップを取得する
local MemoryStoreService = game:GetService("MemoryStoreService")local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
ソートされたマップを取得した後、次の機能のいずれかを呼び出して、その中にデータを読んだり書いたりします:
機能 | 行動 |
---|---|
MemoryStoreSortedMap:SetAsync() | 追加 新しいキーを追加するか、既存のキーの値を上書きし、またはソートキーを変更する場合、キーがすでに存在する場合。 |
MemoryStoreSortedMap:GetAsync() | 特定のキーを読む |
MemoryStoreSortedMap:GetRangeAsync() | すべての既存のキー、または特定の範囲をすべて読む |
MemoryStoreSortedMap:UpdateAsync() | 更新 ソートマップから回収した後、キーの値と/またはソートキーの値を更新する |
MemoryStoreSortedMap:RemoveAsync() | 除去 キーをソートされたマップから削除。 |
データを追加または上書きする
ソートされたマップの新しいキーを追加するか、キーの値またはソートキーを上書きするには、名前キー、値、秒単位の有効期限、そしてオプションのソートキーを使用して、名前キー、値、そしてオプションのソートキーを呼び出します。キーが期限切れになると、メモリは自動的にクリーンアップされます。最大有効期限は 3,888,000秒 (45日)です。提供された場合、ソートキーは有効な数 (整数または浮動小数) または文字列である必要があります。
キーの並べ替え順序では、ソートキーがキーより優先されます。たとえば、上昇順に並べ替えるとき、数字の並べ替えキーが最初に並べ替えられ、次に文字列の並べ替えキー、次に排列キーのないアイテムが並べ替えられます。数字のソートキーを持つすべてのアイテムは、2つのアイテムのソートキーが同じ場合、キーでソートされます。同様に、ストリングソートキーを持つすべてのアイテムは、2つのアイテムのソートキーが同じ場合、キーでソートされます。ソートキーがないすべてのアイテムは、キーだけでソートされます。
上昇順に並べ替えられたデータの例 -
{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}
ソートキーで全てのキーをソートする方法を観察してください。 Note how player0 sorts after all keys with a sort key.player6 全てのキーに数字のソートキーが付いた後に種類が決まります。player4 と player5 は、同じ種類のキーを持っているので、キーで上から順に並べ替えられます。
ソートされたマップにデータを追加する
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
データを取得する
特定のキーに関連するデータ値を取得して並べ替えるか、範囲内のキーの値を複数取得して並べ替えることもできます。
1つのキーでデータを取得する
ソートマップから 1つのキーに関連する値とソートキーを取得するには、キー 名 で 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() を呼び出します。この機能は、デフォルトですべての既存のキーをリストしますが、キー範囲の上限と下限を設定できます。たとえば、次のコードサンプルは、10 より大きなキー、100 より大きなソートキー、および 50 より小さなキー、500 より小さなソートキーを含む、ソートされたマップの最初から最大 20 アイテムを取得します。
ソートされたマップからキーの範囲を取得する
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
データを更新する
ソートされたマップからキーの値とソートキーを取得し、更新するには、 にキー 名 、 コールバック関数 を呼び出して、このキーの値とソートキーを更新し、秒で期限時間 を更新します。最大有効期限は 3,888,000秒 (45日)です。
ほとんどのエクスペリエンスでは、複数のサーバーが同時に同じキーを更新し、値を変更できます。As 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() に似ています。
競合が発生すると、システムはこれらのうちの 1つが発生するまで、操作を自動的に再試行します:操作が成功し、コールバック関数が nil を返すか、リトライの最大数に達します。システムが最大リトライ数に達すると、コンフリクトが返されます。
データを削除
を使用して、ソートマップから 1 つのキーを削除し、メモリストのソートマップにすべてのデータを削除することができます。
キーを削除する
ソートされたマップからキーを削除するには、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")
-- 初期の null の最低値の最初のアイテムからフラッシュ開始
local exclusiveLowerBound = nil
while true do
-- 現在の下限から最大 100 個のアイテムを取得する
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)
-- 範囲が 100 アイテム未満の場合、マップの端に到達する
elseif #items < 100 then
break
else
-- 最後に取得されたキーは、次のイテレーションの独占的な下限です
exclusiveLowerBound = {}
exclusiveLowerBound["key"] = items[#items].key
exclusiveLowerBound["sortKey"] = items[#items].sortKey
end
end
end