Kho dữ liệu

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

DataStoreService cho phép bạn lưu trữ dữ liệu cần duy trì giữa các phiên, như là đồ vật trong kho của người chơi hoặc điểm kỹ năng. Kho dữ liệu là đồng nhất cho từng trò chơi, vì vậy bất kỳ khu vực nào trong trò chơi cũng có thể truy cập và thay đổi cùng một dữ liệu, bao gồm các khu vực trên các máy chủ khác nhau.

Nếu bạn muốn thêm quyền kiểm soát tỉ mỉ cho kho dữ liệu của mình và truy cập chúng bên ngoài Studio hoặc máy chủ Roblox, bạn có thể sử dụng Open Cloud APIs cho kho dữ liệu.

Để xem và theo dõi tất cả các kho dữ liệu trong một trò chơi thông qua Trung tâm Tạo, hãy sử dụng Quản lý Kho Dữ Liệu.

Đối với dữ liệu tạm thời mà bạn cần cập nhật hoặc truy cập thường xuyên, hãy sử dụng bộ nhớ.

Bật quyền truy cập Studio

Theo mặc định, các trò chơi được thử nghiệm trong Studio không thể truy cập kho dữ liệu, vì vậy bạn phải bật chúng trước. Truy cập kho dữ liệu trong Studio có thể nguy hiểm cho các trò chơi đang hoạt động vì Studio truy cập cùng một kho dữ liệu như ứng dụng khách. Để tránh ghi đè lên dữ liệu sản xuất, hãy không bật tùy chọn này cho các trò chơi đang hoạt động. Thay vào đó, hãy bật nó cho một phiên bản thử nghiệm riêng biệt của trò chơi.

Để bật quyền truy cập Studio trong một trò chơi đã được phát hành:

  1. Mở cửa sổ Cài đặt Trải nghiệm trong Tệp ⟩ Cài đặt Trải nghiệm.
  2. Điều hướng đến Bảo mật.
  3. Bật công tắc Bật quyền truy cập Studio vào API Services.
  4. Nhấp vào Lưu.

Truy cập kho dữ liệu

Để truy cập một kho dữ liệu trong một trò chơi:

  1. Thêm DataStoreService vào một Script phía máy chủ.
  2. Sử dụng hàm GetDataStore() và chỉ định tên của kho dữ liệu mà bạn muốn sử dụng. Nếu kho dữ liệu không tồn tại, Studio sẽ tạo một kho khi bạn lưu dữ liệu trò chơi lần đầu tiên.

local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")

Tạo dữ liệu

Một kho dữ liệu về cơ bản là một từ điển, tương tự như một bảng Luau. Một khóa duy nhất chỉ mục cho mỗi giá trị trong kho dữ liệu, như là Player.UserId duy nhất của người dùng hoặc một chuỗi được đặt tên cho một chương trình khuyến mãi trò chơi.

Khóa dữ liệu người dùngGiá trị
3125060850
35167597920
50530609278000
Khóa dữ liệu khuyến mãiGiá trị
ActiveSpecialEventSummerParty2
ActivePromoCodeBONUS123
CanAccessPartyPlacetrue

Để tạo một mục mới, gọi SetAsync() với tên khóa và một giá trị.


local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, errorMessage = pcall(function()
gameStore:SetAsync("User_1234", 50)
end)
if not success then
print(errorMessage)
end

Cập nhật dữ liệu

Để thay đổi bất kỳ giá trị lưu trữ nào trong kho dữ liệu, gọi UpdateAsync() với tên khóa của mục và một hàm callback xác định cách bạn muốn cập nhật mục đó. Callback này nhận giá trị hiện tại và trả về một giá trị mới dựa trên logic mà bạn xác định. Nếu callback trả về nil, thao tác ghi sẽ bị hủy và giá trị sẽ không được cập nhật.


local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local function makeNameUpper(currentName)
local nameUpper = string.upper(currentName)
return nameUpper
end
local success, updatedName = pcall(function()
return nicknameStore:UpdateAsync("User_1234", makeNameUpper)
end)
if success then
print("Tên viết hoa:", updatedName)
end

Set vs update

Sử dụng set để nhanh chóng cập nhật một khóa cụ thể. Hàm SetAsync():

  • Có thể gây ra bất đồng bộ dữ liệu nếu hai máy chủ cố gắng đặt cùng một khóa cùng một lúc
  • Chỉ được tính là một lần ghi

Sử dụng update để xử lý các lần cố gắng của nhiều máy chủ. Hàm UpdateAsync():

  • Đọc giá trị khóa hiện tại từ máy chủ đã cập nhật nó lần cuối trước khi thực hiện bất kỳ thay đổi nào
  • Chậm hơn vì nó đọc trước khi ghi
  • Tính vào cả giới hạn đọc và ghi

Đọc dữ liệu

Để đọc giá trị của một mục trong kho dữ liệu, gọi GetAsync() với tên khóa của mục.


local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, currentGame = pcall(function()
return gameStore:GetAsync("User_1234")
end)
if success then
print(currentGame)
end

Tăng dữ liệu

Để tăng một số nguyên trong kho dữ liệu, gọi IncrementAsync() với tên khóa của mục và một số cho biết mức độ thay đổi giá trị. IncrementAsync() là một hàm tiện lợi cho phép bạn tránh phải gọi UpdateAsync() và tự động tăng số nguyên.


local DataStoreService = game:GetService("DataStoreService")
local gameStore = DataStoreService:GetDataStore("PlayerGame")
local success, newGame = pcall(function()
return gameStore:IncrementAsync("Player_1234", 1)
end)
if success then
print(newGame)
end

Xóa dữ liệu

Để xóa một mục và trả về giá trị liên quan đến khóa, gọi RemoveAsync().


local DataStoreService = game:GetService("DataStoreService")
local nicknameStore = DataStoreService:GetDataStore("Nicknames")
local success, removedValue = pcall(function()
return nicknameStore:RemoveAsync("User_1234")
end)
if success then
print(removedValue)
end

Metadata

Có hai loại metadata liên kết với các khóa:

  • Dịch vụ xác định: Metadata chỉ đọc mặc định, giống như thời gian cập nhật gần đây nhất và thời gian tạo. Mỗi đối tượng đều có metadata được xác định bởi dịch vụ.
  • Người dùng xác định: Metadata tùy chỉnh cho việc gán nhãn và phân loại. Được xác định bằng cách sử dụng đối tượng DataStoreSetOptions và hàm SetMetadata().

Để quản lý metadata, hãy mở rộng các hàm SetAsync(), UpdateAsync(), GetAsync(), IncrementAsync(), và RemoveAsync().

  • SetAsync() chấp nhận các đối số tùy chọn thứ ba và thứ tư:

    • Một bảng UserIds. Điều này có thể giúp theo dõi và xóa nội dung bản quyền và tài sản trí tuệ.

    • Một đối tượng DataStoreSetOptions, nơi bạn có thể định nghĩa metadata tùy chỉnh bằng cách sử dụng hàm SetMetadata().


      local DataStoreService = game:GetService("DataStoreService")
      local gameStore = DataStoreService:GetDataStore("PlayerGame")
      local setOptions = Instance.new("DataStoreSetOptions")
      setOptions:SetMetadata({["GameElement"] = "Fire"})
      local success, errorMessage = pcall(function()
      gameStore:SetAsync("User_1234", 50, {1234}, setOptions)
      end)
      if not success then
      print(errorMessage)
      end
  • GetAsync(), IncrementAsync(), và RemoveAsync() trả về một giá trị thứ hai trong đối tượng DataStoreKeyInfo. Giá trị thứ hai này chứa cả thuộc tính được định nghĩa bởi dịch vụ và các hàm để lấy metadata do người dùng định nghĩa.

    • Hàm GetUserIds() lấy bảng UserIds mà bạn đã truyền cho SetAsync().
    • Hàm GetMetadata() lấy metadata do người dùng định nghĩa mà bạn đã truyền cho SetAsync() thông qua SetMetadata().
    • Thuộc tính Version lấy phiên bản của khóa.
    • Thuộc tính CreatedTime lấy thời gian khóa được tạo, định dạng là số mili giây kể từ thời điểm bắt đầu.
    • Thuộc tính UpdatedTime lấy thời gian gần nhất khóa được cập nhật, định dạng là số mili giây kể từ thời điểm bắt đầu.

    local DataStoreService = game:GetService("DataStoreService")
    local gameStore = DataStoreService:GetDataStore("PlayerGame")
    local success, currentGame, keyInfo = pcall(function()
    return gameStore:GetAsync("User_1234")
    end)
    if success then
    print(currentGame)
    print(keyInfo.Version)
    print(keyInfo.CreatedTime)
    print(keyInfo.UpdatedTime)
    print(keyInfo:GetUserIds())
    print(keyInfo:GetMetadata())
    end
  • Hàm callback của UpdateAsync() nhận một tham số bổ sung trong đối tượng DataStoreKeyInfo mô tả trạng thái hiện tại của khóa. Nó trả về giá trị đã sửa đổi, các khóa liên kết với UserIds, và metadata của khóa.


    local DataStoreService = game:GetService("DataStoreService")
    local nicknameStore = DataStoreService:GetDataStore("Nicknames")
    local function makeNameUpper(currentName, keyInfo)
    local nameUpper = string.upper(currentName)
    local userIDs = keyInfo:GetUserIds()
    local metadata = keyInfo:GetMetadata()
    return nameUpper, userIDs, metadata
    end
    local success, updatedName, keyInfo = pcall(function()
    return nicknameStore:UpdateAsync("User_1234", makeNameUpper)
    end)
    if success then
    print(updatedName)
    print(keyInfo.Version)
    print(keyInfo.CreatedTime)
    print(keyInfo.UpdatedTime)
    print(keyInfo:GetUserIds())
    print(keyInfo:GetMetadata())
    end

Để biết giới hạn khi định nghĩa metadata, xem giới hạn metadata.

Kho dữ liệu có thứ tự

Theo mặc định, các kho dữ liệu không sắp xếp nội dung của chúng. Nếu bạn cần lấy dữ liệu theo cách có thứ tự, như là trong thống kê bảng xếp hạng bền vững, hãy gọi GetOrderedDataStore() thay vì GetDataStore().


local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")

Các kho dữ liệu có thứ tự hỗ trợ cùng các hàm cơ bản như các kho dữ liệu mặc định, cộng với hàm đặc biệt GetSortedAsync(). Điều này cho phép lấy nhiều khóa đã được sắp xếp dựa trên một thứ tự sắp xếp cụ thể, kích thước trang, và giá trị tối thiểu/tối đa.

Ví dụ sau sắp xếp dữ liệu nhân vật thành các trang với ba mục, mỗi mục theo thứ tự giảm dần, sau đó lặp qua các trang và xuất tên và tuổi của từng nhân vật.


local DataStoreService = game:GetService("DataStoreService")
local characterAgeStore = DataStoreService:GetOrderedDataStore("CharacterAges")
-- Điền kho dữ liệu có thứ tự
local characters = {
Mars = 19,
Janus = 20,
Diana = 18,
Venus = 25,
Neptune = 62
}
for char, age in characters do
local success, errorMessage = pcall(function()
characterAgeStore:SetAsync(char, age)
end)
if not success then
print(errorMessage)
end
end
-- Sắp xếp dữ liệu theo thứ tự giảm dần thành các trang ba mục mỗi trang
local success, pages = pcall(function()
return characterAgeStore:GetSortedAsync(false, 3)
end)
if success then
while true do
-- Lấy trang hiện tại (trang đầu tiên)
local entries = pages:GetCurrentPage()
-- Lặp qua tất cả các cặp khóa-giá trị trên trang
for _, entry in entries do
print(entry.key .. " : " .. tostring(entry.value))
end
-- Kiểm tra xem đã đến trang cuối cùng chưa
if pages.IsFinished then
break
else
print("----------")
-- Chuyển sang trang tiếp theo
pages:AdvanceToNextPageAsync()
end
end
end
©2026 Roblox Corporation. Roblox, logo Roblox và Powering Imagination là các nhãn hiệu đã đăng ký và chưa đăng ký của chúng tôi tại Hoa Kỳ và các quốc gia khác.