简体   繁体   中英

Redis embedding value in the key vs json

I'm planning to store rooms availability in a redis database. The json object looks as such:

{
  BuildingID: "RE0002439",
  RoomID: "UN0002384391290",
  SentTime: 1572616800,
  ReceivedTime: 1572616801,
  Status: "Occupied",
  EstimatedAvailableFrom: 1572620400000,
  Capacity: 20,
  Layout: "classroom"
}

This is going to be reported by both devices and apps (tablet outside the room, sensor within the room in some rooms, by users etc.) and vary largely as we have hundreds of buildings and over 1000 rooms.

My intention is to use a simple key value structure in Redis. The main query would be which room is available now, but other queries are possible.

Because of that I was thinking that the key should look like

RoomID,Status,Capacity

My question is is it correct assumption because this is the main query we expect to have these all in the key? Should there be other fields in the key too or should the key be just a number with Redis increment, as if it was SQL?

There are plenty of questions I could find about hierarchy but my object has no hierarchy really.

Unless you will use the redis instance exclusively for this, using keys with pattern matching for common queries is not a good idea. KEYS is O(N) and SCAN too when called multiple times to traverse the whole keyspace.

Consider RediSearch module , it would give you a lot of power on this use case.

If RediSearch is not an option:

You can use a single hash key to store all rooms, but then you have to store the whole json string as value, and whenever you want to modify a field, you need to get, then modify then set.

You are probably better off using multiple data structures, here an idea to get you started:

Store each room as a hash key. If RoomID is unique you can use it as key, or pair it with building id if needed. This way, you can edit a field value in one operation.

HSET UN0002384391290 BuildingID RE0002439 Capacity 20 ...

Keep a set with all room IDs. SADD AllRooms UN0002384391290

Use sets and sorted sets as indexes for the rest:

A set of available rooms : Use SADD AvailableRooms UN0002384391290 and SREM AvailableRooms UN0002384391290 to mark rooms as available or not. This way your common query of all rooms available is as fast as it gets. You can use this in place of Status inside the room data. Use SISMEMBER to test is a given room is available now.

A sorted set with capacity : Use ZADD RoomsByCapacity 20 UN0002384391290 . So now you can start doing nice queries like ZRANGEBYSCORE RoomsByCapacity 15 +inf WITHSCORES to get all rooms with a capacity >=15. You then can intersect with available rooms.

Sets by layout : SADD RoomsByLayout:classroom UN0002384391290 . Then you can intersect by layout, like SINTER AvailableRooms RoomsByLayout:classroom to get all available classrooms.

Sets by building : SADD RoomsByBuilding:RE0002439 UN0002384391290 . Then you can intersect by buildings too, like SINTER AvailableRooms RoomsByLayout:classroom RoomsByBuilding:RE0002439 to get all available classrooms in a building.

You can mix sets with sorted sets, like ZINTERSTORE Available:RE0002439:ByCap 3 RoomsByBuilding:RE0002439 RoomsByCapacity AvailableRooms AGGREGATE MAX to get all available rooms scored by capacity in building RE0002439. Sorted sets only allow ZINTERSTORE and ZUNIONSTORE , so you need to clean up after your queries.

You can avoid sorted sets by using sets with capacity buckets, like Rooms:Capacity:1-5 , Rooms:Capacity:6-10 , etc.

Consider adding coordinates to your buildings, so your users can query by proximity. See GEOADD and GEORADIUS .

You may want to allow reservations and availability queries into the future. See Date range overlap on Redis? .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM