Redis键值类型<key value> 以及键的使用注意事项

Redis的常用键值对

Redis的键值对

Redis是以键值(Key-Value)为基础,支持不同类型值(value)的数据结构服务器。在传统键值存储中,一般将字符串键字符串值相关联,而在Redis中,该值不仅限于简单的字符串,还可以容纳列表、有序列表、哈希、二进制等数据结构。

redis的数据库存储结构如下:

typedef truct redisDb {
  dict *dict; // 数据库键空间,保存数据库中的所有键值对
  dict *expires; // 过期字典,保存着键的过期时间 键是键空间的键的指针,值是unix时间戳
}redisDb ;

dict数据包含了哈希表、哈希函数类型私有数据等数据,键值(Key-Value)就存储在hash表中
可以将这种数据结构想象成Java中的HashMap,在进行查找时,首先计算出键的hash值,通过hash找到存储数组的下标,然后通过匹配值找到对应的键值对元素。Redis通过链地址法解决哈希冲突。

有关redis底层数据结构的内容可以参考:
Redis基础知识 底层数据结构的实现




Redis-Key

Redis的键(Key)是二进制安全的字符串,在Redis的底层中由SDS实现。

二进制安全字符串:即支持任意类型的数据作为键。从“ foo”之类的字符串到JPEG文件的内容,都可以是有效的redis键,同时空字符串也包含在内。

一个SDS(simple dynamic string)的存储定义如下:

struct sdshdr {
  int len; // 记录buf数组中已使用的字节数量,等于SDS所保存字符串的长度
  
  int free; // 记录buf数组中未使用的字节数量
  
  char buf[]; // 字节数组,用于保存字符串
}

设置键的注意点

  • key使用的字节不宜过长:键太长时,不仅在内存方面是个负担,并且在redis服务器为了查找这个键,可能需要进行一些代价高昂的哈希值计算。

  • key也不宜设置太短:与“ user:1000:followers”对比,使用“ u1000flw”作为键毫无意义,前者往往更具可读性。且与键对象本身和值对象使用的空间相比,单单添加key消耗的空间更少。

  • key使用同一种设置类型:使用形如“ object-type:id”的格式,不仅在可读性方面更佳,也能有效的降低键重复时造成的值覆盖。例如“ user:1000”。点或破折号通常用于多字段的连接,例如“ comment🔢reply.to”或“ comment🔢reply-to”中。

  • 键允许的最大大小为512 MB




Redis-Value

Redis的值(Value)支持以下几种类型

  • Binary-safe strings:二进制安全字符串。

  • Lists:根据插入顺序排序的字符串元素的集合。它们基本上是链表

  • Sets:唯一,未排序的字符串元素的集合。

  • Sorted sets:类似于集合,但是每个字符串元素在存入时都将于一个浮点数值的分数相关联,元素总是按照它们的分数排序,因此与Sets不同,可以检索一系列元素

  • Hashes:键值组成的哈希映射,键值都是字符串。

  • Bit arrays (or simply bitmaps):可以使用特殊命令像位数组一样处理字符串值:可以设置和清除单个位,计数所有设置为1的位,找到第一个设置或未设置的位,等等。

  • HyperLogLogs:这是一个概率数据结构,用于估计集合的基数。

  • Streams:提供抽象日志数据类型的类地图项的仅追加集合。


redis值的内部实现结构如下

type类型encoding编码ptr指向的数据结构
REDIS_STRINGREDIS_ENCODING_INT整数值的实现的字符串对象
REDIS_STRINGREDIS_ENCODING_EMBSTRembstr编码的sds实现的字符串对象
REDIS_STRINGREDIS_ENCODING_RAWsds字符串实现的字符串对象
REDIS_LISTREDIS_ENCODING_ZIPLIST压缩列表实现
REDIS_LISTREDIS_ENCODING_LINKEDLIST链表实现
REDIS_HASHREDIS_ENCODING_ZIPLIST压缩表实现
REDIS_HASHREDIS_ENCODING_HT字典实现
REDIS_SETREDIS_ENCODING_INTSET整数集合实现
REDIS_SETREDIS_ENCODING_HT字典实现
REDIS_ZSETREDIS_ENCODING_ZIPLIST压缩表实现
REDIS_ZSETREDIS_ENCODING_SKIPLIST跳跃表和字典实现




Redis值的常用数据类型

  1. 字符串:String

Redis字符串类型是与Redis键关联的最简单的值类型。它也是Memcached中唯一的数据类型。

值是二进制安全的字符串,意味着redis的string可以包含任何数据。比如jpg图片或者序列化的对象。与键相同,值最大能存储512 MB的数据。


  1. 列表:List

redis是由双向链表(Linked List)的方式实现,而非数组形式。它能从链表的头尾进行操作。它是根据插入的顺序进行排序的有序列表。

列表的常用案例:记住用户发布到社交网络上的最近更新。频繁查看的日志。


  1. 集合:Set

set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

可以理解为一堆值不重复的列表,类似数学领域中的集合概念,且Redis也提供了针对集合的求交集、并集、差集等操作。


  1. 有序集合:Sorted Set

Redis有序集合类似Redis集合,不同的是增加排序的功能。一个有序集合的每个成员带有分数属性,排序时根据分数来拍续。

Redis有序集合添加、删除和测试的时间复杂度均为O(1)(固定时间,无论里面包含的元素集合的数量)。列表的最大长度为2^32- 1(4294967295)。

Redis有序集合的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。


  1. 哈希表:Hash

对应值内部实际就是一个HashMap,这里与redis数据库字典下的哈希表使用的是同一种数据类型。

实际上,哈希表根据数据量大小会有2种不同实现方式:

  • 当成员比较少时,Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应值的encoding为REDIS_ENCODING_ZIPLIST
  • 当成员数量增大时,会自动转成真正的HashMap,此时encoding为REDIS_ENCODING_HT。

每个 hash 可以存储 2^32 -1 键值对。




参考:

Redis Documentation

Redis维基百科

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值