redis数据结构及应用场景

1、数据库种类

  关系型数据库:常见的Mysql,Oracle,PostgreSql

  k-v数据库:常见的Redis,C

  列式数据库:Hbase,Cassandra

  文档型数据库:MongoDB,CouchDB

  图形数据库:Neo4j,GraphSql

  newSql:   Oceanbase,TIDB

  

redis是由C语言编写,作为k-v型数据库,基于内存操作,也可以持久化,有着非常高的处理性能。

redis命令参考网站:http://doc.redisfans.com/

 redis版本6.0

2、redis数据类型

1》String(字符串)

2》Hash(哈希表

3》List(有序且可重复集合)

4》Set(无序且补课重复集合)

5》zSet(有序且补课重复集合)

6》HyperLogLog(基数)

7》Streams(流信息)

8》Geospatial(地理位置计算)

9》Bit Arrays(位集合)

 

3、String类型

常用命令:

set key value [ex seconds] ...   对key设置value值

get key 获取指定key的value值

del key [key ...] 删除指定key

mset key value [key value ...] 批量设置值

mget key [key ...] 批量获取值

incr key               对指定的key对应的value值进行原子递增(value必须是int类型,可以做分布式id)
decr key               对指定的key对应的value值进行原子递减

setex key value(second)      设置指定key的过期时间,单位为秒

setnx                 将key的值设置为value,如果key存在,返回0不做任何处理,否则返回(可以做分布式锁)
getset                 将指定key的值设置为value,并返回key修改之前的值

 

在C语言中没有String的类型,它在c语言中的数据结构存储:是使用SDS动态类型的一个储存,根据字符串的长度,来选择不同的SDS结构:

比如:set  name  'hello'  选择的是sdshd8的一个结构存储:

 

String类型作为最常用的一种,主要应用场景有:

  1、应用缓存,例如把字典数据,常用的城市数据,存储在redis中

  2、分布式id,可以利用incr命令,实现原子递增操作

    

  3、分布式session,让多个应用把seeeion存储在redis中,这样可以避免像session复制这样性能损耗的操作

  4、限流或计算器等,例如验证码的获取次数,密码的错误次数等。

  ........

key命名规范:

  1、不要太长,占用内存和宽带,例如当一个值有1024byte,这时候建议采用hash值,例如使用SHA1

  2、不要太短,没有意义的缩写,例如:user:1000:followers缩写成u1000flw,见名知意。

    建议格式:object-type:id,中间用::分割,例如:user:1000,comment:1234:reply-to

    3、最大的key值为512M

 

4、hash

 常用命令:

HSET key field value        将Hash表key中field字段的值设置为value,如果key不存在,则创建一个新的hash表,否则夏盖field的值
              
HGET key field           返回Hash表key中指定field字段的值

HDEL key field [field ...]     删除Hash表Key中一个或者多个field,如果不存在,则直接忽略

HEXISTS key field              查看Hash表key中,指定field是否存在,存在返回1,否则返回0

HGETALL key                    返回Hash表key中所有的fheld和value

HKEYS key             返回Hash表key中所有的field

HLEN key              返回Hash表key中field的数量

HVALS key              返回Hash表key中所有的field的value

HMGET key field [feld ..]    返回Hash表Key中,-个或多个指定field的值

HMSET key feld value [feld value ..]    同时将多个field-value设置到Hash表指定的key中,如果存在field,则爱盖。如果key不存在,则创建一个新的Hash表

hash结构更适合存储对象数据,例如:存储用户信息

  

 

 

当然也可以用String类型来存储,但如果我们需要修改address字段的值,首先需要转为对象,再去设置值,再转为json数据

用hash的话,就可以直接去设置address的值 :hset user:1001 address hunan

还可以使用hincrby命令实现数字的递增效果,例如年龄加10:hincrby user:1001 age 10

 

数据结构:hash有两种存储数据结构:

 

1、ziplist

2、dictht

当hash对象可以同时满足两个条件时,哈希对象使用ziplist。
  1>哈希对象保存的所有键值对的键和值的字符串长度都小于64字节
       2>哈希对象保存的键值对数量小于512个

 

应用场景:

  1、购物车数据,商品详情页数据

  2、用户数据

  3、原子递增

  ....................

 

5、list

常用命令:

LPUSH key value [value...]               从队列的左边入队一个元素或多个元素
LPOP key 从队列的左边出队元素
RPUSH key value [value ....] 从队列的右边入队一个元素
RPOP key                    从队列的右边出队一个元素
BLPOP key [key ...] timeout 删除,并获得该列表中的第一元素,如果当前队列没有元素则阻塞,直到有新的元素
BRPOP key [key ...] timeout 删除,并获得该列表中的最后一个元素,如果当前队列没有元素则阻塞,直到有新的元素
LRANGE key start stop 返回列表 key中指定区间内的元素,区间以偏移量start和stop指定。
RPOPLPUSH source destination        命令RPOPLPUSH在一个原子时间内,执行以下两个动作:
                          1.将列表source中的最后一个元素(尾元素)弹出,并返回给客户端。
                          2.将source 弹出的元素插入到列表destination,作为destination列表的的头元素。

 LLEN key                                 返回列表 key的长度。

数据结构:

  1、栈结构+队列结构

  2、支持阻塞/非阻塞的LIFO/FIFO  

list是由一个QuickList的一个结构,由一个双向链表,每个节点的数据基于zipList(压缩列表),压缩列表可以节省系统资源。

 

 

 

应用场景:

  1、分布式队列,消息队列

  2、随机红包,一个红包分为十份,创建一个大小为10的List的数据结构

  3、库存秒杀活动

  .......

 

6、set

常用命令:

SADD key member [member...]         添加一个或者多个元素到集合(set)里
SCARD key                    获取集合里面的元素数量
SDIFF key [key ...]              获得队列不存在的元素
SDIFFSTORE destination key [key ....]     获得队列不存在的元素,并存储在一个关键的结果集
SINTER key [key...]              获得两个集合的交集
SINTERSTORE destination key [key ...]     获得两个集合的交桌,并存储在一个关键的结果集
SISMEMBER key member                      确定一个给定的值是一个集合的成员
SMEMBERS key                  获取集合里面的所有元素
SMOVE source destination member       移动集合里面的一个元素到另一个集合
SPOP key [count]                删除并获取一个集合里面的元素
SRANDMEMBER key [count]           从集合里面随机获取一个元素
SREM key member [member ...]              从集合里删除一个或多个元素
SUNION key [key ...]             添加多个set元素
SUNIONSTORE destination key [key ...]     合并set元素,并将结果存入新的set里面

数据结构:没有重复元素的一个集合数据结构

    

 

 

 set也有两种数据结构:

intset:  

 

 

 

dictht:和hash一样,只不过value值是为null

当满足以下两个条件时,采用intset:

  1》集合对象保存的所有元素都是整数值。
       2》集合对象保存的元素数量不超过512个。

应用场景:

  1、用户画像,推荐

  2、用户匹配

  3、标签

  ....

 

7、zset

常用命令:

  


zadd key score member[{score member}...]    创建或设置指定key对应的有序集合。根据每个值对应的score来排名,升序。

zrem key member                   删除指定key对应的集合中的member元素

zcard key                       返回指定key对应的有序集合的元素数量

zincrby key increment member           将指定key对应的集合中的member元素对应的分值递增加increment

zcount key min max                 返回指定key对应的有序集合中。分值在min-max之间的元素个数

zrank key member                  返回指定key对应的有序集合中。指定元素member在集合中排名,从0开始切分值是从小到大升序

zscore key member                  返回指定key中的集合中指定member元素对应的分值

zrange key min max [withscores]        返回指定key对应的有序集合中。索引在min~max之间的元素信息,如果带上withscores属性 的话,可以将分值也带出来

zrevrank key member                返回指定key对应的集合中,指定member在其中的排名.注意排名从0开始且按照分值从大到小降序

zrevrange key start end [withscores]      指定key对应的集合中,分值在start~end之间的降序.加上withscores的话可以将分值以及 value都显示出来

zrangebyscore key start end [withscores]    同zrange命令不同的是,zrange命令是索引在start-end范围的查询。 而zrangebyscore命令是根 据分值在start-end之间的查询且升序展示

zremrangebyrank key start end          移除指定key对应集合中索引在start~end之间(包括start和end本身)的元素
zremrangebyscore by min max            同zremrangebyrank命令类似.不同的该命令是删除分值在min~max之间的元素

 

数据结构:zset也是采用了两种数据结构

  zipList:压缩列表

  zskipList:跳表

 

满足以下两个条件使用压缩列表

  1>键值对数量少于128个;

  2>每个元素的长度小于64字节

 

 

跳跃表:在有序链表的数据结构中,查询的效率为O(n),在跳跃表中,通过建立层次索引,来提高查询的效率O(Logn),

 

跳跃表体现了空间换时间的思想,在数据比较大的时候的使用。

 

跳跃表的查询过程:

例如下图已经生成一个调表的结构:现在需要查询13的数,从最高层索引开始查询,步骤如图所示。

 

 

 

应用场景:

  1、热点话题

  2、排行榜

  .......

 

 

 

 参考:

http://doc.redisfans.com/

https://blog.csdn.net/mccand1234/article/details/93411326

https://www.cnblogs.com/reecelin/p/13368374.html

https://redis.io/documentation

 

  

  

posted @ 2021-09-05 16:58  来一杯可乐  阅读(307)  评论(0编辑  收藏  举报