1. 哈希(Hash)类型
Redis 哈希(Hash)类型是字符串key和字符串value之间的映射,所以它十分适合用来表示一个对象信息。如:我们可以将一个用户对象存储为一个哈希类型,将用户的用户名、年龄、性别等属性各表示为一个key-value对。
哈希在某些应用场景中是一个非常有用存储方式,你可以将数以百万计的对象存储在一个很小的 Redis实例中。一个Redis 哈希值可存储232-1(40亿)个key-value对。
2. 哈希类型中的命令及使用
2.1 设置与取值
对哈希类型的操作,就是对一个哈希表的操作。对哈希表的设置及取值,就是对哈希表中字段的设置与取值。
2.1.1 HSET - 设置值
HSET key field value
设置哈希表key的field字段值为value。如果key不存在,一个新的哈希表会被创建并进行HSET操作。如果field字段已经存在,旧值将被覆盖。
使用HSET命令,每次只能设置一个属性(字段)值,如果需要同时设置多个,可以使用HMSET命令。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:
如果
field是哈希表中的一个新字段,并且值设置成功,返回1。如果field已存在,且旧值已被新值覆盖,则返回0。
使用示例
redis> hset abc f1 v1 (integer) 1 redis> hget abc f1 "v1" redis> hset abc f1 v2 (integer) 0 redis> hget abc f1 "v2"
2.1.2 HSETEX - 字段不存则设置其值
HSETNX key field value
与HSET命令一样,HSETEX同样会设置哈希表key的field字段值为value。但仅当field不存在才会设置。如果field字段已经存在,该操作无效。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:设置成功,返回
1。如果field已存在,则无操作且返回0。
使用示例
redis> HSETNX nosql key-value-store redis (integer) 1 # key-value-store 字段已存在,无操作 redis> HSETNX nosql key-value-store redis (integer) 0
2.1.3 HGET - 获取指定字段值
HGET key field
返回哈希表key中field字段的值。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:
key存在且field存在则返回其值。否则返回nil。
使用示例
# 域存在 redis> HSET site itbilu niefengjun.cn (integer) 1 redis> HGET site itbilu "niefengjun.cn" # 域不存在 redis> HGET site hehe (nil)
2.1.4 HGETALL - 获取所有字段及值
HGETALL key
返回哈希表key中所有的field和其值。
复杂度、返回值:
- 时间复杂度:
O(N),N为哈希表的大小 - 返回值:以列表形式返回哈希表中的字段和值。若哈希表不存在,否则返回一个空列表。
使用示例
redis> HSET people jack "Jack Sparrow" (integer) 1 redis> HSET people gump "Forrest Gump" (integer) 1 redis> HGETALL people 1) "jack" # 字段 2) "Jack Sparrow" # 值 3) "gump" 4) "Forrest Gump"
2.2 批量操作
2.2.1 HMSET - 设置多个字段及值
HMSET key field value [field value ...]
将一个或多个field-value对设置到哈希表key。如果要设置的field已存在,则会覆盖其值。如果哈希表不存在,首先会创建再执行HMSET操作。
复杂度、返回值:
- 时间复杂度:
O(N),N为field-value对的数量 - 返回值:执行成功,返回
OK。如果key不是哈希类型,则返回一个错误。
使用示例
redis> HMSET website google www.google.com yahoo www.yahoo.com OK redis> HGET website google "www.google.com" redis> HGET website yahoo "www.yahoo.com"
2.2.2 HMGET - 返回多个字段值
HMGET key field [field ...]
返回哈希表key中,一个或多个指定的定段。如果指定的字段在哈希表中不存在,则返回一个nil。如果
复杂度、返回值:
- 时间复杂度:
O(N),N为指定字段的数量 - 返回值:指定字段所关联值的列表。如果指定的
key为哈段结构,则返回一个错误。
使用示例
# 一次设置多个字段 redis> HMSET pet dog "doudou" cat "nounou" OK # 返回值多个字段值,返回顺序和传入参数的顺序一样 redis> HMGET pet dog cat fake_pet 1) "doudou" 2) "nounou" 3) (nil) # 不存在的字段返回nil值 # 非哈希结构 redis> set strKey "Hello World" OK redis> hmget strKey f1 (error) WRONGTYPE Operation against a key holding the wrong kind of value
2.3 字段/值操作
哈希类型支持单独字段或值,我们可以将不需要的字段删除、判断字段是否存在等;也可以不指定字段,而只获取所有字段的值。
2.3.1 HDEL - 字段删除
HDEL key field [field ...]
返回哈希表key中一个或多个指定字段,不存在的字段将被忽略。
复杂度、返回值:
- 时间复杂度:
O(N),N为要删除的字段数量 - 返回值:被成功删除的字段数。
使用示例
# 测试数据 redis> HGETALL abbr 1) "a" 2) "apple" 3) "b" 4) "banana" 5) "c" 6) "cat" 7) "d" 8) "dog" # 删除单个字段 redis> HDEL abbr a (integer) 1 # 删除不存在的字段 redis> HDEL abbr not-exists-field (integer) 0 # 删除多个字段 redis> HDEL abbr b c (integer) 2 redis> HGETALL abbr 1) "d" 2) "dog"
2.3.2 HEXISTS - 判断字段是否存在
HEXISTS key field
判断哈希表key中字段field是否存在。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:哈希表及指定字段存在,返回
1。哈希表或指定字段不存在,返回0。
使用示例
redis> HEXISTS phone myphone (integer) 0 redis> HSET phone myphone nokia-1110 (integer) 1 redis> HEXISTS phone myphone (integer) 1
2.3.3 HKEYS - 返回所有字段
HKEYS key
返回哈希表key中所有的字段。
复杂度、返回值:
- 时间复杂度:
O(N),N为哈希表的大小 - 返回值:哈希表存在,返回字段列表。哈希表不存在,返回空列表。
使用示例
# 哈希表非空 redis> HMSET website google www.google.com yahoo www.yahoo.com OK redis> HKEYS website 1) "google" 2) "yahoo" # 空哈希表不存在 redis> EXISTS fake_key (integer) 0 redis> HKEYS fake_key (empty list or set)
2.3.4 HLEN - 返回字段数量
HLEN key
返回哈希表key中字段的数量。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:哈希表存在,返回字段数。哈希表不存在,返回
0。
使用示例
redis> HSET db redis redis.com (integer) 1 redis> HSET db mysql mysql.com (integer) 1 redis> HLEN db (integer) 2 redis> HSET db mongodb mongodb.org (integer) 1 redis> HLEN db (integer) 3
2.3.5 HVALS - 返回所有字段值
HVALS key
返回哈希表key中所有字段的值。
复杂度、返回值:
- 时间复杂度:
O(N),N为哈希表的大小 - 返回值:哈希表存在,返回字段值的列表。哈希表不存在,返回空列表。
使用示例
# 非空哈希表 redis> HMSET website google www.google.com yahoo www.yahoo.com OK redis> HVALS website 1) "www.google.com" 2) "www.yahoo.com" # 空哈希表/不存在的key redis> EXISTS not_exists (integer) 0 redis> HVALS not_exists (empty list or set)
2.4 自增
如果字段中存储的是数字值,我们可以对其进行加/减法操作。
2.4.1 HINCRBY - 为指定字段值增加
HINCRBY key field increment
为哈希表key中的指定字段field增加一个增量increment。增量也可以为负数,相当于对为指定字段进行减法操作。
如果哈希表不存在,则会创建一个哈希表,再执行HINCRBY操作。如果指定字段field不存在,那么会首先初始化为0,再执行HINCRBY。
如果为非数字值执行HINCRBY操作,则返回一个错误。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:执行
HINCRBY操作后,哈希表key中字段field的值。
使用示例
# increment 为正数 # 对空域进行设置 redis> HEXISTS counter page_view (integer) 0 redis> HINCRBY counter page_view 200 (integer) 200 redis> HGET counter page_view "200" # increment 为负数 redis> HGET counter page_view "200" redis> HINCRBY counter page_view -50 (integer) 150 redis> HGET counter page_view "150" # 尝试对字符串值的字段执行HINCRBY命令 redis> HSET myhash string hello,world (integer) redis> HGET myhash string "hello,world" redis> HINCRBY myhash string 1 (error) ERR hash value is not an integer redis> HGET myhash string "hello,world" # 原值不变
2.4.2 HINCRBYFLOAT - 为指定字段值增加浮点数
HINCRBYFLOAT key field increment
为哈希表key中的指定字段field增加一个浮点数增量increment。增量也可以为负数,相当于对为指定字段进行减法操作。
如果哈希表不存在,则会创建一个哈希表,再执行HINCRBYFLOAT操作。如果指定字段field不存在,那么会首先初始化为0,再执行HINCRBYFLOAT。
如果为非数字值执行HINCRBYFLOAT操作,则返回一个错误。
复杂度、返回值:
- 时间复杂度:
O(1) - 返回值:执行
HINCRBYFLOAT操作后,哈希表key中字段field的值。
使用示例
# 值和增量都是普通小数 redis> HSET mykey field 10.50 (integer) 1 redis> HINCRBYFLOAT mykey field 0.1 "10.6" # 值和增量都是指数符号 redis> HSET mykey field 5.0e3 (integer) 0 redis> HINCRBYFLOAT mykey field 2.0e2 "5200" # 对不存在的键执行 HINCRBYFLOAT redis> EXISTS price (integer) 0 redis> HINCRBYFLOAT price milk 3.5 "3.5" redis> HGETALL price 1) "milk" 2) "3.5" # 对不存在的字段进行 HINCRBYFLOAT redis> HGETALL price 1) "milk" 2) "3.5" redis> HINCRBYFLOAT price coffee 4.5 "4.5" redis> HGETALL price 1) "milk" 2) "3.5" 3) "coffee" 4) "4.5"
