doc: 阅读redis hash文档

This commit is contained in:
asahi
2025-09-08 11:05:49 +08:00
parent 8e4fca612a
commit 1c9b73cd5d

View File

@@ -65,6 +65,12 @@
- [SREM](#srem) - [SREM](#srem)
- [SPOP](#spop) - [SPOP](#spop)
- [SRANDMEMBER](#srandmember) - [SRANDMEMBER](#srandmember)
- [redis hashes](#redis-hashes)
- [对象表示](#对象表示)
- [counters](#counters)
- [Field Expiration](#field-expiration)
- [Common field expiration use cases](#common-field-expiration-use-cases)
- [Field Expiration examples](#field-expiration-examples)
# redis # redis
@@ -950,3 +956,120 @@ SDIFF命令在`difference between all sets is empty`时会返回一个empty a
"bike:2" "bike:2"
``` ```
### redis hashes
redis hashes为记录`field-value pair`集合的数据结构可以使用hashes来表示基本对象或存储counter的分组示例如下
#### 对象表示
```redis-cli
> HSET bike:1 model Deimos brand Ergonom type 'Enduro bikes' price 4972
(integer) 4
> HGET bike:1 model
"Deimos"
> HGET bike:1 price
"4972"
> HGETALL bike:1
1) "model"
2) "Deimos"
3) "brand"
4) "Ergonom"
5) "type"
6) "Enduro bikes"
7) "price"
8) "4972"
```
通常来讲可以存储在hash中的fields数量并没有限制。
命令`HSET`可用于向hash中设置多个fields而命令`HGET`可以用于获取一个field`HMGET`可以用于获取多个field。
```redis-cli
> HMGET bike:1 model price no-such-field
1) "Deimos"
2) "4972"
3) (nil)
```
同样的hash结构支持对单个field进行操作例如`HINCRBY`
```redis-cli
> HINCRBY bike:1 price 100
(integer) 5072
> HINCRBY bike:1 price -100
(integer) 4972
```
#### counters
将hash用于存储counters分组的示例如下所示
```redis-cli
> HINCRBY bike:1:stats rides 1
(integer) 1
> HINCRBY bike:1:stats rides 1
(integer) 2
> HINCRBY bike:1:stats rides 1
(integer) 3
> HINCRBY bike:1:stats crashes 1
(integer) 1
> HINCRBY bike:1:stats owners 1
(integer) 1
> HGET bike:1:stats rides
"3"
> HMGET bike:1:stats owners crashes
1) "1"
2) "1"
```
#### Field Expiration
在`redis open source 7.4`中支持为独立的hash field指定超时
- `HEXPIRE`: set the remaining TTL in seconds
- `HPEXPIRE`: set the remaining TTL in milliseconds
- `HEXPIREAT`: set expiration time to a timestamp specified in seconds
- `HPEXPIREAT`: set the expiration time to a timestamp specified in milliseconds
如上所示在指定超时时可以通过时间戳来指定也可以通过TTL来指定。
同时,获取超时事件也可以通过`时间戳`和`TTL`来获取:
- `HEXPIRETIME`: get the expiration time as timestamp in seconds
- `HPEXPIRETIME`: get the expiration time as timestamp in milliseconds
- `HTTL`: get the remaining ttl in seconds
- `HPTTL`: get the remaining ttl in milliseconds
如果想要移除指定hash field的expration可以通过如下方式
- `HPERSIST`: 移除hash field的超时
##### Common field expiration use cases
- `Event Tracking`使用hash key来存储`最后一小时的事件`。其中field为每个事件而设置事件field的ttl为1小时并可使用`HLEN`来统计最后一小时的事件数量。
- `Fraud Detection`通常用户行为进行分析时可按小时记录用户的事件数量。可通过hash结果记录过去48小时中每小时的操作数量其中hash field代表用户某一个小时内的操作数。每个hash field的过期时间都为48h。
- `Customer session management`: 可以通过hash来存储用户数据。为每个session创建一个hash key并且向hash key中添加session field。当session过期时自动对session key和session field进行expire操作。
- `Active Session Tracking`: 将所有的active sessions存储再一个hash key中。每当session变为inactive时将session的TTL设置为过期。可以使用`HLEN`来统计活跃的sessions数量。
##### Field Expiration examples
`对于hash field ixpiration的支持在官方client libraries中尚不可用`,但是可以在`python(redis-py)`和`java(jedis)`的beta版本client libraries中使用。
如下python示例展示了如何使用field expiration
```py
event = {
'air_quality': 256,
'battery_level':89
}
r.hset('sensor:sensor1', mapping=event)
# set the TTL for two hash fields to 60 seconds
r.hexpire('sensor:sensor1', 60, 'air_quality', 'battery_level')
ttl = r.httl('sensor:sensor1', 'air_quality', 'battery_level')
print(ttl)
# prints [60, 60]
# set the TTL of the 'air_quality' field in milliseconds
r.hpexpire('sensor:sensor1', 60000, 'air_quality')
# and retrieve it
pttl = r.hpttl('sensor:sensor1', 'air_quality')
print(pttl)
# prints [59994] # your actual value may vary
# set the expiration of 'air_quality' to now + 24 hours
# (similar to setting the TTL to 24 hours)
r.hexpireat('sensor:sensor1',
datetime.now() + timedelta(hours=24),
'air_quality')
# and retrieve it
expire_time = r.hexpiretime('sensor:sensor1', 'air_quality')
print(expire_time)
# prints [1717668041] # your actual value may vary
```