redis hash
1. 哈希(hash)
哈希类型是指 redis 键值对中的值本身又是一个键值对结构,形如 value=[{field1,value1},...{fieldN,valueN}],其与 redis 字符串对象的区别
2. 内部实现
哈希类型的内部编码有两种:ziplist (压缩列表), hashtable (哈希表)。只有当存储的数据量比较小的情况下,redis 才使用压缩列表来实现字典类型。具体需要满足两个条件:
-
当哈希类型元素个数小于 hash-max-ziplist-entries 配置(默认512个)
-
所有值都小于 hash-max-ziplist-value 配置(默认64字节)
ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比 hashtable 更加优秀。当哈希类型无法满足 ziplist 的条件时,redis 会使用 hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,而 hashtable 的读写时间复杂度为O(1)。
2. 常用命令
命令 | 描述 |
---|---|
hdel key field1 [field2] | 删除一个或多个字段 |
hexists key field | 查看字段是否存在 |
hget key field | 获取指定字段 |
hgetall key | 获取所有字段 |
hincrby key field increment | 字段值加上指定增量值 |
hincrbyfloat key field increment | 浮点值加上指定增量值 |
hkeys key | 获取所有哈希表中的字段 |
hlen key | 获取哈希表中字段的数量 |
hmget key field1 [field2] | 获取所有给定字段的值 |
hmset key field1 value1 [field2 value2 ] | 同时将多个 field-value (域-值)对设置到哈希表 key 中 |
hset key field value | 将哈希表 key 中的字段 field 的值设为 value |
hsetnx key field value | 设置hash的一个字段,只有当这个字段不存在时有效 |
hvals key | 获取hash中所有值 |
hscan key cursor [MATCH pattern] [COUNT count] | 迭代hash中的元素 |
3. 使用场景
-
存储对象
如存储一些对象信息,如用户信息、商品信息、配置信息等
如用户信息它在关系型数据库中的结构是这样的
id 1 name age 1 tom 15 2 jerry 13 而使用 redis Hash 存储其结构如下图:
-
购物车
很多电商网站都会使用 cookie实现购物车,优点就是:无须对数据库进行写入,而缺点是:程序需要重新解析和验证 cookie,数据多了之后请求发送和处理的速度可能会有所降低。
购物车的定义非常简单:我们以每个用户的用户 id 作为 redis 的 key,每个用户的购物车都是一个哈希表,这个哈希表存储了商品 id 与商品订购数量之间的映射。在商品的订购数量出现变化时,操作 redis 哈希对购物车进行更新
-
计数器
redis 哈希表作为计数器的使用也非常广泛。它常常被用在记录网站每一天、一月、一年的访问数量。每一次访问,我们在对应的 field 上自增1
4. 遇到问题
-
在用 redis 存储已经排序好的数据,获取时会出现无序
可以使用函数进行排序处理
// 二维数组按照 score 和 time 进行排序
array_multisort(array_column($array, 'score'), SORT_DESC, array_column($array, 'time'), SORT_DESC, $array);