pihentagy
pihentagy9mo ago

kv store key granuality

How cheap are the kv.get operations? Say I have a userprofile with 3 fields, should I create 3 keys for them, so that I can easily update th 3 fields, or should I keep number of keys low, and just have one value for the user (in that case when updating, one should first get the "complex" value, update it and then write back the updated value)
4 Replies
Deno AI Helper
Deno AI Helper9mo ago
The documentation does not provide a specific answer to your question about the cost of kv.get operations or the granularity of keys in Deno's key-value store. However, it does provide some insights that might help you make a decision. Firstly, the documentation mentions that Deno KV is designed to be fast and easy to use, and it supports atomic operations that allow multiple modifications to take place at once. This could be beneficial if you decide to use separate keys for each field of a user profile, as you could update all fields in a single atomic operation. On the other hand, the documentation also mentions that keys in Deno KV are sequences of key parts, which allow modeling of hierarchical data. This could be useful if you decide to store all fields of a user profile under a single key, as you could structure the key in a way that represents the hierarchy of the data. In terms of performance, the documentation does not provide specific details. However, it does mention that all writes to the KV store are strongly consistent and immediately durably persisted, and reads are strongly consistent by default. Ultimately, the decision might depend on the specific requirements of your application, such as the frequency of updates to different fields, the complexity of the user profile data, and the need for atomicity of operations.
Kofi GOLO
Kofi GOLO9mo ago
You should use only one key per user like so
kv.set([“users”, “SEQ ID/ULID/UUID”], {
email,
password,
created_at,
});
kv.set([“users”, “SEQ ID/ULID/UUID”], {
email,
password,
created_at,
});
But you should also create some indexes for fast retrieval and search by value Like:
kv.atomic()
.set([“users”, “SEQ ID/ULID/UUID”], {
email,
password,
created_at,
})
.set([“users_by_email”], “SEQ ID/ULID/UUID”)
.commit()
kv.atomic()
.set([“users”, “SEQ ID/ULID/UUID”], {
email,
password,
created_at,
})
.set([“users_by_email”], “SEQ ID/ULID/UUID”)
.commit()
pihentagy
pihentagy9mo ago
Ok, but in that case the upload logic would be a bit more complicated: gettint the whole user object, doing an updated user object, and setting it instead of just boom, addimg a new sub object I mean where there are multiple value to a user
Kofi GOLO
Kofi GOLO9mo ago
Your message is a bit confusing but I assume you want to be able to just send the minimum data possible over the wire (internet connection). Let’s say your user modified one of his attribute/field on his user account panel, you could just send this one field, yes obviously you can. Then on your backend, you GET the WHOLE user back, and modify the field before re-SET the WHOLE user in Deno KV. That’s really simple. It’s not so far from classic SQL logic. But yes in SQL you could do INSERT INTO users (the-single-attribute) VALUES ‘new value’ ___ Although you could envision to set each field of a user one by one, you would have to create a whole “system” hierarchy and DenoKv allows that
kv.atomic()
.set([“Users”,UserId,”email”], john.doe@gmail.com)
.set(…)
.set(…)
.commit()
kv.atomic()
.set([“Users”,UserId,”email”], john.doe@gmail.com)
.set(…)
.set(…)
.commit()
Then in case of retrieval you can get the whole user back like so:
let user = {};
const userFields = kv.list({ prefix: [“users”,UserId] })
for await (const field of userFields) {
user[field.key[2]] = field.value;
}
let user = {};
const userFields = kv.list({ prefix: [“users”,UserId] })
for await (const field of userFields) {
user[field.key[2]] = field.value;
}
Yes it works: https://dash.deno.com/playground/granular-kv