百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

# Redis 入门到精通(一)数据类型(2)

mhr18 2024-11-19 06:53 18 浏览 0 评论

# Redis 入门到精通(一)数据类型(2)

## 一、redis 数据类型--hash 类型介绍与基本操作

### 1、hash 类型

- 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息。

- 需要的存储结构:一个存储空间保存多个键值对数据。

- hash 类型:底层使用哈希表结构实现数据存储。

### 2、hash 存储结构优化

- 如果 field 数量较少,存储结构优化为类数组结构。

- 如果 field 数量较多,存储结构使用HashMap结构。

### 3、hash 类型数据的基本操作

```bash

# 1)添加/修改数据

hset key field value

# 获取数据

hget key field

hgetall key

# 删除数据

hdel key fieldl [field2]

# 范例:

127.0.0.1:6379> hset zsf name zhangsanfeng

(integer) 1

127.0.0.1:6379> hset zsf age 101

(integer) 1

127.0.0.1:6379> hset zsf weight 80

(integer) 1

127.0.0.1:6379> hget zsf age

"101"

127.0.0.1:6379> hgetall zsf

1) "name"

2) "zhangsanfeng"

3) "age"

4) "101"

5) "weight"

6) "80"

127.0.0.1:6379>

# 2)添加/修改多个数据

hmset key fieldl valuel field2 value2

# 获取多个数据

hmget key fieldl field2...

# 获取哈希表中字段的数量

hlen key

# 获取哈希表中是否存在指定的字段

hexists key field

# 范例:

127.0.0.1:6379> hmget zsf name age

1) "zhangsanfeng"

2) "101"

127.0.0.1:6379> hmset zsf name lixiaolong age 38

OK

127.0.0.1:6379> hgetall zsf

1) "name"

2) "lixiaolong"

3) "age"

4) "38"

5) "weight"

6) "80"

127.0.0.1:6379>

127.0.0.1:6379> hlen zsf

(integer) 3

127.0.0.1:6379> hexists zsf age

(integer) 1

127.0.0.1:6379> hexists zsf hight

(integer) 0

127.0.0.1:6379>

```

## 二、redis 数据类型--hash 扩展操作与使用注意事项

### 1、hash 类型数据扩展操作

```bash

# 获取哈希表中所有的字段名或字段值

hkeys key

hvals key

# 设置指定字段的数值数据增加指定范围的值

hincrby key field increment

hincrbyfloat key field increment

# 范例:

127.0.0.1:6379> hkeys zsf

1) "name"

2) "age"

3) "weight"

127.0.0.1:6379> hvals zsf

1) "lixiaolong"

2) "38"

3) "80"

127.0.0.1:6379> hset zsf weight 38

(integer) 0

127.0.0.1:6379> hvals zsf

1) "lixiaolong"

2) "38"

3) "38"

127.0.0.1:6379> hincrby zsf age 2

(integer) 40

127.0.0.1:6379>

```

### 2、hash 类型数据操作的注意事项

- hash 类型下的 value 只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到对应的值为(nil)。

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

- hash 类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,切记不可滥用,更不可以将hash作为对象列表使用。

- hgetal 操作可以获取全部属性,如果内部 field 过多,遍历整体数据效率就很会低,有可能成为数据访问瓶颈。

## 三、redis 数据类型--hash 实现购物车

### 1、hash 类型应用场景:业务场景--电商网站购物车设计与实现

1)业务分析

- 仅分析购物车的 redis 存储模型添加、浏览、更改数量、删除、清空。

- 购物车于数据库间持久化同步(不讨论)。

- 购物车于订单间关系(不讨论 )。

提交购物车:读取数据生成订单。

商家临时价格调整:隶属于订单级别。

- 未登录用户购物车信息存储(不讨论)。

cookie 存储。

2)解决方案

- 以客户 id 作为 key,每位客户创建一个 hash 存储结构存储对应的购物车信息。

- 将商品编号作为 field,购买数量作为 value 进行存储。

- 添加商品:追加全新的 field 与 value。

- 浏览:遍历 hash。

- 更改数量:自增/自减,设置 value 值。

- 删除商品:删除 field。

- 清空:删除 key。

- 此处仅讨论购物车中的模型设计。

- 购物车与数据库间持久化同步、购物车与订单间关系、未登录用户购物车信息存储不进行讨论。

### 2、redis 实际模拟操作:

```bash

# 如:用户01,购买商品g01, 100个,购买商品g02,200个

127.0.0.1:6379> hmset user01 g01 100 g02 200

OK

# 如:用户02,购买商品g02, 1个,购买商品g04,7个,购买商品g05,100个,

127.0.0.1:6379> hmset user02 g02 1 g04 7 g05 100

OK

# 如:用户01,再次购买商品g03, 5个,

127.0.0.1:6379> hset user01 g03 5

(integer) 1

# 如:查询 用户01 购买的商品和数量

127.0.0.1:6379> hgetall user01

1) "g01"

2) "100"

3) "g02"

4) "200"

5) "g03"

6) "5"

127.0.0.1:6379>

# 如:用户01 不需要商品g01(删除商品)

127.0.0.1:6379> hdel user01 g01

(integer) 1

127.0.0.1:6379> hgetall user01

1) "g02"

2) "200"

3) "g03"

4) "5"

127.0.0.1:6379>

# 如:用户01 添加商品g03(购物)1个

127.0.0.1:6379> hincrby user01 g03 1

(integer) 6

127.0.0.1:6379> hgetall user01

1) "g02"

2) "200"

3) "g03"

4) "6"

127.0.0.1:6379>

```

### 3、hash 类型应用场景:当前设计是否加速了购物车的呈现?

当前仅仅是将数据存储到了 redis 中,并没有起到加速的作用,商品信息还需要二次查询数据库。

- 每条购物车中的商品记录保存成两条 field

- field1 专用于保存购买数量

命名格式:商品id:nums

保存数据:数值

- field2 专用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息等

命名格式:商品id:info

保存数据:json


### 4、redis 实际模拟操作:

```bash

# 用户03 购物商品g01,关联数量nums, 100个,商品g01信息info, 为【...】暂时省略。

127.0.0.1:6379> hmset user03 g01:nums 100 g01:info [...]

OK

127.0.0.1:6379> hgetall user03

1) "g01:nums"

2) "100"

3) "g01:info"

4) "[...]"

127.0.0.1:6379>

# 用户04 也购物商品g01,关联数量nums, 5个,商品g01信息info, 为【...】暂时省略。大量重复信息

127.0.0.1:6379> hmset user04 g01:nums 5 g01:info [...]

OK

127.0.0.1:6379> hgetall user04

1) "g01:nums"

2) "5"

3) "g01:info"

4) "[...]"

127.0.0.1:6379>

# 独立 hash,有值,不操作,无值,再添加,就避免大量重复信息与重复操作,效率提高。

# 命令:hsetnx key field value

# 如:正常修改 用户03,商品g01的数量nums 为 200,成功

127.0.0.1:6379> hset user03 g01:nums 200

(integer) 0

127.0.0.1:6379> hgetall user03

1) "g01:nums"

2) "200"

3) "g01:info"

4) "[...]"

# 如:通过 hsetnx 修改 用户03,商品g01的数量nums 为 400,发现商品g01有值,不操作,修改失败。

127.0.0.1:6379> hsetnx user03 g01:nums 400

(integer) 0

# 如:通过 hsetnx 修改 用户03,添加商品g05的数量nums 为 1,发现没有商品g05,添加成功

127.0.0.1:6379> hsetnx user03 g05:nums 1

(integer) 1

127.0.0.1:6379> hgetall user03

1) "g01:nums"

2) "200"

3) "g01:info"

4) "[...]"

5) "g05:nums"

6) "1"

127.0.0.1:6379>

```

### 5、redis 应用场景:

1)redis 用于控制数据库表主键 id,为数据库表主键提供生成策略,保障数据库表的主键唯一性此方案适用于所有数据库,且支持数据库集群。

2)redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作。

3)redis 可应用于各种结构型和非结构型高热度数据访问加速。

4)redis 应用于购物车数据存储设计。

## 四、redis 数据类型--hash 实现抢购

### 1、hash 类型应用场景: 业务场景

双11活动日,销售手机充值卡的商家对移动、联通、电信的 30元、50元、100元 商品推出抢购活动,每种商

品抢购上限1000张。

### 2、hash 类型应用场景:解决方案

- 以商家 id 作为 key。

- 将参与抢购的商品 id 作为 field。

- 将参与抢购的商品数量作为对应的 value。

- 抢购时使用降值的方式控制产品数量。

- 实际业务中还有超卖等实际问题,这里不做讨论。

### 3、redis 实际模拟操作:

```bash

# 如:商家p01, 有 30元、50元、100元手机充值卡各 1000 张。

127.0.0.1:6379> hmset p01 c30 1000 c50 1000 c100 1000

OK

# 商家p01,销售出去50元一张

127.0.0.1:6379> hincrby p01 c50 -1

(integer) 999

# 商家p01,销售出去100元20张

127.0.0.1:6379> hincrby p01 c100 -20

(integer) 980

127.0.0.1:6379> hgetall p01

1) "c30"

2) "1000"

3) "c50"

4) "999"

5) "c100"

6) "980"

127.0.0.1:6379>

```

### 4、redis 应用场景:

1)redis 用于控制数据库表主键 id,为数据库表主键提供生成策略,保障数据库表的主键唯一性此方案适用于所有数据库,且支持数据库集群。

2)redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作。

3)redis 可应用于各种结构型和非结构型高热度数据访问加速。

4)redis 应用于购物车数据存储设计。

5)redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计。

## 五、redis 数据类型--list 类型介绍与基本操作

### 1、list 类型

- 数据存储需求: 存储多个数据,并对数据进入存储空间的顺序进行区分。

- 需要的存储结构: 一个存储空间保存多个数据,且通过数据可以体现进入顺序。

- list 类型: 保存多个数据,底层使用双向链表存储结构实现。

### 2、list 类型数据基本操作--添加/修改数据

```bash

# 添加/修改数据

lpush key valuel [value2]

rpush key valuel [value2]

```

### 3、list 类型数据基本操作--获取数据

```bash

# 获取数据

lrange key start stop

lindex keyindex

1len key

```

### 4、list 类型数据基本操作--获取并移除数据

```bash

# 获取并移除数据

lpop key

rpop key

```

### 5、redis 实际模拟操作:

```bash

# 从左边插入数据

127.0.0.1:6379> lpush list1 huawei

(integer) 1

127.0.0.1:6379> lpush list1 apple

(integer) 2

127.0.0.1:6379> lpush list1 microsoft

(integer) 3

# 从左边获取数据

127.0.0.1:6379> lrange list1 0 2

1) "microsoft"

2) "apple"

3) "huawei"

# 从右边插入数据

127.0.0.1:6379> rpush list2 a b c

(integer) 3

# 从左边获取数据

127.0.0.1:6379> lrange list2 0 2

1) "a"

2) "b"

3) "c"

# 从左边获取数据(未知总数)

127.0.0.1:6379> lrange list1 0 -1

1) "microsoft"

2) "apple"

3) "huawei"

127.0.0.1:6379> lrange list1 0 -2

1) "microsoft"

2) "apple"

127.0.0.1:6379> lrange list1 0 -3

1) "microsoft"

127.0.0.1:6379> lrange list1 0 -4

(empty list or set)

127.0.0.1:6379> lrange list1 -1 0

(empty list or set)

127.0.0.1:6379>

# 获取指定元素

127.0.0.1:6379> lindex list1 0

"microsoft"

127.0.0.1:6379> lindex list2 1

"b"

127.0.0.1:6379> lindex list1 1

"apple"

127.0.0.1:6379> lindex list1 2

"huawei"

127.0.0.1:6379> lindex list2 0

"a"

127.0.0.1:6379> lindex list2 2

"c"

# 获取数据长度

127.0.0.1:6379> llen list1

(integer) 3

127.0.0.1:6379> llen list2

(integer) 3

127.0.0.1:6379>

# 获取并移除数据

127.0.0.1:6379> lpush list3 a b c

(integer) 3

127.0.0.1:6379> lpop list3

"c"

127.0.0.1:6379> llen list3

(integer) 2

127.0.0.1:6379> lpop list3

"b"

127.0.0.1:6379> lpop list3

"a"

127.0.0.1:6379> lpop list3

(nil)

127.0.0.1:6379> llen list3

(integer) 0

127.0.0.1:6379>

```

## 六、redis 数据类型--list 阻塞数据获取

### 1、list 类型数据扩展操作:规定时间内获取并移除数据

```bash

blpop keyl [key2]timeout

brpop keyl [key2] timeout

brpoplpush source destination timeout

```

### 2、redis 实际模拟操作:

```bash

# 打开一个客户端

127.0.0.1:6379> lpush list0 a b

(integer) 2

127.0.0.1:6379> lpop list0

"b"

127.0.0.1:6379> lpop list0

"a"

127.0.0.1:6379> lpop list0

(nil)

127.0.0.1:6379> blpop list0 30

1) "list0"

2) "c"

127.0.0.1:6379> blpop list0 5

(nil)

(5.09s)

127.0.0.1:6379> blpop list0 10

1) "list0"

2) "d"

(2.42s)

127.0.0.1:6379>

```

```bash

# 另外打开一个客户端

127.0.0.1:6379> lpush list0 c

(integer) 1

127.0.0.1:6379> lpush list0 d

(integer) 1

127.0.0.1:6379>

```

## 七、redis 数据类型--list 扩展操作删除数据

### 1、list 类型数据扩展操作:业务场景

微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息如果取消点赞,移除对应好友信息。

### 2、解决方案:使用 redis 移除指定数据

```bash

# 移除指定数据

lrem key count value

```

### 3、redis 实际模拟操作:

```bash

# 从右边插入 5 个数据

127.0.0.1:6379> rpush daqiao a b c d e

(integer) 5

# 从左边获取全部数据

127.0.0.1:6379> lrange daqiao 0 -1

1) "a"

2) "b"

3) "c"

4) "d"

5) "e"

# 删除指定数据(1 个 d)

127.0.0.1:6379> lrem daqiao 1 d

(integer) 1

127.0.0.1:6379> lrange daqiao 0 -1

1) "a"

2) "b"

3) "c"

4) "e"

127.0.0.1:6379>

# 从右边插入 多条有重复的数据

127.0.0.1:6379> rpush daqiao a b a b a b c d a c e

(integer) 15

127.0.0.1:6379> lrange daqiao 0 -1

1) "a"

2) "b"

3) "c"

4) "e"

5) "a"

6) "b"

7) "a"

8) "b"

9) "a"

10) "b"

11) "c"

12) "d"

13) "a"

14) "c"

15) "e"

# 从左边开始,删除指定数据(4 个 a)

127.0.0.1:6379> lrem daqiao 4 a

(integer) 4

127.0.0.1:6379> lrange daqiao 0 -1

1) "b"

2) "c"

3) "e"

4) "b"

5) "b"

6) "b"

7) "c"

8) "d"

9) "a"

10) "c"

11) "e"

127.0.0.1:6379>

```

### 4、redis 应用场景:

1)redis 用于控制数据库表主键 id,为数据库表主键提供生成策略,保障数据库表的主键唯一性此方案适用于所有数据库,且支持数据库集群。

2)redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作。

3)redis 可应用于各种结构型和非结构型高热度数据访问加速。

4)redis 应用于购物车数据存储设计。

5)redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计。

6)redis 应用于具有操作先后顺序的数据控制。

## 八、redis 数据类型--list 实现日志消息队列

### 1、Iist 类型数据操作注意事项

- list 中保存的数据都是 string 类型的,数据总容量是有限的,最多 232-1个元素 (4294967295)。

- list 具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作。

- 获取全部数据操作结束索引设置为 -1。

- list 可以对数据进行分页操作,通常第一页的信息来自于 list,第2页及更多的信息通过数据库的形式加载。

### 2、list 类型应用场景:

1)业务场景1

twitter、新浪微博、腾讯微博中个人用户的关注列表需要按照用户的关注顺序进行展示,粉丝列表需要将最近关注的粉丝列在前面。

2)业务场景2

- twitter、新浪微博、腾讯微博中个人用户的关注列表需要按照用户的关注顺序进行展示,粉丝列表近关注的粉丝列在前面。

- 新闻、资讯类网站如何将最新的新闻或资讯按照发生的时间顺序展示?

- 企业运营过程中,系统将产生出大量的运营数据,如何保障多台服务器操作日志的统一顺序输出?

3)list 类型应用场景--解决方案

- 依赖 list 的数据具有顺序的特征对信息进行管理。

- 使用队列模型解决多路信息汇总合并的问题。

- 使用栈模型解决最新消息的问题。

### 3、redis 实际模拟操作--list 实现日志消息队列:

```bash

# 终端一从右边插入日志数据

127.0.0.1:6379>

127.0.0.1:6379> rpush logs a1..

(integer) 1

127.0.0.1:6379> rpush logs a2...

(integer) 2

# 查询数据

127.0.0.1:6379> lrange logs 0 -1

1) "a1.."

2) "a2..."

3) "b1.."

4) "b2..."

5) "c1.."

6) "c2..."

127.0.0.1:6379>

```

```bash

# 终端二从右边插入日志数据

127.0.0.1:6379> rpush logs b1..

(integer) 3

127.0.0.1:6379> rpush logs b2...

(integer) 4

127.0.0.1:6379>

```

```bash

# 终端三从右边插入日志数据

127.0.0.1:6379>

127.0.0.1:6379> rpush logs c1..

(integer) 5

127.0.0.1:6379> rpush logs c2...

(integer) 6

127.0.0.1:6379>

```

### 4、redis 应用场景:

1)redis 用于控制数据库表主键 id,为数据库表主键提供生成策略,保障数据库表的主键唯一性此方案适用于所有数据库,且支持数据库集群。

2)redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作。

3)redis 可应用于各种结构型和非结构型高热度数据访问加速。

4)redis 应用于购物车数据存储设计。

5)redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计。

6)redis 应用于具有操作先后顺序的数据控制。

7)redis 应用于最新消息展示。

`上一节关联链接请点击:`

https://dzs168.blog.csdn.net/article/details/140267140

[# Redis 入门到精通(一)数据类型(1)](https://dzs168.blog.csdn.net/article/details/140267140)

相关推荐

【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

Pure Storage推出统一数据管理云平台及新闪存阵列

PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

对Java学习的10条建议(对java课程的建议)

不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

JDK21有没有什么稳定、简单又强势的特性?

佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

Java面试题及答案最全总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

数据库日常运维工作内容(数据库日常运维 工作内容)

#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

分布式之系统底层原理(上)(底层分布式技术)

作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

oracle 死锁了怎么办?kill 进程 直接上干货

1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

SpringBoot 各种分页查询方式详解(全网最全)

一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

LoadRunner(loadrunner录制不到脚本)

一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

Redis数据类型介绍(redis 数据类型)

介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

RMAN备份监控及优化总结(rman备份原理)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

取消回复欢迎 发表评论: