暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis的六种基本数据结构

lebronchen 2018-08-30
556

一、String

value是字符串类型。

1.常用命令

  • set key value:设置key、value

  • setex key seconds value:设置key、value,有效期seconds秒

  • setnx key value:设置key、value,如果key存在则setnx失败,返回 0 (set key value nx等价)

  • set key value xx:设置key、value,如果key不存在失败,返回 0

  • get key:获取key的值

  • getset key value:设置key、value,并返回value

  • mset key value key value:批量设置key、value

  • mget key key:批量获取key的值

  • incr key:key对应的value自增,如果key对应value不是整数返回错误,如果key不存在,将value设置为 1

  • decr key:key对应的value自减

  • incrby key increment:key对应的value增加increment

  • decrby key increment:key对应的value减少increment

  • incrbyfloat key increment:key对应的浮点数value增加increment(只有incrbyfloat命令,没有decrbyfloat命令,可以用incrbyfloat一个负数实现decrbyfloat命令)

2.内部编码

字符串类型的内部编码有三种(可以使用 object encoding key来查看key对应value的编码格式):

  • int:8 个字节的长整型

  • embstr:小于等于 39 个字节的字符串

  • raw:大于 39 个字节的字符串

3、使用场景

  • setnx命令可用于分布式锁的一种实现方案,保证只有一个客户端能请求成功。

  • mget、mset命令可以在多条命令时减少网络层传输时间。

  • incr命令可用于计数。

二、Hash

value是Hash类型,即value={{field1,value1},{field2,value2}}的格式

1、常用命令

  • hset key field value:为key设置一对 field-value

  • hget key field:查询key中field对应的value

  • hdel key field:删除key中的field属性

  • hlen key:计算key中field个数

  • hmset key field value field value:批量设置key的field-value

  • hmget key field field:批量查询key的不同field

  • hexists key field:判断key是否存在field属性

  • hkeys key:查询key的所有field属性

  • hvals key:查询key对应所有field的value

  • hgetall key:查询key的所有field和value,按序输出

  • hincryby key field increment:对key的field的value增加increment

  • hincrybyfloat key field increment:对key的field的浮点数value增加increment

2、内部编码

Hash类型的内部编码有两种:

  • ziplist(压缩列表)

  • hashtable(哈希表)

ziplist使用更加紧凑的结构实现多个元素的连续存储,在内存方便比hashtable优秀;hashtable的读写时间复杂度是O(1),在读写效率方面会比ziplist高。

在Redis中的两个配置:

  • hash-max-ziplist-entries:默认512

  • hash-max-ziplist-value:默认值64

Hash类型只有满足下面两个条件才会使用ziplist结构:

  • field数量小于hash-max-ziplist-entries

  • 所有value占用字节数都小于hash-max-ziplist-value

这样做能够保证在field少并且value不大的情况下使用ziplist编码方式可以节约内存,而field过多或者value过大的情况下使用hashtable编码方式可以保证读写效率不会降低。

三、list

list类型用来存储有序的字符串,一个列表最多存储 2 ^ 32 -1 个元素

1、常用命令

  • rpush key value [value …]]:从右边插入元素

  • lpush key value [value …]:从左边插入元素

  • linsert key before|after pivot value:从左到右从列表中找到等于pivot的元素,在其前|后插入value元素,如果pivot不存在则返回 -1

  • lrange key start end:从左到右查询list中下标从start到end的元素(包括end),索引下标从左到右是0到N,从右到左是-1到-N,lrange key 0 -1 表示查询所有元素

  • lindex key index:获取指定下标的元素

  • llen key:获取list的长度

  • lpop key:从list左边弹出元素

  • rpop key:从list右边弹出元素

  • lrem key count value:从列表中删除指定数量的等于value的元素

    • count < 0:从右到左,删除最多count绝对值个元素

    • count = 0:删除所有

    • count > 0:从左到右,删除最多count个元素

  • lset key index newValue:修改list中指定下标的元素

  • blpop key [key …] timeout:阻塞式的从左边弹出多个key中的元素

  • brpop key [key …] timeout:阻塞式的从右边弹出多个key中的元素

上面常用命令中的blpop和brpop命令不好理解,这里再详细说一下这两个命令。

其中blpop和brpop除了弹出方向不一样以外,其他情况都一样,所以就以blpop命令进行说明。

timeout表示阻塞时间,如果blpop命令没有取到元素,那么命令会阻塞,等到timeout时间之后会释放,如果阻塞期间取到元素,直接返回元素,timeout = 0表示如果取不到元素,一直阻塞下去。

key [key …]表示多个list的key,使用blpop命令的时候会去从左到右的遍历所有的list,一旦有一个list的lpop命令取到元素则直接返回,如果所有list都取不到元素,则阻塞。

如果多个客户端对同一个key执行blpop操作,那么最先执行blpop命令的客户端可以先取到元素。

有一点需要注意的是brpop命令只是会从list的右边弹出元素,对于多个list,还是会从左到右遍历这些list的。

2、内部编码

List类型的内部编码有两种:

  • ziplist(压缩列表)

  • linkedlist(链表)

ziplist使用更加紧凑的结构实现多个元素的连续存储,在内存方便比linkedlist优秀;linkedlist在读写效率方面会比ziplist高。

在Redis中的两个配置:

  • list-max-ziplist-entries:默认512

  • list-max-ziplist-value:默认值64

List类型只有满足下面两个条件才会使用ziplist结构:

  • 元素数量小于list-max-ziplist-entries

  • 所有元素占用字节数都小于list-max-ziplist-value

这样做能够保证在元素少并且元素不大的情况下使用ziplist编码方式可以节约内存,而元素过多或者元素过大的情况下使用linkedlist编码方式可以保证读写效率不会降低。

Redis 3.2版本提供了quicklist的内部编码方式,它是以ziplist为节点的linkedlist,结合了两者的优势,实现方式更加优秀。

3、使用场景

  • 消息队列:使用lpush和brpop命令组合可以实现阻塞队列

  • 队列:lpush + rpop

  • 栈:lpush + lpop

四、Set

Set用来存储多个字符串元素,和List的区别在于元素不重复

1、常用命令

  • sadd key elememt [element …]:添加元素

  • srem ket elememt [element …]:移除元素

  • scard key:计算元素个数,时间复杂度O(1),不会遍历集合所有元素,直接使用Redis内部变量

  • sismember key element:判断元素是否在Set中

  • srandmember key [count]:从Set中随机返回count个元素,不指定count默认返回一个元素

  • spop key:从Set中随机弹出一个元素

  • smembers key:获取所有元素

  • sinter key [key …]:求多个Set的交集

  • sunion key [key …]:求多个Set的交集

  • sdiff key [key …]:求多个Set的差集,多个key依次取差集

  • sinterstore destination key [key …]:将多个Set的交集保存到destination上

  • sunionstore destination key [key …]:将多个Set的并集保存到destination上

  • - sdiffstore destination key [key …]:将多个Set的差集保存到destination上

2、内部编码

Set类型的内部编码有两种:

  • intset(整数集合)

  • hashtable(哈希表)

intset使用更加紧凑的结构实现多个元素的连续存储,在内存方便比hashtable优秀;hashtable在读写效率方面会比intset高。

在Redis中的一个配置:

  • set-max-intset-entries:默认512

List类型只有满足下面两个条件才会使用intset结构:

  • 元素数量小于set-max-intset-entries

  • 元素都是整数

这样做能够保证在元素少并且都是整数的情况下使用intset编码方式可以节约内存,而元素过多或者不是整数的情况下使用hashtable编码方式可以保证读写效率不会降低。

3、使用场景

Set类型提供了集合的交并差集运算,比较适合的场景是标签(tag)。

例如给用户添加标签就可以通过交集查出用户的共同标签;

给标签添加用户就可以通过交集查出有共同标签的用户。

五、有序集合

Zset有序集合和Set一样不能有重复的元素,并且可以对元素进行排序。

这里说的排序不是按照索引进行排序,而是会给每个元素设置一个分数(score),根据score来排序。

1、常用命令

  • zadd key score member [score member …]:添加成员

  • zcard key:计算成员数量

  • zscore key member:计算某个成员的分数

  • zrank key member:计算成员的排名,从低到高计算

  • zrevrank key member:计算成员的排名,从高到低计算

  • zrem key member [member …]:删除成员

  • zincrby key increment member:增加成员的分数

  • zrange key start end [withscores]:从低到高排序取指定元素,如果带上withscores则同时返回score

  • zrevrange key start end [withscores]:从高到低排序取指定元素,如果带上withscores则同时返回score

  • zrangebyscore key min max [withscores]:从低到高排序显示分值在min到max之间的成员(包括min和max)

  • zrevrangebyscore key min max [withscores]:从高到低排序显示分值在min到max之间的成员(包括min和max)

  • zcount key min max:统计分值在min到max之间的成员(包括min和max)个数

  • zremrangebyrank key start end:从低到高排序,删除排名在start到end之间的元素(包括start和end)

  • zremrangebyscore key min max:删除分值在min到max之间的成员(包括min和max)

  • zinterstore destination numkeys key [key …] [weights weight [weight …]] [aggregate sum|min|max]:计算交集

    • destination:计算结果保存到这个key

    • numkeys:参与交集运算key的数量

    • key [key …]:参与交集运算的key

    • weights weight [weight …]:每隔键的权重

    • aggregate sum|min|max:计算成员交集后,分值可以按照sum、min、max做汇总,默认sum

  • zunionstore destination numkeys key [key …] [weights weight [weight …]] [aggregate sum|min|max]:计算并集,所有参数含义和zinterstore命令一致

2、内部编码

ZSet类型的内部编码有两种:

  • ziplist(压缩列表)

  • skiplist(跳跃列表)

ziplist使用更加紧凑的结构实现多个元素的连续存储,在内存方便比skiplist优秀;skiplist在读写效率方面会比ziplist高。

在Redis中的两个个配置:

  • zset-max-ziplist-entries:默认128

  • zst-max-ziplist-value:默认64

Zset类型只有满足下面两个条件才会使用ziplist结构:

  • 元素数量小于zset-max-ziplist-entries

  • 每个元素的值都小于zst-max-ziplist-value

这样做能够保证在元素少并且元素不大的情况下使用ziplist编码方式可以节约内存,而元素过多或者元素很大的情况下使用skiplist编码方式可以保证读写效率不会降低。

3、使用场景

Zset提供根据score进行排序,很适合做排行榜。

六、GEO

redis目前已经到了3.2版本,3.2版本里面新增的一个功能就是对GEO(地理位置)的支持。

1、常用命令

  • geoadd key longitude latitude member [longitude latitude member …]:将指定的地理空间位置(纬度、经度、名称)添加到指定的key中

  • geodist key member1 member2 [unit]:返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。指定单位的参数 unit 必须是以下单位的其中一个:

    • m 表示单位为米

    • km 表示单位为千米

    • mi 表示单位为英里

    • ft 表示单位为英尺

  • geopos key member [member …]:从key里返回所有给定位置元素的位置(经度和纬度)

  • geohash key member [member …]:返回一个或多个位置元素的 Geohash 表示

  • georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]:以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素

  • georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]:这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的

2、使用场景

很显然GEO适用于位置查询。



扫码关注,不迷路


文章转载自lebronchen,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论