I want to save my users information in hashes. I want to create a hash for each user in the application.
The hashes name is like this: "user:1001"
Now, i want to users id start from 1000 and increase by one.
how can i do this?
thanks
You can have a key called user:id, which will be a number that you will increment to obtain new ids. In your case, you can set the initial value to 1000:
SET user:id 1000
Then by using INCR you will be able to get a new id for your next user:
INCR user:id
Depending on the language you use, there may be already some tools to solve this problem. I would recommend you check Ohm, or one of the ports.
Related
I am working with the redis-cli tool and querying my redis database.
I am storing my keys in redis in the following fashion
H:name:id
where name is a specific string related to the value data and id is the specific id related to the value data.
In this case, I am trying to input new value data into an existing key, where the id stays the same, but the name is changing in the key (new_name).
H:name:id -> H:new_name:id (where -> means to replace)
I am having trouble setting the new value to the existing key, when I change the name to new_name.
Instead redis is creating two different keys,
H:name:id
H:new_name:id
Any suggestions?
Thank you!
What redis commands are you trying? This should work:
rename H:name:id H:new_name:id
How can I store collection with key-value pairs in Redis? For example, I want to log time when user tried to login, to some collection. Every user have id, so I want to use it as a key. But I want to store it separatly from other elements, in separate collection
For each user you can have a sorted set. You can use the user id in the name of the sorted set. Just use 1 as the value since you don't need to store something there and use the timestamp as the score.
zadd 'user:' + uid +':logins' currentTimestamp 1
With this you can run queries to grab how many times a user tried to login during certain periods with zcount etc.
I need to store an array of ints. Now my issue is, there's an operation that's done quite a few times so I'd like to limit it to one single query. In tha query, I would need to add an int to a certain int from the array.
It's for a timer of the time spent on a certain page. Currently it's just a general counter that counts for all the pages in the same field, so I only have to do
UPDATE user SET active = active+$totaltime WHERE id=:id
with the $totaltime being the time difference between last check and then. Now I'd like to store for certain pages seperately. The problem is I don't know exactly how many pages there will be. I thought about using serialize, but then I'd need to do 2 queries a lot of times which doesn't seem like a good solution.
Are there any other methods to do so?
What you need is a separate table for the levels which keeps track of active time associated with each user on each level.
Lets calls this table userlevels, and give it the following columns:
userid INT
levelid INT
active INT
The primary key should be a combination of the userid and leveid columns, since there can only be one entry for a particular combination of user and level.
Then when you want to update the amount of time a user has spent on a certain level, you would do something like:
INSERT INTO userlevels (userid,levelid,active)
VALUES (:userid,:levelid,$totaltime)
ON DUPLICATE KEY UPDATE active=active+$totaltime;
This creates a new entry in the table if the user has never been on that level before, or adds to the active time if there is already an entry.
This is mysql specific syntax, but the same thing can be achieved on other databases with different calls.
I have a problem I'm not sure how to solve elegantly.
Background Information
I have a table of widgets. Each widget is assigned an ID from a range of numbers, let's say between 1-999. The values of 1-999 is saved in my database as "lower_range" and "upper_range" in a table called "config".
When a user requests to create a new widget using my web app, I need to be able to do the following:
generate a random number between 1 and 999 using lua's math.random function or maybe a random number generator in sqlite (So far, in my tests, lua's math.random always returns the same value...but that's a different issue)
do a select statement to see if there already is a widget with this number assigned...
if not, create the new widget.
otherwise repeat process until you get a number that is not currently in use.
Problem
The problem I see with the above logic is two-fold:
the algorithm can potentially take a long time because I have to keep searching until I find a unique value.
How do I prevent simultaneous requests for new widget numbers generating the same value?
Any suggestions would be appreciated.
Thanks
Generate your random numbers ahead of time and store them in a table; make sure the numbers are unique. Then when you need to get the next number, just check how many have already been assigned and get the next number from your table. So, instead of
Generate a number between 1-999
Check if it's already assigned
Generate a new number, and so on.
do this:
Generate array of 999 elements that have values 1-999 in some random order
Your GetNextId function becomes return ids[currentMaxId+1]
To manage simultaneous requests, you need to have some resource that generates a proper sequence. The easiest is probably to use a key in your widget table as the index in the ids array. So, add a record to the widgets table first, get its key and then generate widget ID using ids[key].
Create a table to store the keys and the 'used' property.
CREATE TABLE KEYS
("id" INTEGER, "used" INTEGER)
;
Then use the following to find a new key
select id
from KEYS
where used = 0
order by RANDOM()
limit 1
Don't generate a random number, just pick the number off a list that's in random order.
For example, make a list of numbers 1 - 999. Shuffle that list using Fisher-Yates or equivalent (see also Randomize a List in C# even if you're not using C#).
Now you can just keep track of the most recently used index into your list. (Shuffling the list should occur exactly once, then you store and reuse the result).
Rough pseudo-code:
If config-file does not contain list of indices
create a list with numbers 1 - 999
Use Fisher-Yates to shuffle that list
// list now looks like 0, 97, 251, 3, ...
Write the list to the config file
Set 'last index used' to 0 and write to config file
end if
To use this,
NextPK = myList[last-index-used]
last-index-used = last-index-used + 1
write last-index-used to config file
To get and flag an ID as used at same time (expanding on Declan_K's answer):
replace into random_sequence values ((select id from random_sequence where used=0 order by random()), 1);
select id from random_sequence where rowid = last_insert_rowid();
6
When you run out of "unused" sequence table entries the select will return "blank"
I use replace into as update doesn't have an last_insert_rowid() equiv that I can see.
You Can get sql to create a primary key, that will increase by one evert time you add a ros to the database.
I have been experimenting with Redis, and I really like the scalability that it brings to the table. However, I'm wondering how to handle changes to data structures for a system that's already in production.
For example, let me say that I am collecting information about a user, and I use the user_id as a key, and dumping the other data about the user as comma separated values.
user_id: name, email, etc.
Now, say after about 100,000 records, I realise that I needed to query by email - how would I now take a snapshot of the existing data and create a new index for it?
Using csv is not a great idea if you want to support changes. You need to use a serializer that handles missing/new values if everything is in one key, or you can use a redis hash, which gives you named subkeys. Either way you can add/remove fields with the only requirement being that your code knows what to do if it reads a record without the new value.
To allow lookup by email you need to add an index - basically a key (or list) for each email with the user id as the value. You will need to populate this index by getting all keys once, then making sure you update it when emails change.
You could iterate over all keys and store them with a different id, but that is probably more trouble than it is worth.
From my understanding of Redis, this would require something which Redis is not designed to do. You would have to loop though all your records (using keys *) and then change the order of the data and make a new key. I, personally, would recommend using a list instead of a comma separated string. In a list, you can reorder it from inside redis. A Redis List looks like the following:
"Colum" => [0] c.mcgaley#gmail.com
[1] password
[2] Something
I am building an app in which I encountered the same problem. I solved it by having a list for all the user's info, and then have a key with the user's email with a value of the user's id. So my database would something like this:
"Colum" => [0] c.mcgaley#gmail.com
[1] password
[2] Something
"c.mcgaley#gmail.com" => "Colum"
So I could query the ID or the Email and still get the information I needed.
Sorry that I was not able to directly answer your question. Just hope this helped.