Redis数据结构之哈希详解
简介
Redis本身是键值对数据库,但是值对应多种数据结构,其中就有哈希(即键值对),值中的键值对称为field和value。
基本命令
命令 | 命令描述 |
---|---|
hset key field value |
设置哈希,和字符串类似,也提供了hsetnx 命令,不过是nx是针对field |
hget key field |
获取值 |
hdel key field [field...] |
删除field,返回成功删除的个数 |
hlen key |
计算field的个数 |
hmget key field [field...] ,hmset key field value [field value....]
|
批量设置或获取field-value |
hexists key field |
判断field是否存在 |
hkeys key |
获取所有field |
hvals key |
获取所有value |
hgetall key |
获得所有field-value,如果field-value数量比较多,会存在阻塞Redis的可能,一般用hmget和hscan |
hincrby key field , hincrbyfloat key field
|
自增field操作,hincrbyfloat适用于整数和浮点数,而hincrby只适用于整数 |
hstrlen key field |
计算value的字符串长度 |
内部编码
哈希类型内部编码有两种:
ziplist(压缩列表):当哈希类型元素的个数小于hash-max-ziplist-entries配置,默认是512,同时所有值都小于hash-max-ziplist-value配置时,默认是64字节,Redis会使用ziplist作为哈希类型的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。
hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)
使用场景
- 关系型数据库表记录可以用Redis的哈希类型进行存储,一条记录作为一个key-value,而每列属性对应值可以作为field-value存储在key-value中,也即采用哈希类型存储一条记录,一张表可以根据主键区分,用多个哈希类型的key-value进行存储。
- 哈希类型是稀疏的,而关系型数据库是完全结构化的,非关系型数据库和关系型数据库,关系型数据库插入一个新属性列,则所有记录都要插入并设置值,而非关系型数据库里的每条记录的属性列可以不相同,没有结构关系
- 关系型数据库可以做复杂的关系查询,而Redis去模拟关系型复杂查询开发困难,维护成本高。
合适的场景使用合适的技术,对象缓存功能有三种实现方法:
- 每个属性一个key
优点:简单直观,每个属性都支持更新操作
缺点:占用过多的key,内存占用量大,同时对象的属性内聚性比较差,一般不会在生成环境中使用 - 序列化字符串类型:将对象信息序列化成一个字符串,然后用一个key保存
优点:简化编程,合理使用序列化技术可以提高内存使用率
缺点:序列化和反序列化有一定的开销,同时每次更新一个属性都要把全部数据取出进行反序列化,更新完再序列化到Redis中 - 哈希类型:每个对象一个key,每个属性一个field-value
优点:简单直观,使用合理可以减少内存空间
缺点:要控制哈希在ziplist和hashtable两种内部编码之间的转换,hashtable会消耗更多内存。