Binding multiple keys to single value is very useful to omit manual maintance of additional 'index' data structures.

# Create user:
hmset user:12 id 12 name John email a@b.c age 30
hset user/email a@b.c user:12

# Get user name by email:
hget user/email a@b.c
hget user:12 name

# Delete user by email:
hget user/email a@b.c
del user:12
hdel user/email a@b.c

Let me propose such concept:

# Create user:
hmset user:12 id 12 name John email a@b.c age 30
bind user/email:a@b.c user:12

# Get user name by email:
hget user/email:a@b.c name

# Delete user by email (and all bound keys):
del user/email:a@b.c

# Remove additional key, but not a corresponding value (maybe failing if it's a only one key):
unbind user/email:a@b.c

# Set TTL to key:
bexpire user/session:1234567890abcdef1234567890abcdef 2592000

Same example is getting user info/roles/permissions by 'session token' in web backends.

What we get: - Simpler data management in some cases - Fewer 'read' commands => faster client code / less bottlenecks - Guess yourself...)

Comment From: rozzzly

+1

I would love something like this, even though the proposal is rather simplistic. There is a lot more functionality could be added, but at that point I think it might be better to explore using a traditional RDBMS, or following redis' roll-your-own philosophy. Still, some simple functionality like this would be great for prototyping and whatnot.

Somehow, I expect that my sentiment won't be echoed by some of the more active/invested contributors/community members as it probably "violates the structureless, open ended philosophy," or something of the sort. I see both sides' arguments. As much as I would love to see some really nice functionality like this baked-into redis, I think it might be more appropriate as a plugin/custom script. Certainly would like to hear what the leaders of redis think about this proposal.

Comment From: thearchitect

Sorry, English is not my native.

It's like MultiKeyMap data structure implemented in Java's Apache Commons Collections. In general if some entity have multiple unique attributes/characteristics we can find the entity by any attribute.

Yes, we can implement this with some script/plugin but I don't have enough C experience and performance won't be the best. I think implementing this in the core will be the best option for performance.

Comment From: apopov-cv

It is key feature we also want for our project. It is important that data must use memory only once. It is cool to have timeout for each key(don't sure it is needed) and for data(for all keys), opportunity remove(unbind) key or remove data(with all keys). Also we want to have opportunity store the same data in multiple structures(in the list and in the dict), when you remove data from one of the structures, it removes from all others.

Comment From: godblesshugh

vote for this. Actually it likes adding multiple indexes into one table at mysql. "One user has two unique ids: userId and email."

Comment From: erikdubbelboer

This can quite easily be implemented using simple Lua scripts for setting and getting.

Comment From: godblesshugh

what do you mean? Multiple keys for a same value using Lua?

Comment From: erikdubbelboer

You can keep the data inside one hash and then have one or more index hashes for the lookups. The index lookup hashes would only contain the key for the main hash as value. You'd write two simple Lua script. One that when adding the value to the main hash also adds all the keys to the index lookup hashes. And one that looks up the key inside one of the index lookup hashes and returns the value from the main hash.

Comment From: godblesshugh

... too dump without thinking about mapping and point. brilliant idea, thanks

Comment From: skanagavelu

@erikdubbelboer Could you please elaborate it? Are you saying like below?

redis> HSET USER_VALUES user1 "{"name":"velu", "email":"velu@mail.com", "age": "32", ....}" (integer) 1 redis> HSET USER_VALUES user2 "{"name":"kanagu", "email":"kanagu@mail.com", "age": "31", ....}" (integer) 1

redis> HSET USER_LOOKUP velu "user1" (integer) 1 redis> HSET USER_LOOKUP velu@mail.com "user1" (integer) 1

redis> HSET USER_LOOKUP kanagu "user2" (integer) 1 redis> HSET USER_LOOKUP kanagu@mail.com "user2" (integer) 1

redis> HGET USER_LOOKUP kanagu "user2" redis> HGET USER_VALUES "user2" "{"name":"kanagu", "email":"kanagu@mail.com", "age": "31", ....}"

OR

redis> SET user1 "{"name":"velu", "email":"velu@mail.com", "age": "32", ....}" OK redis> SET user2 "{"name":"kanagu", "email":"kanagu@mail.com", "age": "31", ....}" OK

redis> SET velu user1 OK redis> SET velu@mail.com user1 OK redis> SET kanagu user2 OK redis> SET kanagu@mail.com user2 OK

redis> GET kanagu "user2" redis> GET user2 "{"name":"kanagu", "email":"kanagu@mail.com", "age": "31", ....}"

But these are all will increase round trip times, and my only concern is that LUA is atomic when the client fails; but not atomic when the redis server went down in between the lua execution. We need more atomic commands like LPOPRPUSH similar to java's atomic package.

Comment From: mcraveiro

Hi,

I think it would be extremely useful to have something like the bind command proposed above, making it really easy to use. Whilst it may be possible to achieve something similar with scripting, it's not as easy to those unfamiliar, resulting in many hacks and workarounds.

Cheers

Marco

Comment From: udik-chudik

Please, provide this feature! We need it! I will be extremely useful!

Comment From: sasha-x

+1

Comment From: farooqkhan003

+1 It will surely be a great feature. It is quite common scenario. Other cache solutions are also providing this support.

Comment From: gcustard

This would be a great feature to have.

Comment From: itsmunim

Will it ever be in consideration? 😢

Comment From: chuckmitchell

I too would love to have this considered

Comment From: realfrozenfire

+1

Comment From: joaoscotto

+1

Comment From: rajendarreddyj

+1

Comment From: rLitto

No interest in this?

Comment From: chienjchienj

+1

Comment From: br1

+1

Comment From: raschle

+1

Comment From: brianhhq

+1

Comment From: flyzed

+1

Comment From: tneilturner

+1

Comment From: vamdt

+1

Comment From: kikaragyozov

Please implement this Dapper, you'll be even greater for it. Other caching solutions are already providing this feature. I'm sure you guys have the technical know-how to implement it.

Comment From: MerouaneBali

+1

Comment From: Tcheutchoua-Steve

+1

Comment From: pareddy113

+1

Comment From: Rifmaz

+1

Comment From: ivanduka

People, please stop creating "+1" comments, adding "likes" to the original message (https://github.com/redis/redis/issues/2668#issue-94460815) is sufficient.

That being said, this feature seems to be desired by many people.

Can someone from the Redis team provide us with their high-level opinion on the issue? Can it possibly be considered? Is it technically viable? Will the performance hit be substantial?

Comment From: madolson

The main issue here is that redis has a share nothing architecture, so we don't really want key/values having references to other key/values. We could solve this by just keeping a reference to the key name of the reference, but without a hard link between multiple values it might dangle if you delete it.

I'm sure this is solvable, it just seems like it would add a bit of complexity. Perhaps we should invest some cycles to better understand the solution space given the number of people asking for it though. I like the idea generally. In a way it's kind of like a secondary index on the redis key space, which seems useful.

Edit: I apparently added it to our redis 7 backlog already, so I guess I looked at this earlier without commenting 😅.

Comment From: villesau

@madolson @oranagra what's the status of this? Looks like it was supposed to come with Redis 7 but was then removed from the backlog. This would be extremely handy and would open totally new ways to adapt Redis. If reference is not an option, maybe some way to ensure duplication?

Comment From: oranagra

i don't think it was seriously considered to be a part of 7.0, maybe just an early list of candidates to consider. we did consider two other things that can some some similar use cases: * https://github.com/redis/redis/issues/8372 would allow you to react to changes in the database and do other changes, so for instance if one key is deleted, delete the other one. not implemented * https://github.com/redis/redis/issues/8693 allows you to create high level interface for the application, which manages multiple keys under the surface. implemented

we don't currently have plans to support what's discussed in this issue in the near future.

Comment From: madolson

Yes, it was added to 7.0 since we were adding all potential projects there and cutting stuff that wasn't implemented. I've moved it to our right backlog just so it's being tracked.

FWIW, I don't think Key annotations is the right solution to solve this problem.

Comment From: huluobotx

+1

Comment From: madolson

@huluobotx Please add a thumb to the top level comment instead of +1. Hard to sort based on +1.

Comment From: sapirshamun

Hi, I am working with multiple keys pointing to a single value also worth mention one of them is geo key. I created LUA script to add all, does it mean the action is atomic now? I wonder if I should handle the case that some keys were added successfully and some not