Redis

1 redis入门

1.1 NoSQL的引言

        NoSQL(Not Only SQL),意即不仅仅是SQL, 泛指非关系型的数据库。Nosql这个技术门类,早期就有人提出,发展至2009年趋势越发高涨。

1.2 为什么是NoSQL

        随着互联网网站的兴起,传统的关系数据库在应付动态网站,特别是超大规模和高并发的纯动态网站已经显得力不从心,暴露了很多难以克服的问题。如商城网站中对商品数据频繁查
询、对热搜商品的排行统计、订单超时问题、以及微信朋友圈(音频,视频)存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不
是那么乐观。nosql这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。

1.3 NoSQL的四大分类
1.3.1 键值(Key-Value)存储数据库

1.说明: 
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的
键和一个指针指向特定的数据。

2.特点
Key/value模型对于IT系统来说的优势在于简单、易部署。  
但是如果DBA只对部分值进行查询或更新的时候,Key/value就
显得效率低下了。

3.相关产品
Tokyo Cabinet/Tyrant,
Redis  内存
SSDB   硬盘
Voldemort 
Oracle BDB

 

 1.3.2 列存储数据库

1.说明
这部分数据库通常是用来应对分布式存储的海量数据。

2.特点
键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。

3.相关产品
Cassandra、HBase、Riak.

1.3.3 文档型数据库 

# 1.说明
- 文档型数据库的灵感是来自于Lotus Notes办公软件的,而且
它同第一种键值存储相类似该类型的数据模型是版本化的文档,
半结构化的文档以特定的格式存储,比如JSON。文档型数据库
可以看作是键值数据库的升级版,允许之间嵌套键值。而且文
档型数据库比键值数据库的查询效率更高

# 2.特点
- 以文档形式存储

# 3.相关产品
- MongoDB、CouchDB、 MongoDb(4.x). 国内也有文档型数据
库SequoiaDB,已经开源。

 

1.3.4 图形(Graph)数据库

1.说明
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它
是使用灵活的图形模型,并且能够扩展到多个服务器上。
NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询
需要制定数据模型。许多NoSQL数据库都有REST式的数据接口
或者查询API。

2.相关产品
Neo4J、InfoGrid、 Infinite Graph、

 1.3.5 NoSQL应用场景

数据模型比较简单

需要灵活性更强的IT系统

对数据库性能要求较高

不需要高度的数据一致性

1.4 Redis 简介 
问题现象
海量用户
高并发

罪魁祸首——关系型数据库
性能瓶颈:磁盘IO性能低下
扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群

解决思路
降低磁盘IO次数,越低越好 —— 内存存储
去除数据间关系,越简单越好 —— 不存储关系,仅存储数据
这里Nosql可以解决

NoSQL:即 Not-Only SQL( 泛指非关系型的数据库),作为关系
型数据库的补充
作用:应对基于海量用户和海量数据前提下的数据处理问题。

特征:
可扩容,可伸缩
大数据量下高性能
灵活的数据模型
高可用

常见 Nosql 数据库:
Redis
memcache
HBase
MongoDB
1.5 电商场景 

1.6 认识Redis 

概念:Redis (REmote DIctionary Server) 是用 C 语言开发
的一个开源的高性能键值对(key-value)数据库

Redis is an open source (BSD licensed),
in-memory data structure store, used as a database, 
cache and message broker.
Redis开源遵循BSD  基于内存数据存储 被用于作为数据库
缓存消息中间件
总结: redis是一个内存型的数据库

特征:
1. 数据间没有必然的关联关系
2. 内部采用单线程机制进行工作
3. 高性能。官方提供测试数据,50个并发执行100000 个请求,
4. 读的速度是110000 次/s,写的速度是81000次/s。
5. 多数据类型支持
字符串类型 string
列表类型 list
散列类型 hash
集合类型 set
有序集合类型 sorted_set
6. 持久化支持。可以进行数据灾难恢复
1.7 Redis 的应用
为热点数据加速查询(主要场景),如热点商品、热点新闻、
热点资讯、推广类等高访问量信息等
任务队列,如秒杀、抢购、购票排队等
即时信息查询,如各位排行榜、各类网站访问统计、公交到站信息、
在线人数信息(聊天室、网站)、设
备信号等
时效性信息控制,如验证码控制、投票控制等
分布式数据共享,如分布式集群架构中的 session 分离
消息队列
分布式锁
 
1.8 Redis 的下载与安装
0.准备环境
vmware15.x+
centos7.x+

1.下载redis源码包
https://redis.io/

 

2.下载完整源码包
redis-6.0.9.tar.gz

3.将下载redis资料包上传到Linux中

4.解压缩文件

[root@localhost opt]# tar -zxvf redis-6.0.9.tar.gz
[root@localhost opt]# ls
containerd  redis  redis-6.0.9.tar.gz  rh

5.安装gcc  
yum install -y gcc

6.进入解压缩目录执行如下命令
make MALLOC=libc
# 这一步可能会报错,升级gcc版本即可
升级gcc版本
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils 
scl enable devtoolset-9 bash  # scl命令启用只是临时的,
退出xshell或者重启就会恢复到原来的gcc版本。

# 如果要长期生效的话,执行如下:
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile

注意:如果用客户端工具连接服务器的话,有可能使用gcc -v还是
原来的版本,只需要断开重新连接即可 
7.编译完成后执行如下命令
make install PREFIX=/usr/redis  # 将编译好的文件放到指定目录下

8.进入/usr/local/redis/bin目录启动redis服务 
./redis-server



 

9.Redis服务端口默认是 6379

10.进入bin目录执行客户端连接操作
./redis-cli –p 6379

补充:
默认配置启动
redis-server
redis-server -p 6379
redis-server  -p 6380
 
指定配置文件启动
redis-server redis.conf
redis-server redis-6379.conf
redis-server redis-6380.conf ……
redis-server conf/redis-6379.conf
redis-server config/redis-6380.conf ……

默认连接
redis-cli
连接指定服务器
redis-cli -h 127.0.0.1
redis-cli -p 6379
redis-cli -h 127.0.0.1 -p 6379

基本配置
daemonize yes
以守护进程方式启动,使用本启动方式,redis将以服务的形式存在,
日志将不再打印到命令窗口中
port 6***
设定当前服务启动端口号
dir “/自定义目录/redis/data“
设定当前服务文件保存位置,包含日志文件、持久化文件
(后面详细讲解)等
logfile "6***.log“
设定日志文件名,便于查阅

 

1.9 核心文件
redis-serve 服务器启动命令
redis-cli 命令行客户端
redis.conf    redis核心配置文件
redis-benchmark 性能测试工具
redis-check-aof AOF文件修复工具
redis-check-dump  RDB文件检查工具(快照持久化文件)
1.10 Redis 的基本操作
信息添加
set key value
set name itheima

信息查询
功能:根据 key 查询对应的 value,如果不存在,返回空(nil)
get key
get name

清除屏幕信息
功能:清除屏幕中的信息
clear

退出客户端命令行模式
功能:退出客户端
quit
exit
<ESC>

帮助
功能:获取命令帮助文档,获取组中所有命令信息名称
命令
help 命令名称
help set

127.0.0.1:6379> help get

GET key
summary: Get the value of a key
since: 1.0.0
group: string

help @组名
127.0.0.1:6379> help @string

APPEND key value
summary: Append a value to a key
since: 2.0.0

BITCOUNT key [start end]
summary: Count set bits in a string
since: 2.6.0

BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
summary: Perform arbitrary bitfield integer operations on strings
since: 3.2.0

2. Redis 数据类型

  • string String
  • hash HashMap
  • list LinkedList
  • set  HashSet
  • sorted_set TreeSet
 2.1 redis 数据存储格式

redis自身是一个Map,其中所有的数据都是采用key : value的形式存储数据类型指的是存储的数据的类型,也就是value部分的类型,key部分永远都是字符串key的语法:
在一个项目中,key最好使用统一的命名模式

key区分大小写
key不要太长,尽量不要超过1024字节。不仅消耗内存,也会降低查找的效率

key不要太短,太短可读性会降低

2.2 string 类型 
2.2.1 string操作
存储的数据:单个数据,最简单的数据存储类型,也是最常用的
数据存储类型
存储数据的格式:一个存储空间保存一个数据
存储内容:通常使用字符串,如果字符串以整数的形式展示,
可以作为数字操作使用

添加/修改数据
set key value
获取数据
get key
删除数据
del key

127.0.0.1:6379> set age 100
OK
127.0.0.1:6379> get age
"100"
127.0.0.1:6379> del age
(integer) 1
127.0.0.1:6379> del age
(integer) 0


添加/修改多个数据
mset key1 value1 key2 value2 …
获取多个数据
mget key1 key2 …
获取数据字符个数(字符串长度)
strlen key
追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append key value
127.0.0.1:6379> mset a 1 b 2 c 3
OK
127.0.0.1:6379> mget a b c
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> strlen a
(integer) 1
127.0.0.1:6379> append a 23
(integer) 3
127.0.0.1:6379> get a
"123"


设置数值数据增加指定范围的值
incr key  # 增加1
incrby key increment
incrbyfloat key increment

127.0.0.1:6379> get a
"123"
127.0.0.1:6379> incr a
(integer) 124
127.0.0.1:6379> incrby a 26
(integer) 150
127.0.0.1:6379> incrbyfloat a 50
"200"


设置数值数据减少指定范围的值
decr key # 减少1
decrby key increment

127.0.0.1:6379> get a
"174"
127.0.0.1:6379> decr a
(integer) 173
127.0.0.1:6379> decrby a 25
(integer) 148



string 作为数值操作
string在redis内部存储默认就是一个字符串,当遇到增减
类操作incr,decr时会转成数值型进行计算。
redis所有的操作都是原子性的,采用单线程处理所有业务,
命令是一个一个执行的,因此无需考虑并发
带来的数据影响。
注意:按数值进行操作的数据,如果原始数据不能转成数值,
或超越了redis 数值上限范围,将报错。

9223372036854775807(java中long型数据最大值,
Long.MAX_VALUE)

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

设置数据具有指定的生命周期
setex key seconds value  # 秒为单位
psetex key milliseconds value   # 毫秒为单位

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


127.0.0.1:6379> setex a 5 1
OK
127.0.0.1:6379> get a
"1"
127.0.0.1:6379> get a
(nil)

127.0.0.1:6379> psetex a 5000 2
OK
127.0.0.1:6379> get a
"2"
127.0.0.1:6379> get a
"2"
127.0.0.1:6379> get a
(nil)



string 类型数据操作的注意事项
数据操作不成功的反馈与数据正常操作之间的差异
① 表示运行结果是否成功
(integer) 0 → false 失败
(integer) 1 → true 成功
② 表示运行结果值
(integer) 3 → 3 3个
(integer) 1 → 1 1个
数据未获取到
(nil)等同于null
数据最大存储量
512MB
数值计算最大范围(java中的long的最大值)
9223372036854775807
2.2.2 单数据操作与多数据操作的选择之惑

set小闹钟表示发送时间,result小闹钟表示返回时间。大闹钟表示执行命令的时间

2.2.3 string 类型应用场景 

在redis中为大V用户设定用户信息,以用户主键和属性值作为key,
后台设定定时刷新策略即可
eg: user:id:3506728370:fans → 12210947
eg: user:id:3506728370:blogs → 6164
eg: user:id:3506728370:focuss → 83

127.0.0.1:6379> set user:id:3506728370:fans 12210947
OK
127.0.0.1:6379> get user:id:3506728370:fans 
"12210947"
127.0.0.1:6379> set user:id:3506728370:blogs 6164
OK
get user:id:3506728370:blogs 
"6164"
127.0.0.1:6379> set user:id:3506728370:focuss 83
OK
127.0.0.1:6379> get user:id:3506728370:focuss 
"83"


在redis中以json格式存储大V用户信息,定时刷新
(也可以使用hash类型)
eg: user:id:3506728370 →
{"id":3506728370,"name":"春晚","fans":12210862,"blogs":6164, "focus":83}

Tips 3:
redis应用于各种结构型和非结构型高热度数据访问加速
 2.2.4 key 的设置约定
set user:id:00789:fans 123
set user:id:00789:blogs 789
set userid:00789 {id:00789,blogs:789,fans:123}

2.3 hash
2.3.1 hash操作
添加/修改数据
hset key field value
获取数据
hget key field
hgetall key
删除数据
hdel key field1 [field2]

127.0.0.1:6379> hset a name xiaoming
(integer) 1
127.0.0.1:6379> hset a age 18
(integer) 1
127.0.0.1:6379> hget a name
"xiaoming"
127.0.0.1:6379> hgetall a
1) "name"
2) "xiaoming"
3) "age"
4) "18"
127.0.0.1:6379> hdel a name
(integer) 1
127.0.0.1:6379> hgetall a
1) "age"
2) "18"


添加/修改多个数据
hmset key field1 valuel field2 value2
获取多个数据
hmget key fieldl field2
获取哈希表中字段的数量
hlen key
获取哈希表中是否存在指定的字段
exists key field

127.0.0.1:6379> hmset a name xiaohong age 20
OK
127.0.0.1:6379> hmget a name age
1) "xiaohong"
2) "20"
127.0.0.1:6379> hlen a
(integer) 2
127.0.0.1:6379> exists a name
(integer) 1


获取哈希表中所有的字段名或字段值
keys key
hals key

127.0.0.1:6379> hkeys a
1) "age"
2) "name"
127.0.0.1:6379> hvals a
1) "20"
2) "xiaohong"


设置指定字段的数值数据増加指定范围的值
hincrby key field increment
hincrbyfloat key field increment


127.0.0.1:6379> hincrby a age 10
(integer) 30
127.0.0.1:6379> hgetall a
1) "age"
2) "30"
3) "name"
4) "xiaohong"
127.0.0.1:6379> hincrbyfloat a age 30.1
"60.1"
127.0.0.1:6379> hgetall a
1) "age"
2) "60.1"
3) "name"
4) "xiaohong"


hash类型数据操作的注意事项
hash类型下的 value只能存储字符串,不允许存储其
他数据类型,不存在嵌套现象。如果数据未获取到,对
应的值为(nil)
每个hash可以存储2^32-1个键值对
hash类型十分贴近对象的数据存储形式,并且可以灵活添加
删除对象属性。但hash设计初衷不是为了存储大量对象而
设计的,切记不可滥用,更不可以将hash作为对象列表使用
hgetal操作可以获取全部属性,如果内部 field过多,遍
历整体数据效率就很会低,有可能成为数据访问瓶颈
2.3.2 电商网站购物车设计与实现

解决方案
以客户id作为key,每位客户创建一个hash存储结构存
储对应的购物车信息
将商品编号作为field,购买数量作为value进行存储
添加商品:追加全新的field与value
浏览:遍历hash
更改数量:自增/自减,设置value值
删除商品:删除field
清空:删除key
此处仅讨论购物车中的模型设计
购物车与数据库间持久化同步、购物车与订单间关系、未登
录用户购物车信息存储不进行讨论


127.0.0.1:6379> hmset 001 g01 100 g02 200
OK
127.0.0.1:6379> hmset 002 g02 1 g04 7 g05 100
OK
127.0.0.1:6379> hset 001 g03 5
(integer) 1
127.0.0.1:6379> hgetall 001
1) "g01"
2) "100"
3) "g02"
4) "200"
5) "g03"
6) "5"
127.0.0.1:6379> hdel 001 g01
(integer) 1
127.0.0.1:6379> hgetall 001
1) "g02"
2) "200"
3) "g03"
4) "5"
127.0.0.1:6379> hincrby 001 g03 1
(integer) 6
127.0.0.1:6379> hgetall 001
1) "g02"
2) "200"
3) "g03"
4) "6"

当前仅仅是将数据存储到了redis中,并没有起到加速的作用,
商品信息还需要二次查询数据库
每条购物车中的商品记录保存成两条field
field1专用于保存购买数量
命名格式:商品id:nums
保存数据:数值
field2专用于保存购物车中显示的信息,包含文字描述,
图片地址,所属商家信息等
命名格式:商品id:info
保存数据:json 
hsetnx key field value # 如果field存在不覆盖,如果不存在则添加

Tips 4:
redis 应用于购物车数据存储设计

127.0.0.1:6379> hmset 003 g01:nums 100 g01:info {.....}
OK
127.0.0.1:6379> hgetall 003
1) "g01:nums"
2) "100"
3) "g01:info"
4) "{.....}"
127.0.0.1:6379> hmset 004 g01:num 5 g01:info {.....}
OK
127.0.0.1:6379> hgetall 004
1) "g01:num"
2) "5"
3) "g01:info"
4) "{.....}"

127.0.0.1:6379> hgetall 003
1) "g01:nums"
2) "200"
3) "g01:info"
4) "{.....}"
127.0.0.1:6379> hsetnx 003 g01:nums 300
(integer) 0
127.0.0.1:6379> hgetall 003
1) "g01:nums"
2) "200"
3) "g01:info"
4) "{.....}"
127.0.0.1:6379> hsetnx 003 g01:age 18
(integer) 1
127.0.0.1:6379> hgetall 003
1) "g01:nums"
2) "200"
3) "g01:info"
4) "{.....}"
5) "g01:age"
6) "18"


2.3.3 双11活动日

解决方案
以商家id作为key
将参与抢购的商品id作为field
将参与抢购的商品数量作为对应的value
抢购时使用降值的方式控制产品数量
实际业务中还有超卖等实际问题,这里不做讨论

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

127.0.0.1:6379> hmset p01 c30 1000 c50 1000 c100 1000
OK
127.0.0.1:6379> hincrby p01 c50 -1
(integer) 999
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"

 2.3.4 string跟hash的对比

string存储对象(json)与hash存储对象,string讲究整体性,主要体现读操作,而hash整体性不是那么强,主要体现更新操作

2.4 list
2.4.1 list操作
数据存储需求:存储多个数据,并对数据进入存储空间
的顺序进行区分
需要的存储结构:一个存储空间保存多个数据,且通过
数据可以体现进入顺序
list类型:保存多个数据,底层使用双向链表存储结构实现


添加/修改数据
lpush key value1 [value2] ……
rpush key value1 [value2] ……

获取数据
lrange key start stop
lindex key index
llen key 

获取并移除数据
lpop key
rpop key

127.0.0.1:6379> lpush list1 a b c
(integer) 3
127.0.0.1:6379> rpush list2 d e f
(integer) 3
127.0.0.1:6379> lrange list1 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> lrange list2 0 -1
1) "d"
2) "e"
3) "f"
127.0.0.1:6379> lindex list1 0
"c"
127.0.0.1:6379> lindex list1 -1
"a"
127.0.0.1:6379> lindex list1 -2
"b"
127.0.0.1:6379> llen list1
(integer) 3
127.0.0.1:6379> llen list2
(integer) 3
127.0.0.1:6379> lpop list1
"c"
127.0.0.1:6379> rpop list1
"a"
127.0.0.1:6379> llen list1
(integer) 1
127.0.0.1:6379> lpop list2 
"d"
127.0.0.1:6379> rpop list2
"f"
127.0.0.1:6379> llen list2
(integer) 1

规定时间内获取并移除数据
blpop key1 [key2] timeout
brpop key1 [key2] timeout

127.0.0.1:6379> keys *
1) "list2"
127.0.0.1:6379> lpush list1 aa
(integer) 1
127.0.0.1:6379> keys *
1) "list2"
127.0.0.1:6379> lpush list3 bb
(integer) 1
127.0.0.1:6379> 

127.0.0.1:6379> blpop list1 10
1) "list1"
2) "aa"
127.0.0.1:6379> blpop list3 10
1) "list3"
2) "bb"
(3.78s)
2.4.2 微信朋友圈点赞

list 类型数据扩展操作
移除指定数据
lrem key count value  # count表示移除的个数


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


127.0.0.1:6379> lpush list1 a b c d a
(integer) 5
127.0.0.1:6379> lrange list1 0 -1
1) "a"
2) "d"
3) "c"
4) "b"
5) "a"
127.0.0.1:6379> lrem list1 2 a
(integer) 2
127.0.0.1:6379> llen list1
(integer) 3
127.0.0.1:6379> lrange list1 0 -1
1) "d"
2) "c"
3) "b"
2.4.3 list 类型数据操作注意事项 
list中保存的数据都是string类型的,数据总容量是有限的,
最多2^32-1 个元素 (4294967295)。

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

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

list可以对数据进行分页操作,通常第一页的信息来自于list,
第2页及更多的信息通过数据库的形式加载
2.4.4 保障多台服务器操作日志的统一顺序输出 
依赖list的数据具有顺序的特征对信息进行管理
使用队列模型解决多路信息汇总合并的问题
使用栈模型解决最新消息的问题


Tips 7:
redis 应用于最新消息展示

127.0.0.1:6379> rpush logs a1..
(integer) 1
127.0.0.1:6379> rpush logs a1...
(integer) 2
127.0.0.1:6379> lrange logs 0 -1
1) "a1.."
2) "a1..."
3) "b1.."
4) "c1.."
5) "b1..."
6) "c1..."

127.0.0.1:6379> rpush logs b1..
(integer) 3
127.0.0.1:6379> rpush logs b1...
(integer) 5

127.0.0.1:6379> rpush logs c1..
(integer) 4
127.0.0.1:6379> rpush logs c1...
(integer) 6
2.5 set类型
2.5.1 set操作
新的存储需求:存储大量的数据,在查询方面提供更高的效率
需要的存储结构:能够保存大量的数据,高效的内部存储机制,
便于查询
set类型:与hash存储结构完全相同,仅存储键,不存储
值(nil),并且值是不允许重复的

set 类型数据的基本操作
添加数据
sadd key member1 [member2]
获取全部数据
smembers key 
删除数据
srem key member1 [member2]
获取集合数据总量
scard key
判断集合中是否包含指定数据
sismember key member

127.0.0.1:6379> sadd users zs
(integer) 1
127.0.0.1:6379> sadd users ls
(integer) 1
127.0.0.1:6379> sadd users ww
(integer) 1
127.0.0.1:6379> smembers users
1) "zs"
2) "ww"
3) "ls"
127.0.0.1:6379> srem users ww
(integer) 1
127.0.0.1:6379> smembers users
1) "zs"
2) "ls"
127.0.0.1:6379> scard users
(integer) 2
127.0.0.1:6379> sismember users zs
(integer) 1
127.0.0.1:6379> sismember users ww
(integer) 0

set 类型数据操作的注意事项
set 类型不允许数据重复,如果添加的数据在 set 中已经存在,
将只保留一份
set 虽然与hash的存储结构相同,但是无法启用hash中存
储值的空间

127.0.0.1:6379> sadd a a
(integer) 1
127.0.0.1:6379> sadd a a
(integer) 0
127.0.0.1:6379> hset a a 1
(error) WRONGTYPE Operation against a key holding the wrong kind of value

set 类型数据的扩展操作
随机获取集合中指定数量的数据
srandmember key [count]

随机获取集合中的某个数据并将该数据移出集合
spop key [count]

Tips 8:
redis 应用于随机推荐类信息检索,例如热点歌单推荐,
热点新闻推荐,热卖旅游线路,应用APP推荐,
大V推荐等

Tips 9:
redis 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索
显示共同关注(一度)
显示共同好友(一度)
由用户A出发,获取到好友用户B的好友信息列表(一度)
由用户A出发,获取到好友用户B的购物清单列表(二度)
由用户A出发,获取到好友用户B的游戏充值列表(二度)

127.0.0.1:6379> sadd news n1
(integer) 1
127.0.0.1:6379> sadd news n2
(integer) 1
127.0.0.1:6379> sadd news n3
(integer) 1
127.0.0.1:6379> sadd news n4
(integer) 1
127.0.0.1:6379> srandmember news 1
1) "n1"
127.0.0.1:6379> srandmember news 1
1) "n1"
127.0.0.1:6379> srandmember news 1
1) "n1"
127.0.0.1:6379> srandmember news 1
1) "n3"
127.0.0.1:6379> scard news
(integer) 4
127.0.0.1:6379> spop news 1
1) "n1"
127.0.0.1:6379> smembers news
1) "n4"
2) "n2"
3) "n3"
127.0.0.1:6379> spop news 2
1) "n4"
2) "n3"
127.0.0.1:6379> smembers news
1) "n2"

求两个集合的交、并、差集
sinter key1 [key2]
sunion key1 [key2]
sdiff key1 [key2]


求两个集合的交、并、差集并存储到指定集合中
sinterstore destination key1 [key2]
sunionstore destination key1 [key2]
sdiffstore destination key1 [key2] 

将指定数据从原始集合中移动到目标集合中
smove source destination member 

127.0.0.1:6379> sadd u1 a1
(integer) 1
127.0.0.1:6379> sadd u1 s1
(integer) 1
127.0.0.1:6379> sadd u1 b1
(integer) 1
127.0.0.1:6379> sadd u2 s1
(integer) 1
127.0.0.1:6379> sadd u2 w1
(integer) 1
127.0.0.1:6379> sinter u1 u2
1) "s1"
127.0.0.1:6379> sunion u1 u2
1) "a1"
2) "s1"
3) "w1"
4) "b1"
127.0.0.1:6379> sdiff u1 u2
1) "a1"
2) "b1"
127.0.0.1:6379> sdiff u2 u1
1) "w1"
127.0.0.1:6379> sdiffstore u3 u1 u2
(integer) 2
127.0.0.1:6379> smembers u3
1) "a1"
2) "b1"
127.0.0.1:6379> smove u2 u1 w1
(integer) 1
127.0.0.1:6379> smembers u1
1) "a1"
2) "s1"
3) "w1"
4) "b1"
127.0.0.1:6379> smembers u2
1) "s1"

2.5.2 sorted_set

新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式需要的存储结构:新的存储模型,可以保存可排序的数据sorted_set类型:在set的存储结构基础上添加可排序字段

sorted_set 类型数据的基本操作
添加数据
zadd key score1 member1 [score2 member2]
获取全部数据
zrange key start stop [WITHSCORES]
zrevrange key start stop [WITHSCORES]
删除数据
zrem key member [member ...]
按条件获取数据
zrangebyscore key min max [WITHSCORES] [LIMIT]
zrevrangebyscore key max min [WITHSCORES]
条件删除数据
zremrangebyrank key start stop
zremrangebyscore key min max
注意:
min与max用于限定搜索查询的条件
start与stop用于限定查询范围,作用于索引,表示开始和结束索引
offset与count用于限定查询范围,作用于查询结果,
表示开始位置和数据总量
获取集合数据总量
 zcard key
zcount key min max
集合交、并操作
zinterstore destination numkeys key [key ...]
zunionstore destination numkeys key [key ...]

127.0.0.1:6379> zadd scores 94 zs
(integer) 1
127.0.0.1:6379> zadd scores 100 ls
(integer) 1
127.0.0.1:6379> zadd scores 60 ww
(integer) 1
127.0.0.1:6379> zadd scores 47 zl
(integer) 1
127.0.0.1:6379> zrange scores 0 -1
1) "zl"
2) "ww"
3) "zs"
4) "ls"
127.0.0.1:6379> zrange scores 0 -1 withscores
1) "zl"
2) "47"
3) "ww"
4) "60"
5) "zs"
6) "94"
7) "ls"
8) "100"
127.0.0.1:6379> zrevrange scores 0 -1 withscores
1) "ls"
2) "100"
3) "zs"
4) "94"
5) "ww"
6) "60"
7) "zl"
8) "47"
127.0.0.1:6379> zrem scores ls
(integer) 1
127.0.0.1:6379> zrevrange scores 0 -1 withscores
1) "zs"
2) "94"
3) "ww"
4) "60"
5) "zl"
6) "47"

127.0.0.1:6379> zrange scores 0 -1 withscores
 1) "wangwu"
 2) "45"
 3) "zhangsan"
 4) "67"
 5) "zhouqi"
 6) "71"
 7) "qianba"
 8) "92"
 9) "lisi"
10) "99"
11) "zhangliu"
12) "100"
127.0.0.1:6379> zrangebyscore scores 50 80 withscores
1) "zhangsan"
2) "67"
3) "zhouqi"
4) "71"
127.0.0.1:6379> zrevrangebyscore scores 80 50 withscores
1) "zhouqi"
2) "71"
3) "zhangsan"
4) "67"
127.0.0.1:6379> zrangebyscore scores 50 99 withscores
1) "zhangsan"
2) "67"
3) "zhouqi"
4) "71"
5) "qianba"
6) "92"
7) "lisi"
8) "99"
127.0.0.1:6379> zrangebyscore scores 50 99 withscores limit 0 3
1) "zhangsan"
2) "67"
3) "zhouqi"
4) "71"
5) "qianba"
6) "92"
127.0.0.1:6379> zrangebyscore scores 50 99 withscores limit 0 1
1) "zhangsan"
2) "67"
127.0.0.1:6379> zremrangebyscore scores 50 70
(integer) 1
127.0.0.1:6379> zrange scores 0 -1 withscores
 1) "wangwu"
 2) "45"
 3) "zhouqi"
 4) "71"
 5) "qianba"
 6) "92"
 7) "lisi"
 8) "99"
 9) "zhangliu"
10) "100"
127.0.0.1:6379> zremrangebyrank scores 0 1
(integer) 2
127.0.0.1:6379> zrange scores 0 -1 withscores
1) "qianba"
2) "92"
3) "lisi"
4) "99"
5) "zhangliu"
6) "100"
127.0.0.1:6379> zcard scores
(integer) 3
127.0.0.1:6379> zcount scores 99 200
(integer) 2
127.0.0.1:6379> zadd s1 50 aa 60 bb 70 cc
(integer) 3
127.0.0.1:6379> zadd s2 60 aa 40 bb 90 aa
(integer) 2
127.0.0.1:6379> zadd s3 70 aa 20 bb 100 dd
(integer) 3
127.0.0.1:6379> zinterstore sss 3 s1 s2 s3   # 求和
(integer) 2
127.0.0.1:6379> zrange sss 0 -1 withscores
1) "bb"
2) "120"
3) "aa"
4) "210"
127.0.0.1:6379> zinterstore ssss 3 s1 s2 s3 aggregate max  # 求最大值
(integer) 2
127.0.0.1:6379> zrange ssss 0 -1 withscores
1) "bb"
2) "60"
3) "aa"
4) "90"
127.0.0.1:6379> help zunionstore

  ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
  summary: Add multiple sorted sets and store the resulting sorted set in a new key
  since: 2.0.0
  group: sorted_set

127.0.0.1:6379> help zinterstore

  ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
  summary: Intersect multiple sorted sets and store the resulting sorted set in a new key
  since: 2.0.0
  group: sorted_set


sorted_set 类型数据的扩展操作
获取数据对应的索引(排名)
zrank key member
zrevrank key member
score值获取与修改
zscore key member
zincrby key increment member
Tips 11:
redis 应用于计数器组合排序功能对应的排名

127.0.0.1:6379> zadd movies 143 aa 97 bb 201 cc
(integer) 3
127.0.0.1:6379> zrank movies bb
(integer) 0
127.0.0.1:6379> zrevrank movies bb
(integer) 2
127.0.0.1:6379> zscore movies aa
"143"
127.0.0.1:6379> zincrby movies 1 aa
"144"
127.0.0.1:6379> zscore movies aa
"144"

sorted_set 类型数据操作的注意事项
score保存的数据存储空间是64位,如果是
整数范围是-9007199254740992~9007199254740992
score保存的数据也可以是一个双精度的double值,基
于双精度浮点数的特征,可能会丢失精度,使用时
候要慎重
sorted_set 底层存储还是基于set结构的,因此数据不
能重复,如果重复添加相同的数据,score值将被反
复覆盖,保留最后一次修改的结果

3.Jedis

        我们要使用 Java 来操作 Redis,什么是Jedis 是 Redis 官方推荐的 java连接开发工具! 使用Java 操作 Redis 中间件! 

3.1 导入对应的依赖
<!--导入jedis的包-->
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.2.0</version>
        </dependency>
3.2 编码测试:
 @Test
    public void show(){
        Jedis jedis=new Jedis("localhost" ,6379);
        System.out.println(jedis.ping());
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值