主题
DataStore
概览
| 字段 | 值 |
|---|---|
| Kind | Data · 数据 Data |
| Realm | server |
继承关系
- [DataStore](10 函数)
- OrderedDataStore(1 函数)
数据存储集合,用于在服务端持久化保存键值对数据,支持按键读取、写入、自增、原子更新与删除,并提供键列表遍历和历史版本查询、清理能力。它无法自行创建,只能由 DataStoreService:GetDataStore()、GetGlobalDataStore() 或 GetOrderedDataStore() 返回,是操作某一份持久化存储的入口对象。
适用场景
常用于玩家存档、全局配置或排行榜类数据的持久化:在服务端脚本中先取到存储实例,再以玩家标识等字符串作为键,对存档执行读取、保存或重置操作。
使用要点
先用 game:GetService("DataStoreService") 获取服务,再通过 DataStoreService:GetDataStore("StoreName") 得到 DataStore 实例,并在 Task.Spawn 等协程环境中执行异步读写:GetAsync 读取数据,SetAsync 覆盖写入,UpdateAsync 基于旧值原子修改,RemoveAsync 清除记录。需要遍历时用 ListKeysAsync 分页取得键信息,需要回溯时用 GetVersionAsync、GetVersionAtTimeAsync、ListVersionsAsync 查询历史版本,并用 RemoveVersionAsync 删除指定版本。
注意事项
DataStore 由 DataStoreService:GetDataStore()、GetGlobalDataStore() 或 GetOrderedDataStore() 返回;异步读写应在 Task:Spawn 等协程中调用。各方法的返回值不同:GetAsync 读取数据,SetAsync 首项返回 String 版本号,UpdateAsync 按自身签名返回数据和 DataStoreKeyInfo。WithKeyInfo 仅适用于声明了相应 options 的方法,不应给 UpdateAsync 添加该参数。请分别按每个方法的完整返回签名接收结果,并注意写入频率限制。
代码示例
在协程中读取数据
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local dataStore = DataStoreService:GetDataStore('StoreName')
local key = "attack"
local options = DataStoreGetOptions.New()
Task:Spawn(function()
local result = dataStore:GetAsync(key, options)
if result ~= nil then
print("调用成功,结果: " .. tostring(result))
end
end)函数 (10)
GetAsync
签名:GetAsync(key: String, options?: DataStoreGetOptions) -> Any (数据值, key 不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
GetAsync 按 key 读取 DataStore 中当前存储的数据值。参数 key 为字符串键名,可选参数 options 为 DataStoreGetOptions,用于描述本次读取的选项。返回值为数据值本体,当 key 不存在时返回 nil;当 options 中开启 WithKeyInfo 时,第二个返回值给出 DataStoreKeyInfo 键信息。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
options? | DataStoreGetOptions | 可选参数, 优先级高于 DataStore 初始化时的 DataStoreOptions, 可通过 DataStoreGetOptions.New() 创建 |
返回值 Any (数据值, key 不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
读取玩家数据
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local playerId = 'demo-player'
Task:Spawn(function()
local data = store:GetAsync('player_' .. playerId) -- 必须传 key
print('读取到:', data)
end)SetAsync
签名:SetAsync(key: String, value: Any, options?: DataStoreSetOptions) -> String (版本号), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
SetAsync 将数据值写入指定 key。参数 key 为字符串键名,value 为要写入的数据,第三个可选参数 options 为 DataStoreSetOptions。返回值为本次写入产生的版本号字符串;当 options 中开启 WithKeyInfo 时,第二个返回值给出 DataStoreKeyInfo 键信息。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
value | Any | 数据值 |
options? | DataStoreSetOptions | 可选参数, 优先级高于 DataStore 初始化时的 DataStoreOptions, 可通过 DataStoreSetOptions.New() 创建 |
返回值 String (版本号), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
写入玩家数据
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local playerId = 'demo-player'
Task:Spawn(function()
store:SetAsync('player_' .. playerId, {coins=100, level=1})
end)IncrementAsync
签名:IncrementAsync(key: String, delta: Int, options?: DataStoreIncrementOptions) -> Any (自增后的值), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
IncrementAsync 对指定 key 的数值执行原子自增。参数 key 为字符串键名,delta 为整数增量,第三个可选参数 options 为 DataStoreIncrementOptions。返回值为自增后的值;当 options 中开启 WithKeyInfo 时,第二个返回值给出 DataStoreKeyInfo 键信息。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
delta | Int | 自增值 (非零) |
options? | DataStoreIncrementOptions | 可选参数, 优先级高于 DataStore 初始化时的 DataStoreOptions, 可通过 DataStoreIncrementOptions.New() 创建 |
返回值 Any (自增后的值), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
原子自增计数
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
Task:Spawn(function()
store:IncrementAsync('login_count', 1) -- delta 必须非零
end)RemoveAsync
签名:RemoveAsync(key: String, options?: DataStoreRemoveOptions) -> Any (删除前的数据值, key 不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
RemoveAsync 删除指定 key 所存储的数据。参数 key 为字符串键名,可选参数 options 为 DataStoreRemoveOptions。返回值为删除前的数据值,key 不存在时返回 nil;当 options 中开启 WithKeyInfo 时,第二个返回值给出 DataStoreKeyInfo 键信息。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
options? | DataStoreRemoveOptions | 可选参数, 优先级高于 DataStore 初始化时的 DataStoreOptions, 可通过 DataStoreRemoveOptions.New() 创建 |
返回值 Any (删除前的数据值, key 不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
删除玩家数据
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local options = DataStoreRemoveOptions.New()
options.WithKeyInfo = true
Task:Spawn(function()
local removedValue, keyInfo = store:RemoveAsync('player_demo', options)
print('删除值:', removedValue, '版本:', keyInfo and keyInfo.Version)
end)UpdateAsync
签名:UpdateAsync(key: String, transformFunction: Function) -> Any (更新后的值, 放弃更新时返回 nil), DataStoreKeyInfo (键信息)
对指定键执行先读后写的复合更新操作:调用时传入键名 key 与转换函数 transformFunction,由转换函数基于该键的当前值计算出要写回的新值;调用返回更新后的值以及键信息 DataStoreKeyInfo,当转换函数放弃更新时返回值中的值为 nil。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
transformFunction | Function | 变换函数 function(currentValue, keyInfo) -> newValue, DataStoreSetOptions?; 返回 newValue=nil 时放弃更新; 可返回 DataStoreSetOptions 自定义写入选项 (如 metas, userIds); 每轮重试都会重新调用 transformFunction 拿到最新值 |
返回值 Any (更新后的值, 放弃更新时返回 nil), DataStoreKeyInfo (键信息)
示例代码
读-改-写原子更新
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local playerId = 'demo-player'
Task:Spawn(function()
store:UpdateAsync('player_' .. playerId, function(oldValue, keyInfo)
if type(oldValue) ~= 'table' then return {coins=50} end
local coins = tonumber(oldValue.coins) or 0
oldValue.coins = coins + 50
return oldValue -- 返回 nil 放弃更新
end)
end)ListKeysAsync
签名:ListKeysAsync(prefix?: String, pageSize?: Int, cursor?: String, options?: DataStoreListKeyOptions) -> DataStoreKeyBriefInfoPages (分页迭代器)
分页列出数据存储中的 key,支持按前缀过滤。
| 参数 | 类型 | 说明 |
|---|---|---|
prefix? | String | 前缀过滤, 默认空字符串 |
pageSize? | Int | 页大小, 默认 0 (使用服务端默认值) |
cursor? | String | 分页游标 |
options? | DataStoreListKeyOptions | 可选参数, 优先级高于 DataStore 初始化时的 DataStoreOptions, 可通过 DataStoreListKeyOptions.New() 创建 |
返回值 DataStoreKeyBriefInfoPages (分页迭代器)
示例代码
分页列出键名
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local options = DataStoreListKeyOptions.New()
options.ExcludeDeleted = false
Task:Spawn(function()
local pages = store:ListKeysAsync('player_', 10, '', options)
for _, keyInfo in ipairs(pages:GetCurrentPage()) do
print('键名:', keyInfo.Key)
end
end)GetVersionAsync
签名:GetVersionAsync(key: String, version: String, options?: DataStoreGetVersionOptions) -> Any (数据值, 版本或 key 不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
按版本号读取指定 key 的历史版本;options 可省略,也可通过 DataStoreGetVersionOptions.New() 创建。
⚙ DataStoreGetVersionOptions 支持 .New(),但不支持类型名直接调用简写。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
version | String | 版本号 |
options? | DataStoreGetVersionOptions | 可选参数;可通过 DataStoreGetVersionOptions.New() 创建,需要 KeyInfo 时设置 WithKeyInfo=true。 |
返回值 Any (数据值, 版本或 key 不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
按版本号读取历史数据
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local key = 'player_demo'
Task:Spawn(function()
local pages = store:ListVersionsAsync(key, false, 0, 0, 10)
local versionInfo = pages:GetCurrentPage()[1]
if versionInfo == nil then
print('当前键没有可读取的历史版本')
return
end
local value = store:GetVersionAsync(key, versionInfo.Version)
print('历史版本数据:', value)
end)GetVersionAtTimeAsync
签名:GetVersionAtTimeAsync(key: String, timestamp: Int, options?: DataStoreGetVersionOptions) -> Any (数据值, 该时间点无对应版本时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
按时间点读取指定 key 在该时间附近的历史版本;options 可省略,也可通过 DataStoreGetVersionOptions.New() 创建。
⚙ DataStoreGetVersionOptions 支持 .New(),但不支持类型名直接调用简写。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
timestamp | Int | 时间戳 (毫秒) |
options? | DataStoreGetVersionOptions | 可选参数;可通过 DataStoreGetVersionOptions.New() 创建,需要 KeyInfo 时设置 WithKeyInfo=true。 |
返回值 Any (数据值, 该时间点无对应版本时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
按时间点读取历史数据
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
local key = 'player_demo'
local timestamp = 1700000000 * 1000
Task:Spawn(function()
local value = store:GetVersionAtTimeAsync(key, timestamp)
print('指定时间附近的数据:', value)
end)ListVersionsAsync
签名:ListVersionsAsync(key: String, ascending?: Bool, minDate?: Int, maxDate?: Int, pageSize?: Int) -> DataStoreVersionInfoPages (分页迭代器)
列出指定 key 的所有历史版本信息。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
ascending? | Bool | 排序方向, true 时按版本更新时间升序, false 时降序 |
minDate? | Int | 最小时间 (毫秒) |
maxDate? | Int | 最大时间 (毫秒) |
pageSize? | Int | 页大小, 默认 0 (使用服务端默认值) |
返回值 DataStoreVersionInfoPages (分页迭代器)
示例代码
列出指定键的历史版本
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('PlayerBackpack')
Task:Spawn(function()
local pages = store:ListVersionsAsync('player_demo', false, 0, 0, 10)
for _, versionInfo in ipairs(pages:GetCurrentPage()) do
print('版本:', versionInfo.Version, '创建时间:', versionInfo.CreatedTime)
end
end)RemoveVersionAsync
签名:RemoveVersionAsync(key: String, version: String, options?: DataStoreRemoveVersionOptions) -> Any (删除前的数据值, 版本不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
删除指定 key 的历史版本;options 可省略,也可通过 DataStoreRemoveVersionOptions.New() 创建。
⚙ DataStoreRemoveVersionOptions 支持 .New(),但不支持类型名直接调用简写。
| 参数 | 类型 | 说明 |
|---|---|---|
key | String | 键名 |
version | String | 版本号 |
options? | DataStoreRemoveVersionOptions | 可选参数;可通过 DataStoreRemoveVersionOptions.New() 创建,需要 KeyInfo 时设置 WithKeyInfo=true。 |
返回值 Any (删除前的数据值, 版本不存在时返回 nil), DataStoreKeyInfo (键信息 (需 WithKeyInfo=true 才会返回))
示例代码
删除指定历史版本
lua
-- @runtime server
local DataStoreService = game:GetService('DataStoreService')
local Task = game:GetService('Task')
local store = DataStoreService:GetDataStore('DocumentationSandbox')
local key = 'cleanup_demo'
Task:Spawn(function()
local pages = store:ListVersionsAsync(key, false, 0, 0, 10)
local versionInfo = pages:GetCurrentPage()[1]
if versionInfo == nil then
print('当前键没有可删除的历史版本')
return
end
-- 仅在确认该沙盒版本可以删除后执行
local removedValue = store:RemoveVersionAsync(key, versionInfo.Version)
print('删除的版本数据:', removedValue)
end)