有勇气的牛排博客

Redis(二)数据库操作、常见数据类型讲解与应用场景解读

有勇气的牛排 647 数据库 2023-01-12 21:33:29

哈喽,大家好,我是有勇气的牛排(全网同名)🐮🐮🐮

有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。

文章目录

1 Redis 十大数据类型

Redis中数据是 key-value 形式存储。一般key被设定为字符串。key为字符串类型,
value有如下类型:

  1. redis字符串(String)
  2. redis列表(List)
  3. redis哈希表(Hash)
  4. redis集合(Set)
  5. redis有序集合(ZSet)
  6. redis地理空间(GEO)
  7. reids基数统计(HyperLogLog)
  8. reids位图(bitmap)
  9. redis位域(bitfield)
  10. redis流(Stream)

2 库操作

1、切换数据库

select 库

2、查看当前数据库的key数量

dbsize

3、清空当前库

flushdb

4、通杀全部库

flushall

帮助:hele @数据类型

3 Redis的Key

  • 一般成功返回1,失败返回0
  • 命令不区分大小写,而key区分大小写

3.1 keys *

查看所有key

keys *

h?llo 匹配 hello, hallo 和 hxllo
h*llo 匹配 hllo 和 heeeello
h[ae]llo 匹配 hello and hallo, 不匹配 hillo
h[^e]llo 匹配 hallo, hbllo, … 不匹配 hello
h[a-b]llo 匹配 hallo 和 hbllo

3.2 dbsize

查看当前数据库key的数量

3.2 exist key 判断key是否存在

语法:exist <key>

set name 有勇气的牛排 exists name exists name1

image.png

3.3 type key 查看key类型

语法:type <key>

image.png

3.4 expire key 为key设置过期时间

单位秒

语法:expire <key> <秒数>

set name 有勇气的牛排 expire name 5

3.5 ttl key 查看key过过期时间

语法:ttl <key>

-1:代表永不过期。
-2:代表已过期

image.png

3.6 move key 移动key到其他库

语法:move key [0~15]

# 移动k1到db2 move k1 2

3.7 del key 删除指定key数据

1、语法:del <key>(多个key,用空格隔开)

返回值:被删除key的数量。

image.png

3.8 unlink key 异步删除key

2、语法:unlink <key>(多个key,用空格隔开)

不同于del的是,unlink仅将keysoace从元数据中删除,真正的删除在后续的异步操作完成。

set name 有勇气的牛排 unlink name

4 Redis字符串(String)

String是Redis最基本的数据类型,最大到512M,是二进制安全的。意味着Redis的String可以包含任何数据。比如jpg图片或者序列化的对象。

String的数据结构为简单东岱字符串(Simple Dynamic String,缩写SDS),是可以修改的字符串,内部结构实现上类似于JAVA的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。

一般内部会给字符串分配大于字符串的长度,当字符串长度小于1M时,扩容加倍增长;当大于1M时,则只会多扩1M空间,最大512M。

4.1 set 命令

1、set
语法:set <key> <value> <EX> <PX>

属性:重复set,则覆盖原有value

key:键
value:值
ex:超时秒数
PX:超时毫秒数

例如:key=name、value=cs,并且5秒过期

set name cs 5

4.2 get 命令

定义:获取key的value值
语法:get <key>

image.png

4.3 append 字符串内容追加

定义:获取字符串内容,并且内容追加

语法:append <key> <value>

image.png

4.4 strlen 获得值的长度

语法:stelen <key>

strlen name

4.5 getrange与setrange 区间范围值

语法:
getrange <key> <起始位置> <结束位置>
setrange <key> <起始位置>(会按位数覆盖)

image.png

4.6 数值自增&自减

4.6.1 incr、decr

定义:将key中的的数值+1或-1,必须为数值类型,若为空,则默认为1。
场景:可以做流量控制、网页访问次数统计等,具有原子性。
语法:incr <key>decr <key>

image.png

4.6.2 incrby与decrby指定步长

语法:incrby <key> <步长>decrby <key> <步长>

image.png

4.7 mset、msetnx与mget 读/写多个k-v

语法:
mset <key1> <value1> <key2> <value2>
msetnx <key1> <value1> <key2> <value2>
mget <key1> <key2>

注:msetnx当且仅当所有key不存在才能成功,只要一个失败,则都失败(原子性)。

image.png

4.8 getset 新旧址替换

定义:获取旧值,并且替换为新值。

语法:getset <key> <value>

image.png

4.9 分布式锁

4.9.1 setnx

定义:key不存在时才能成功设置值

语法:stelen <key>

4.9.2 setex

定义:写键值对,附加过期时间

语法:setex <key> <过期时间> <value>

5 Redis列表List

Redis列表是简单的字符串列表,即一键多值,按照插入顺序排序,可以插到列表头部或者尾部。

其底层实际是由双向列表实现,对两端的操作性能很高,通过索引下标操作中间节点的性能较差。

数据结构

List

5.1 lpush与rpush

定义:从左边/右边插入1个或多个值。

lpush <key> <v1> <v2> ... <vn>
rpush <key> <v1> <v2> ... <vn>

image.png

5.2 lpop与rpop

定义:从左边/右边 吐出一个值。(取出来就没有了哦)

语法:

lpop <key> <count>
rpop <key> <count>

image.png

5.4 rpoplpush 右出左进

定义:右边pop一个值,push到左边。

语法:rpoplpush <key1> <key2>

5.4 lrange查询

定义:安装索引下表查询元素(从左到右)

lrange <key> <start> <stop>

查询所有:

lrange <key> 0 -1

5.5 其他

# 1 按照索引下标获得元素(从做到右) 语法:lindex <key> <index> # 2 获取列表长度 语法:llen <key> # 3 删除左边n个value 语法:lrem <key> <n> <value> # 4 插入新值 linsert <key> index before/after # 5 lset

5.6 应用场景(公众号消息订阅)

微信公众号订阅消息

原理:创作者发布文章后,就会将文章id写入到订阅者的List中。

6 Redis 哈希(Hash)

  • Redis hash是一个键值对集合。
  • Redis hash是一个string类型的files和value的映射表,hash特别适合用于存储对象。
  • kv模式不变,但v是一个键值对。

数据结构

Hash类型对应的数据结构有两种:

  1. ziplist(压缩列表)
  2. hashtable(哈希表)

当field-value 长度较短且个数较少时,使用ziplist,否则使用hashtable。

6.1 hset、hget

给集合key的filed复制value
hset <key> <filed> <value>

hget <key> <filed>

hset user:cs age 20 hget user:cs age

6.2 hmset、hmget批量设置值

hmset <key1> <filed1> <value1> <filed2> <value2> ...

hmset user name cs age 20 id 001 hmget user name age id

image.png

6.3 hgetall、hlen、hdel

hgetall <key>:获取所有子键

hlen <key>:获取键长度

hdel <key>:删除键

image.png

6.4 hexists、hkeys、hvals

hexists <key1> <filed>: 查看哈希集合key中filed是否存在

hkeys <key>: 列出哈希集合key中所有field

hvals <key>: 列出哈希集合key的所有value

6.5 hincrby 数值增减

为哈希集合key的field的值加减指定值

hincrby <key> <filed> <increment>

6.6 hsetnx 不存在新增(分布式)

新增哈希集合key的filed域,当且仅当filed不存在

hsetnx <key> <field> <value>

image.png

6.7 应用场景(购物车)

小公司可以用

例如:购物车中商品的数量

# 场景 bigkey smallkey value 用户id 商品id 商品属性(数量) # 新增商品(001用户,加购2号商品,5个) hset shopcar:user001 2 5 # 增加商品数量 hincrby shopcar:user001 2 1 # 加购商品总数量 hlen shopcar:user001 # 全部选择 hget shopcar:user001

7 Redis集合(Set)

  • 单key,多value,且不重复

Redis Set对外提供的功能与list类似,都提供的是列表功能,其特殊之处在于set可以自动排重,而且set提供了判断成员是否存在的接口,list是没有的。

Redis的set集合是string类型的无序集合,底层为一个value为null的hash表,故新增、删除、查询的复杂度都是 O(1),即查询时间不随数据量增减而改变。

数据结构

其数据结构由dict字典实现(字典由哈希表实现)

Java中的HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。

Redis的set结构也一样,其内部使用hash结构,所有value指向同一个值。

7.1 sadd、smembers

1、将一个或多个member元素加入到集合key中,已经存在的member会被忽略。
sadd <key> <value1> <value2> ...

2、获取集合key的所有值

smembers <key>

7.2 sismember 判断值是否存在集合中

判断集合key,是否包含value值。

sismember <key> <value>

7.3 scard 获取集合元素个数

返回集合key的元素个数

scard <key>

7.4 srem 删除集合中指定元素

删除集合中的某个元素

srem <key> <value1> <value2> ...

7.6 spop 随机从集合pop值,且删除

随机从集合中吐出n个值(n可以不写,默认为1)

spop <key> <n>

7.7 srandmember 随机取值,不删除

随机从集合中取出n个值,但不从集合中删除

srandmember <key> <n>

7.8 smove 移动

将value从一个集合key1移动到集合key2中。

smove <key1> <key2> <value>

7.9 sinter、sunion 、sdiff 集合运算(交并差集)

获取两个集合的交集

sinter <ke1> <key2>

获取两个集合的并集

sunion <key1> <key2>

获取两个集合的差集

sdiff <key1> <key2>

7.10 应用场景(抽奖、共同好友、可能认识的人…)

抽奖

# 参与抽奖 sadd key 用户ID # 显示多少人参数抽奖 scard key # 随机选取n个中奖人 srandmember key 2 # 元素不删除 spop key 2 # 元素会删除(即不允许重复抽奖)

例如:朋友圈同赞朋友

# 新增点赞 sadd pub:msgID 点赞用户ID1 点赞用户ID2 # 取消点赞 srem pub:msgID 点赞用户ID # 展现所有点赞用户 smembers pub:msgID # 点赞用户数统计 scard pub:msgID

可能认识的人、猜你喜欢

# 原理:取差集 sdiff user1 user2

8 Redis有序结合 Zset(sorted set)

zset与set非常相似,是一个没有重复元素的字符串集合。

不通之处是有序集合的每个成员关联了一个评分(score),这个评分被用来按照从最低到最高分的方式排序集合中的成员。(评分可以被重复)

数据结构

SortedSet(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map(String, Double), 可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部元素会按照权重score进行排序,可以得到每个元素的名词,还可以通过score范围来获取元素列表。

zset底层使用了两个数据结构:

  1. hash,hash的作用是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到响应的score值。
  2. 跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

8.1 zadd 插入 元素+分数

1、将一个或多个member元素及score值加入到有序集key中

zadd <key> <score1> <value> <score2> <value2>

zadd cs 99 math 98 chinese 100 computer

8.2 zrange、zrevrange

  • zrange:安顺序取
  • zrevrange:顺序反转

获取有序集合key中,下表在<start>-<stop>之间的元素

[WITHSOCRES]参数代表,分数也被返回。

zrange <key> <start> <stop> [WITHSOCRES]

取所有:

 zrange cs 0 -1

image.png

带分数

zrange cs 0 -1 withscores

image.png

8.3 zrangebyscore

按score范围查(例如200->300之间),从小到大

zrangebyscore <key> 200 300 withscores

# 拿出99~100的科目 包含99 zrangebyscore cs 99 100 withscores # 拿出99~100的科目 不包含99 zrangebyscore cs (99 100 withscores # 拿出90~100的科目 前两个 zrangebyscore cs 90 100 withscores limit 0 2

8.4 zscore 获取元素的分数

zscore key member

zscore cs computer

8.5 zrem删除

删除指定元素

zrem <key> <value>

8.6 zincrby增加

zincrby <key> <increment> <value>

8.7 zcount 获得分数区间的元素个数

获得分数区间的元素个数

zcount <key> <min> <max>

8.8 zrank 获取下标

  • zrevrank

返回集合中的下标,从0开始

zrank <key> <value>

8.9 zmpop

# 弹出最小的 zmpop 1 cs min count 1

8.10 应用场景(按照销售情况排序商品)

定义商品销售排行榜(sorted set集合),key为good:sellsort,分数为商品销售数量

# 商品1001销量为9,商品1002销量为15 zadd goods: sellsort 9 1001 15 1002 # 有一个客户又买了2件1001 zincrby goods: sellsort 2 1001 # 求商品销量前10名(定时刷新获取) zrange goods:sellsort 0 9 withscores

9 Redis位图(bitmap)

**定义:**由0和1状态表现的二进制位的bit数组

说明:

用String类型作为底层数据结构实现的一种统计二值状态的数据类型。

位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成。每个二进制位都对应一个偏移量(我们称之为索引)。

Bitmap支持最大的位数为232位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息(232=4294967296)

9.1 setbit、getbit

语法: setbit <key> offset value

# 第1、7天有签到 setbit k1 1 1 setbit k1 7 1 # 获取第6天签到情况 getbit k1 6 # 结果0

image.png

9.2 strlen 统计字节数占用多少

原理:这里8位为一组,不是字符串长度多少而占用几个字节,而是超过8位一组,byte再扩容。

语法:strlen <key>,(输出字节数)

9.3 bitcount 全部键里含有1的个数

语法:bitcount <key>

9.4 bitstop(统计登录次数)

查看那连续2天签到用户

# 映射用户 hset uid:map 0 uid_1 hset uid:map 1 uid_2 # 查看所有用户 hgetall uid:map # 记录登录过得用户: # 10号,0~3号用户登录过 setbit 20230310 0 1 setbit 20230310 1 1 setbit 20230310 2 1 setbit 20230310 3 1 # 11号,0、2号用户登录过 setbit 20230310 0 1 setbit 20230311 2 1 # 查看那20230311,0号用户有没有登录过 getbit 20230311 0 # 统计指定10、11号都登录的用户 bitop and haslogin 20230310 20230311 bitcount haslogin

9.5 应用场景(打卡、签到、广告点击…)

  • 用户状态统计
  • 用户是否登录过Y、N;比如每日签到送积分
  • 电影、广告是否被点击播放过
  • 打卡上下班,签到统计

10 Redis HyperLogLog 去重复统计功能的基数估计算法

定义:去重复统计功能的基数估计算法

基数:是一种数据集,去重复后的真实个数

缺点:有个标准误差在0.81%

在Redis里面,每个HyperLogLog键只需要花费12KB内存,就可以计算将近2^64个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为HyperLogLog只会根据输入元素来计算基数,而不会存储元素本身,所以HyperLogLog不能像集合那样,返回输入的各个元素。

10.1 pfadd、pfcount、pfmerge 添加/统计/合并

# 模拟第1、2天的ip pfadd ip01 1 1 2 2 3 4 5 6 pfadd ip02 8 8 9 9 # 统计ip数量 pfcount ip01 # 6个 pfcount ip02 # 2个 # 合并1、2两天的ip pfmerge disresult ip01 ip02 pfcount disresult # 8个

10.2 应用场景(UV统计)

  • 统计某个网站的UV、统计文章的UV
  • 用户搜索网站关键词的数量
  • 统计用户每天搜索不同词条个数

什么是UV:

  • Unique Vistor:独立访客,一般理解为客户端IP
  • 需要去重处理的情况,一个IP为一次

11 Redis地理空间(GEO)

  • Redis在3.2版本以后增加了地理位置的处理
  • 类型为zset

由于中文乱码,连接需要加参数

redis-cli -a 123456 --raw

百度接口(获取经纬度):https://api.map.baidu.com/lbsapi/getpoint/

天安门:116.404082,39.909187

泰山:117.094738,36.269893

11.1 geoadd 添加经纬度坐标

语法:geoadd key 经度 纬度 member

# 添加 geoadd city 116.404082 39.909187 "天安门" 117.094738 36.269893 "泰山" # 查看 zrange city 0 -1

11.2 geopos 返回经纬度

语法:geopos <key> <member> [member ...]

geopos city 天安门 泰山

image.png

11.3 geohash 返回坐标hash表示

  • geohash算法生成base32编码值
  • 3维变2维变1维

语法:geohash <key > <member> [member ...]

geohash city 天安门 泰山

image.png

11.4 geodist 获取两个位置之间距离

语法:geodist <key > <member1> <member2>

单位:m、km、ft、mi

geodist city 天安门 泰山 km

11.5 georadius 以某个半径 查找附近 ***

定义:以给定的经纬度为中心,返回键包含的位置元素中,与中心的距离不超过给定最大距离的所有位置元素。

语法:``

georadius city 116.404082 39.909187 500 km withdist withcoord count 10 withhash desc georadiusbymember city 天安门 500 km withdist withcoord count 10 withhash desc

12 Redis 流(Stream)

12.1 介绍

12.1.1 Stream流是什么

在Redis 5.0之前通过Redis实现消息队列,有两种方案:

  • list实现消息队列(点对点模式)(简单实现)
  • Pub/Sub

但是 发布订阅Pub/Sub模式有个缺点就是消息无法持久化,如果出现网络断开、Redis宕机等,消息机会被丢弃,而且也没有ACK机制来保证数据的可靠性,假设一个消费者都没有,那消息就直接被丢弃了。

因此新增了Steam实现了Redis版的消息中间件。

12.1.1 Stream流能干什么

实现消息队列、支持消息的持久化、支持自动生成全局唯一ID、支持ack确认消息的模式、支持消费组模式登,让消息队列更加的稳定和可靠。

这里建议使用专用的MQ,大厂不会采用。

13 Redis 位域(bitfield)

  • 了解即可(大厂也基本不用)

bitfield命令可以将一个Redis字符串看做是一个由二进制位组成的数组,并对这个数组中任意偏移进行访问。

参考地址:

https://www.bilibili.com/video/BV1YK411M7MG

https://www.bilibili.com/video/BV1Rv41177Af

https://www.bilibili.com/video/BV13R4y1v7sP(尚硅谷 阳哥)


留言

专栏
文章
加入群聊