Hello everybody, I have been trying to think what is the best way of saving data to very large datastore, I expect the datastore size to be near the datastore limit.
So I was currently thinking about two methods.
Method
Keys will be the clans UUID and I can just index the clan easily by doing data[UUID]
local data = {}
data["UUID"] = {
Name = "",
Members = {},
}
Method
The whole datastore is going to be an array - indexing of the clan is going to be done by pairs loop
local data = {}
table.insert(data,{
clanId = "UUID"
Name = "",
Members = {},
})
Please let me know if thereâs better approach to do so or which method should I use.
How willing are you to wait for DataStore V2 to face stable release or completely set up your DataStores with experimental features with a way to handle cases of potential failure? Additionally, are you willing to not query DataStores frequently and only if you need them?
If youâre willing to run these assumptions then save clan data in separate keys and use ListKeysAsync if you want to get a list of all existing guilds in your experience. As for how you should display them, youâll probably want to save on request budget and only display them if the user searches for them or you have, for example, a guild recommendation feature.
Any static information should be cached on the server. If youâre caching any changing data, you may want to let the player know when youâre stalling for more request budget or when the cache was last updated so they understand if theyâre working with updated information or not.
Generally you should not collate data like this into a single key. Keys should be unique to a data set.
My project is far from release so I am willing to wait for a bit.
I just realized it after I wrote this topic that saving under one key wonât be a good idea.
My idea is to update the info about the clan on change so for example I want to change clanâs name and then I will call updateasync. The thing with this is the probability of abuse because more than one player are going to be able to change clanâs info but this can be probably prevented by storing clanâs UUID to table and set change info cooldown.
All active clans in the server will be cached in table and Info replicated via folders in replicated storage with attributes.
Additional question:
Am I going to be able prevent âduplicated namesâ of clans with the ListKeysAsync? Because this is probably my biggest concern right now.
My concern as well since Iâm working on a guild system as well: you probably might have difficulty here unless you actually fetch clan data since ListKeysAsync only returns keys in your DataStore at the moment and additional querying options are still in development. In my case, I intend to use guild names as the identifier and it canât be changed without creating a new guild. Not the best user experience but Iâve got to work with what I have access to and this seemed the most sound.
Thatâs unfortunate but I donât really want to use guild names as a key but as I am seeing your reply thereâs no probably no other efficient way to do it.
My original idea was to make second key in datastore with the name of the clan that will be holding the clanâs UUID and upon rename I can just Remove the key from datastore and create new one.
Check for if the guild name exists would work like that:
local guildName = "somethingx1"
local guildNameRequest = dataStore:GetAsync("@"..guildName) --// the @ is there to prevent conflict with randomly generated UUID
if (not guildNameRequest) then
return true
else
return false
end
I donât really get what benefit would this have, because creating new key in datastore is probably faster than caching received data from MessagingService to table and check if anybody isnât trying to make guild with same name.
But when I am thinking about it now it can be a good idea, but I donât really know if MessagingService is fast enough for it to be even good.
I donât really see the issue here since you are going to call the GetAsync and UpdateAsync here only once and the updates are going to be done only per certain time and on change.
Well thatâs a good idea but how I would go about it?
Something like this?
local currentlyAddedNames = {}
local function getValidName(guildName)
local guildNameRequest = dataStore:GetAsync("@"..guildName) --// the @ is there to prevent conflict with randomly generated UUID
--// Messaging Service implementation
local MessagingConnection = MessagingService:SubscribeAsync("guildNames",function(message)
table.insert(currentlyAddedNames,HttpService:JSONDecode(message.Data))
end
if (not guildNameRequest and not table.find(currentlyAddedNames,guildName)) then
MessagingService:PublishAsync("guildNames",guildName)
MessagingConnection:Disconnect()
return true
else
MessagingConnection:Disconnect()
return false
end
end
You should connect this when the create Guild menu is opened.
Multiple servers contribute to an experience limit (time between request never mentioned) meaning if two clients created a Guild with the same name, two Get requests would be issued possibly causing one to throttle.