Redis 简介

1.1 Redis是什么

(1)全称:Remote Dictionary Server(远程字典服务器)。是完全开源免费的,用C语言编写
的, 遵守BSD协议。是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。
(2)Redis 与其他 key - value 缓存产品有以下三个特点
i)Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用 ii)Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结
构的存储 iii)Redis支持数据的备份,即master-slave模式的数据备份

1.1.2 Redis的用途

(1)内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
(2)取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
(3)模拟类似于HttpSession这种需要设定过期时间的功能
(4)发布、订阅消息系统
(5)定时器、计数器

1.1.3 下载链接

(1)Http://redis.io/
(2)Http://www.redis.cn/

1.1.4 怎么操作

(1)数据类型、基本操作和配置
(2)持久化和复制,RDB/AOF
(3)事务的控制
(4)复制

1.1.5 谁在使用

Redis 简介_第1张图片

 目前全球最大的 Redis 用户是新浪微博,在新浪有 200 多台物理机,400 多个端口正在运行着 Redis,有+4G 的数据跑在 Redis 上来为微博用户提供服务。

Redis 简介_第2张图片

 在新浪微博 Redis 的部署场景很多,大概分为如下的 2 种:
第一种是应用程序直接访问 Redis 数据库

Redis 简介_第3张图片

 第二种是应用程序直接访问 Redis,只有当 Redis 访问失败时才访问 MySQL!

Redis 简介_第4张图片

1.1.6 对比

Redis与其他数据库和软件的对比

一些数据库和缓存服务器的特性与功能

名称 类型 数据存储选项 附加功能
Redis 使用内存存储(in-memory)的非关系数据库 字符串、列表、集合、散列表、有序集合 发布与订阅,主从复制
(master/slavereplication),持久化,脚本(存储过程,storedprocedure)
memcached 使用内存存储的键值缓存 键值之间的映射 为提升性能而设的多线程服务器
MySQL 关系数据库 每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图(view);支持空间(spatial)和第三方扩展 支持ACID性质(需要使用
InnoDB),主从复制和主主复制(master/master
replication)
PostgreSQL 关系数据库 每个数据库可以包含多个表,每个表可以
包含多个行;可以处理多个表的视图;支持空间和第三方扩展;支持可定制类型
支持ACID性质,主从复制,由第三方支持的多主复制(multi-masterreplication)
MongoDB 使用硬盘存储(on-disk)的非关系文档存储 每个数据库可以包含多个表,每个表可以
包含多个无schema(schema-
less)的BSON文档
支持map-reduce操作,主从复制,分片,空间索(spatial index)

1.2 Redis安装

基于CentOS 7.9 x86-64 系统安装

1.2.1 rpm安装

配置epel的yum源

[root@localhost ~]# yum install
http://mirrors.163.com/centos/7.3.1611/extras/x86_64/Packages/epel-release-7-
9.noarch.rpm

在线yum安装

[root@localhost ~]# yum install redis #安装完毕目前是redis-3.2.3-1.el7.x86_64.rpm

安装最新版本使用remi:

[root@localhost ~]# yum install ftp://rpmfind.net/linux/remi/enterprise/7/remi/x86_64/redis-
4.0.1-1.el7.remi.x86_64.rpm

启动服务:

[root@localhost ~]# systemctl start redis
[root@localhost ~]# systemctl enable redis

验证测试:

[root@localhost ~]# netstat -lnupt | grep :6379
   tcp     0    0 127.0.0.1:6379      0.0.0.0:*       
LISTEN    11413/redis-server
   [root@localhost ~]# ps -ef | grep redis
   redis   11413    1  0 10:46 ?     00:00:03 /usr/bin/redis-server
127.0.0.1:6379
   [root@localhost ~]# lsof -i tcp:6379
   COMMAND   PID USER  FD  TYPE DEVICE SIZE/OFF NODE NAME
   redis-ser 11413 redis  6u IPv4  29352   0t0 TCP localhost:6379
(LISTEN)
   
  

 登录:

[root@localhost ~]# redis-cli
    127.0.0.1:6379> help
   redis-cli 4.0.1
   To get help about Redis commands type:
      "help @" to get a list of commands in 
      "help " for help on 
      "help " to get a list of possible help topics
      "quit" to exit
   To set redis-cli preferences:
      ":set hints" enable online hints
      ":set nohints" disable online hints
   Set your preferences in ~/.redisclirc
    127.0.0.1:6379> quit

1.2.2 源码安装

下载:

[root@localhost ~]# curl -O
http://download.redis.io/releases/redis-4.0.1.tar.gz

解压:

[root@localhost ~]# tar xf redis-4.0.1.tar.gz -C /usr/local/src/

 安装:

[root@localhost ~]# cd /usr/local/src/redis-4.0.1/
[root@localhost redis-4.0.1]# yum install gcc gcc-c++ make -y
[root@localhost redis-4.0.1]# make
[root@localhost redis-4.0.1]# make install

启动:
    

[root@localhost redis-4.0.1]# mkdir -p /etc/redis
[root@localhost redis-4.0.1]# cp redis.conf /etc/redis
[root@localhost redis-4.0.1]# cd
[root@localhost ~]# sed -i.bak 's/daemonize no/daemonize yes/'
/etc/redis/redis.conf
[root@localhost ~]# redis-server /etc/redis/redis.conf
      5448:C 12 Aug 11:54:21.743 # oO0OoO0OoO0Oo Redis is starting
oO0OoO0OoO0Oo
      5448:C 12 Aug 11:54:21.743 # Redis version=4.0.1, bits=64,
commit=00000000, modified=0, pid=5448, just started
      5448:C 12 Aug 11:54:21.743 # Configuration loaded

登录:

[root@localhost ~]# redis-cli
      127.0.0.1:6379> ping
     PONG
      127.0.0.1:6379> quit

1.2.3 Redis命令行客户端

发送命令:

redis-cli -h 127.0.0.1 -p 6379
     redis-cli PING
     redis-cli

命令返回值

状态回复,e.g. >PING
     错误恢复, e.g. >ECMD
     整数回复, e.g. >INCR foo
     字符串回复,e.g. >GET foo  >GET notexists`
     多行字符串回复,e.g. >KEYS *

源码配置服务脚本:
  1.2.3.1 创建用户和组

[root@localhost ~]# groupadd -g 935 -r redis
[root@localhost ~]# useradd -u 935 -g 935 -r -d /var/lib/redis -c “redis server” -s /sbin/nologin redis
[root@localhost ~]# mkdir -p /var/lib/redis
[root@localhost ~]# chown -R redis /var/lib/redis
[root@localhost ~]# chmod -R 700 /var/lib/redis

1.2.3.2 修改配置文件/etc/redis/redis.conf  

[root@localhost ~]#  vim /etc/redis/redis.conf
dir /var/lib/redis/
daemonize no

1.2.3.3 创建服务脚本

  [root@localhost ~]# vim /usr/lib/systemd/system/redis.service
     [Unit]
      Description=Redis persistent key-value database
      After=network.target
     [Service]
      ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf --
daemonize no
      ExecStop=/usr/bin/kill -9 `pidof redis-server`
      User=redis
      Group=redis
      RuntimeDirectory=redis
      RuntimeDirectoryMode=0755
     [Install]
      WantedBy=multi-user.target
[root@localhost ~]# systemctl daemon-reload

1.2.3.4 测试脚本

[root@localhost ~]# systemctl stop redis
[root@localhost ~]# ps -ef | grep redis
     root    14888  5517  0 10:36 pts/1   00:00:00 grep --color=auto
redis
[root@localhost ~]# systemctl start redis
[root@localhost ~]# ps -ef | grep redis
     redis   14895    1  0 10:37 ?     00:00:00
/usr/local/bin/redis-server 127.0.0.1:6379

windows 下安装:

windows下载安装 :Releases · microsoftarchive/redis · GitHub

安装:

打开cmd命令窗口,使用命令进行安装和注册redis到window服务
安装命令:redis-server.exe --service-install redis.windows.conf --loglevel verbose
启动服务命令:redis-server.exe  --service-start
关闭服务命令:redis-server.exe  --service-stop

1.3 Redis 配置

 redis已经运行,但要获得好的性能,还需要对配置文件进行合理的配置
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程  
 daemonize no
2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过
pidfile指定  
 pidfile /var/run/redis.pid
3. 指定Redis监听端口,默认端口为6379,为什么选用6379作为默认端口,因为6379在手机按键上MERZ对
应的号码,而MERZ取自意大利歌女Alessia Merz的名字  
 port 6379
4. 绑定的主机地址  
 bind 127.0.0.1
5. 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能  
 timeout 300
6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为
verbose  
 loglevel verbose
7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为
标准输出,则日志将会发送给/dev/null
 logfile stdout
8. 设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id
 databases 16
9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
 save   
 Redis默认配置文件中提供了三个条件:  
 save 900 1  
 save 300 10  
 save 60 10000  
 分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可
以关闭该选项,但会导致数据库文件变的巨大  
 rdbcompression yes
11. 指定本地数据库文件名,默认值为dump.rdb  
 dbfilename dump.rdb
12. 指定本地数据库存放目录   dir ./
13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进
行数据同步  
 slaveof
14. 当master服务设置了密码保护时,slav服务连接master的密码  
 masterauth
15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH 命令
提供密码,默认关闭  
 requirepass foobared

16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打
开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会
关闭新的连接并向客户端返回max number of clients reached错误信息   maxclients 128
17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清
除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以
进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区  
 maxmemory
18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,
可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所
以有的数据会在一段时间内只存在于内存中。默认为no  
 appendonly no
19. 指定更新日志文件名,默认为appendonly.aof   
 appendfilename appendonly.aof
20. 指定更新日志条件,共有3个可选值:
 no:表示等操作系统进行数据缓存同步到磁盘(快)
 always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
 everysec:表示每秒同步一次(折衷,默认值)  
 appendfsync everysec
21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问
量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析
Redis的VM机制)   
 vm-enabled no
22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享   
vm-swap-file /tmp/redis.swap
23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内
存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value
都存在于磁盘。默认值为0    vm-max-memory 0
24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个
对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最
好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认
值    vm-page-size 32
25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,
在磁盘上每8个pages将消耗1byte的内存。    vm-pages 134217728
26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是
串行的,可能会造成比较长时间的延迟。默认值为4    vm-max-threads 4
27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启   glueoutputbuf yes
28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法  
 hash-max-zipmap-entries 64  
 hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默认为开启   activerehashing yes
30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例
又拥有自己的特定配置文件   include /path/to/local.conf

 1.4 Redis的数据类型

1.4.1 string类型及操作

一、概述:

 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。  

二、相关命令列表:

命令原型

时间

复杂

命令描述  返回值
APPEND
key value
O(1) 如果该Key已经存在,APPEND命令将参数Value的数据追
加到已存在Value的末尾。如果该Key不存在,APPEND命
令将会创建一个新的Key/Value。
追加后
Value的
长度。
DECR key  O(1) 将指定Key的Value原子性的递减1。如果该Key不存在,
其初始值为0,在decr之后其值为-1。如果Value的值不能
转换为整型值,如Hello,该操作将执行失败并返回相应
的错误信息。注意:该操作的取值范围是64位有符号整
型。
递减后的
Value
值。
INCR key  O(1) 将指定Key的Value原子性的递增1。如果该Key不存在,
其初始值为0,在incr之后其值为1。如果Value的值不能
转换为整型值,如Hello,该操作将执行失败并返回相应
的错误信息。注意:该操作的取值范围是64位有符号整
型。
递增后的
Value
值。
DECRBY
key
decrement
O(1) 将指定Key的Value原子性的减少decrement。如果该Key
不存在, 其初始值为0,在decrby之后其值为-
decrement。如果Value的值不能转换为整型值,如
Hello,该操作将执行失败并返回相应的错误信 息。注
意:该操作的取值范围是64位有符号整型。
减少后的
Value
值。
INCRBY
key
increment
O(1) 将指定Key的Value原子性的增加increment。如果该Key
不存在, 其初始值为0,在incrby之后其值为
increment。如果Value的值不能转换为整型值,如
Hello,该操作将执行失败并返回相应的错误信 息。注
意:该操作的取值范围是64位有符号整型。
增加后的
Value
值。
GET key O(1) 获取指定Key的Value。如果与该Key关联的Value不是
string类型,Redis将返回错误信息,因为GET命令只能用
于获取string Value。
与该Key
相关的
Value,
如果该
Key不存
在,返回
nil。
SET key
value
O(1) 设定该Key持有指定的字符串Value,如果该Key已经存
在,则覆盖其原有值。
总是返
回"OK"。
GETSET
key value
O(1) 原子性的设置该Key为指定的Value,同时返回该Key的原
有值。和GET命令一样,该命令也只能处理string Value,
否则Redis将给出相关的错误信息。
返回该
Key的原
有值,如
果该Key
之前并不
存在,则
返回nil。
STRLEN
key
O(1) 返回指定Key的字符值长度,如果Value不是string类型,
Redis将执行失败并给出相关的错误信息。
返回指定
Key的
Value字
符长度,
如果该
Key不存
在,返回
0。
SETEX key
seconds
value
O(1) 原子性完成两个操作,一是设置该Key的值为指定字符
串,同时设置该Key在Redis服务器中的存活时间(秒数)。
该命令主要应用于Redis被当做Cache服务器使用时。
SETNX key
value
O(1) 如果指定的Key不存在,则设定该Key持有指定字符串
Value,此时其效果等价于SET命令。相反,如果该Key已
经存在,该命令将不做任何操作并返回。
1表示设
置成功,
否则0。
SETRANGE
key offset
value
O(1) 替换指定Key的部分字符串值。从offset开始,替换的长度
为该命令第三个参 数value的字符串长度,其中如果
offset的值大于该Key的原有值Value的字符串长度,
Redis将会在Value的后面补齐(offset - strlen(value))数量
的0x00,之后再追加新值。如果该键不存在,该命令会将
其原值的长度假设为0,并在其后添补offset个0x00后 再
追加新值。鉴于字符串Value的最大长度为512M,因此
offset的最大值为536870911。最后需要注意的是,如果
该命令在执行时致使指定 Key的原有值长度增加,这将会
导致Redis重新分配足够的内存以容纳替换后的全部字符
串,因此就会带来一定的性能折损。
修改后的
字符串
Value长
度。
GETRANGE
key start
end
O(1) 如果截取的字符串长度很短,我们可以该命令的时间复杂
度视为O(1),否则就是O(N),这里N表示截取的子字符串
长度。该命令在截取子字符串时,将以闭区间的方式同时
包含start(0表示第一个字符)和end所在的字符,如果end
值超过Value的字符长度,该命令将只是截取从start开始
之后所有的字符数据。
子字符串
SETBIT key
offset
value
O(1) 设置在指定Offset上BIT的值,该值只能为1或0,在设定
后该命令返回该 Offset上原有的BIT值。如果指定Key不存
在,该命令将创建一个新值,并在指定的Offset上设定参
数中的BIT值。如果Offset大于 Value的字符长度,Redis
将拉长Value值并在指定Offset上设置参数中的BIT值,中
间添加的BIT值为0。最后需要说明的是 Offset值必须大于
0。
在指定
Offset上
的BIT原
有值。
GETBIT
key offset
O(1) 返回在指定Offset上BIT的值,0或1。如果Offset超过
string value的长度,该命令将返回0,所以对于空字符串
始终返回0。
在指定
Offset上
的BIT
值。
MGET key
[key ...]
O(1) N表示获取Key的数量。返回所有指定Keys的Values,如
果其中某个Key不存在,或者其值不为string类型,该Key
的Value将返回nil
返回一组
指定Keys
的Values
的列表。
MSET key
value [key
value ...]
O(N) N表示指定Key的数量。该命令原子性的完成参数中所有
key/value的设置操作,其具体行为可以看成是多次迭代
执行SET命令。
该命令不
会失败,
始终返回
OK。
MSETNX
key value
[key value
...]
O(N) N表示指定Key的数量。该命令原子性的完成参数中所有
key/value的设置操作,其具体行为可以看成是多次迭代
执行SETNX命令。然而这里需要明确说明的是,如果在这
一批Keys中有任意一个Key已经存在了,那么该操作将全
部回滚,即所有的修改都不会生效。
1表示所
有Keys都
设置成
功,0则
表示没有
任何Key
被修改。

三、命令示例:

 SET/GET/APPEND/STRLEN:

/> redis-cli  #执行Redis客户端工具。

#判断该键是否存在,存在返回1,否则返回0。
redis 127.0.0.1:6379>exists mykey 
(integer) 0

#该键并不存在,因此append命令返回当前Value的长度。
redis 127.0.0.1:6379> append mykey "hello"
(integer) 5

#该键已经存在,因此返回追加后Value的长度。
redis 127.0.0.1:6379>append mykey " world"
(integer) 11

#通过get命令获取该键,以判断append的结果。
redis 127.0.0.1:6379>get mykey 
"hello world"

#通过set命令为键设置新值,并覆盖原有值。
redis 127.0.0.1:6379>set mykey "this is a test"
OK
redis 127.0.0.1:6379>get mykey
"this is a test"

#获取指定Key的字符长度,等效于C库中strlen函数。
redis 127.0.0.1:6379>strlen mykey 
(integer) 14

 INCR/DECR/INCRBY/DECRBY: 

#设置Key的值为20
redis 127.0.0.1:6379>set mykey 20
OK

#该Key的值递增1
redis 127.0.0.1:6379>incr mykey
(integer) 21

#该Key的值递减1
redis 127.0.0.1:6379>decr mykey
(integer) 20

#删除已有键。
redis 127.0.0.1:6379>del mykey 
(integer) 1

#对空值执行递减操作,其原值被设定为0,递减后的值为-1
redis 127.0.0.1:6379>decr mykey
(integer) -1
redis 127.0.0.1:6379>del mykey 
(integer) 1

#对空值执行递增操作,其原值被设定为0,递增后的值为1
redis 127.0.0.1:6379> incr mykey
(integer) 1

#将该键的Value设置为不能转换为整型的普通字符串。
redis 127.0.0.1:6379>set mykey hello
OK

#在该键上再次执行递增操作时,Redis将报告错误信息。
redis 127.0.0.1:6379>incr mykey
(error) ERR value is not an integer or out of range
redis 127.0.0.1:6379>set mykey 10
OK
redis 127.0.0.1:6379>decrby mykey 5
(integer) 5
redis 127.0.0.1:6379>incrby mykey 10
(integer) 15

GETSET: 

#将计数器的值原子性的递增1
redis 127.0.0.1:6379>incr mycounter
(integer) 1

#在取计数器原有值的同时,并将其设置为新值,这两个操作原子性的同时完成。
redis 127.0.0.1:6379>getset mycounter 0
"1"

#查看设置后的结果。
redis 127.0.0.1:6379>get mycounter
"0"

SETEX: 

#设置指定Key的过期时间为10秒。
redis 127.0.0.1:6379>setex mykey 10 "hello" 
OK

#通过ttl命令查看一下指定Key的剩余存活时间(秒数),0表示已经过期,-1表示永不过期。
redis 127.0.0.1:6379>ttl mykey
(integer) 4

#在该键的存活期内我们仍然可以获取到它的Value。
redis 127.0.0.1:6379>get mykey
"hello"

#该ttl命令的返回值显示,该Key已经过期。
redis 127.0.0.1:6379>ttl mykey
(integer) 0

#获取已过期的Key将返回nil。
redis 127.0.0.1:6379>get mykey
(nil)

SETNX: 

#删除该键,以便于下面的测试验证。
redis 127.0.0.1:6379>del mykey
(integer) 1

#该键并不存在,因此该命令执行成功。
redis 127.0.0.1:6379>setnx mykey "hello"
(integer) 1

#该键已经存在,因此本次设置没有产生任何效果。
redis 127.0.0.1:6379>setnx mykey "world"
(integer) 0

#从结果可以看出,返回的值仍为第一次设置的值。
redis 127.0.0.1:6379>get mykey
"hello"

SETRANGE/GETRANGE: 

#设定初始值。
redis 127.0.0.1:6379>set mykey "hello world"
OK

#从第六个字节开始替换2个字节(dd只有2个字节)
redis 127.0.0.1:6379>setrange mykey 6 dd 
(integer) 11

#查看替换后的值。
redis 127.0.0.1:6379>get mykey
"hello ddrld"

#offset已经超过该Key原有值的长度了,该命令将会在末尾补0。
redis 127.0.0.1:6379>setrange mykey 20 dd
(integer) 22

#查看补0后替换的结果。
redis 127.0.0.1:6379>get mykey
"hello ddrld\x00\x00\x00\x00\x00\x00\x00\x00\x00dd"

#删除该Key。
redis 127.0.0.1:6379>del mykey
(integer) 1

#替换空值。
redis 127.0.0.1:6379>setrange mykey 2 dd
(integer) 4

#查看替换空值后的结果。
redis 127.0.0.1:6379>get mykey
"\x00\x00dd" 

#设置新值。
redis 127.0.0.1:6379>set mykey "0123456789" 
OK

#截取该键的Value,从第一个字节开始,到第二个字节结束。
redis 127.0.0.1:6379>getrange mykey 1 2
"12"

#20已经超过Value的总长度,因此将截取第一个字节后面的所有字节。
redis 127.0.0.1:6379>getrange mykey 1 20 
"123456789"

SETBIT/GETBIT:

redis 127.0.0.1:6379>del mykey
(integer) 1

#设置从0开始计算的第七位BIT值为1,返回原有BIT值0
redis 127.0.0.1:6379> setbit mykey 7 1 
(integer) 0

#获取设置的结果,二进制的0000 0001的十六进制值为0x01
redis 127.0.0.1:6379>get mykey
"\x01"

#设置从0开始计算的第六位BIT值为1,返回原有BIT值0
redis 127.0.0.1:6379>setbit mykey 6 1 
(integer) 0

#获取设置的结果,二进制的0000 0011的十六进制值为0x03
redis 127.0.0.1:6379>get mykey
"\x03"

#返回了指定Offset的BIT值。
redis 127.0.0.1:6379>getbit mykey 6
(integer) 1

#Offset已经超出了value的长度,因此返回0。
redis 127.0.0.1:6379>getbit mykey 10
(integer) 0

 MSET/MGET/MSETNX:

#批量设置了key1和key2两个键。
redis 127.0.0.1:6379>mset key1 "hello" key2 "world" 
OK

#批量获取了key1和key2两个键的值。
redis 127.0.0.1:6379>mget key1 key2
1) "hello"
2) "world"

#批量设置了key3和key4两个键,因为之前他们并不存在,所以该命令执行成功并返回1。
redis 127.0.0.1:6379>msetnx key3 "stephen" key4 "liu"
(integer) 1
redis 127.0.0.1:6379>mget key3 key4
1) "stephen"
2) "liu"

#批量设置了key3和key5两个键,但是key3已经存在,所以该命令执行失败并返回0。
redis 127.0.0.1:6379>msetnx key3 "hello" key5 "world"
(integer) 0

#批量获取key3和key5,由于key5没有设置成功,所以返回nil。
redis 127.0.0.1:6379>mget key3 key5
1) "stephen"
2) (nil)

1.4.2 hash类型及操作

一、概述:

       我们可以将Redis中的Hashes类型看成具有String Key和String Value的map容器。所以该类型非常适合于存储值对象的信息。如Username、Password和Age等。如果Hash中包含很少的字段,那么 该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储4294967295个键值对。

二、相关命令列表:

命令原型 时间复杂度 命令描述 返回值
HSET key
field value
O(1) 为指定的Key设定Field/Value对,如果Key不存
在,该命令将创建新Key以参数中的Field/Value
对,如果参数中的Field在该Key中已经存在,则用
新值覆盖其原有值。
1表示新的Field
被设置了新值,
0表示Field已经
存在,用新值覆
盖原有值。
HGET key
field
O(1) 返回指定Key中指定Field的关联值。 返回参数中Field
的关联值,如果
参数中的Key或
Field不存,返回
nil。
HEXISTS
key field
O(1) 判断指定Key中的指定Field是否存在。 1表示存在,0表
示参数中的Field
或Key不存在
HLEN key  O(1) 获取该Key所包含的Field的数量。 返回Key包含的
Field数量,如果
Key不存在,返
回0。
HDEL key
field [field
...]
O(1) 时间复杂度中的N表示参数中待删除的字段数量。
从指定Key的Hashes Value中删除参数中指定的多
个字段,如果不存在的字段将被忽略。如果Key不
存在,则将其视为空Hashes,并返回0.
实际删除的Field
数量。
HSETNX
key field
value
O(1) 只有当参数中的Key或Field不存在的情况下,为指
定的Key设定Field/Value对,否则该命令不会进行
任何操作
1表示新的Field
被设置了新值,
0表示Key或Field
已经存在,该命
令没有进行任何
操作。
HINCRBY
key field
increment
O(1) 增加指定Key中指定Field关联的Value的值。如果
Key或Field不存在,该命令将会创建一个新Key或
新Field,并将其关联的Value初始化为0,之后再指
定数字增加的操作。该命令支持的数字是64位有符
号整型,即increment可以负数。
返回运算后的
值。
HGETALL
key
O(N) 时间复杂度中的N表示Key包含的Field数量。获取
该键包含的所有Field/Value。其返回格式为一个
Field、一个Value,并以此类推。
Field/Value的列
HKEYS
key
O(N) 时间复杂度中的N表示Key包含的Field数量。返回
指定Key的所有Fields名。
Field的列表
HVALS
key
O(N) 时间复杂度中的N表示Key包含的Field数量。返回
指定Key的所有Values名
Value的列表
HMGET
key field
[field ...]
O(N) 时间复杂度中的N表示请求的Field数量。获取和参
数中指定Fields关联的一组Values。如果请求的
Field不存在,其值返回nil。如果Key不存在,该命
令将其视为空Hash,因此返回一组nil。
返回和请求
Fields关联的一
组Values,其返
回顺序等同于
Fields的请求顺
序。
HMSET
key field
value
[field
value ...]
O(N) 时间复杂度中的N表示被设置的Field数量。逐对依
次设置参数中给出的Field/Value对。如果其中某个
Field已经存在,则用新值覆盖原有值。如果Key不
存在,则创建新Key,同时设定参数中的
Field/Value。

三、命令示例:

1. HSET/HGET/HDEL/HEXISTS/HLEN/HSETNX:

#在Shell命令行启动Redis客户端程序
/>redis-cli

#给键值为myhash的键设置字段为field1,值为stephen。
redis 127.0.0.1:6379>hset myhash field1 "stephen"
(integer) 1

#获取键值为myhash,字段为field1的值。
redis 127.0.0.1:6379>hget myhash field1
"stephen"

#myhash键中不存在field2字段,因此返回nil。
redis 127.0.0.1:6379>hget myhash field2
(nil)

#给myhash关联的Hashes值添加一个新的字段field2,其值为liu。
redis 127.0.0.1:6379>hset myhash field2 "liu"
(integer) 1

#获取myhash键的字段数量。
redis 127.0.0.1:6379>hlen myhash
(integer) 2

#判断myhash键中是否存在字段名为field1的字段,由于存在,返回值为1。
redis 127.0.0.1:6379>hexists myhash field1
(integer) 1

#删除myhash键中字段名为field1的字段,删除成功返回1。
redis 127.0.0.1:6379>hdel myhash field1
(integer) 1

#再次删除myhash键中字段名为field1的字段,由于上一条命令已经将其删除,因为没有删除,返回0。
redis 127.0.0.1:6379>hdel myhash field1
(integer) 0

#判断myhash键中是否存在field1字段,由于上一条命令已经将其删除,因为返回0。
redis 127.0.0.1:6379>hexists myhash field1
(integer) 0

#通过hsetnx命令给myhash添加新字段field1,其值为stephen,因为该字段已经被删除,所以该命令添
加成功并返回1。
redis 127.0.0.1:6379>hsetnx myhash field1 stephen
(integer) 1

#由于myhash的field1字段已经通过上一条命令添加成功,因为本条命令不做任何操作后返回0。
redis 127.0.0.1:6379>hsetnx myhash field1 stephen
(integer) 0

2. HINCRBY:

#删除该键,便于后面示例的测试。
redis 127.0.0.1:6379>del myhash
(integer) 1

#准备测试数据,该myhash的field字段设定值1。
redis 127.0.0.1:6379>hset myhash field 5
(integer) 1

#给myhash的field字段的值加1,返回加后的结果。
redis 127.0.0.1:6379>hincrby myhash field 1
(integer) 6

#给myhash的field字段的值加-1,返回加后的结果。
redis 127.0.0.1:6379>hincrby myhash field -1
(integer) 5

#给myhash的field字段的值加-10,返回加后的结果。
redis 127.0.0.1:6379>hincrby myhash field -10
(integer) -5 

3. HGETALL/HKEYS/HVALS/HMGET/HMSET:

#删除该键,便于后面示例测试。
redis 127.0.0.1:6379>del myhash
(integer) 1

#为该键myhash,一次性设置多个字段,分别是field1 = "hello", field2 = "world"。
redis 127.0.0.1:6379>hmset myhash field1 "hello" field2 "world"
OK

#获取myhash键的多个字段,其中field3并不存在,因为在返回结果中与该字段对应的值为nil。
redis 127.0.0.1:6379>hmget myhash field1 field2 field3
1) "hello"
2) "world"
3) (nil)

#返回myhash键的所有字段及其值,从结果中可以看出,他们是逐对列出的。
redis 127.0.0.1:6379>hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"

#仅获取myhash键中所有字段的名字。
redis 127.0.0.1:6379>hkeys myhash
1) "field1"
2) "field2"

#仅获取myhash键中所有字段的值。
redis 127.0.0.1:6379> hvals myhash
1) "hello"
2) "world"

1.4.3 list 类型及操作

一、概述:

       在Redis中,List类型是的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的 元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。 List中可以包含的最大元素数量是4294967295。

       从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量 时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。相信对于有良好数据结构基础的开发者而言,这一点并不难理 解。

二、相关命令列表:

命令原型 时间复
杂度
命令描述  返回值
LPUSH key
value [value ...]
O(1) 在指定Key所关联的List Value的头部插入参数中给
出的所有Values。如果该Key不存在,该命令将在插
入之前创建一个与该Key关联的空链表,之后再将数
据从链表的头部插入。如果该键的Value不是链表类
型,该命令将返回相关的错误信息。
插入后
链表中
元素的
数量。
LPUSHX key
value
O(1) 仅有当参数中指定的Key存在时,该命令才会在其所
关联的List Value的头部插入参数中给出的Value,否
则将不会有任何操作发生。
插入后
链表中
元素的
数量。
LRANGE key
start stop
O(S+N) 时间复杂度中的S为start参数表示的偏移量,N表示
元素的数量。该命令的参数 start和end都是0-
based。即0表示链表头部(leftmost)的第一个元素。
其中start的值也可以为负值,-1将表示链表中的最后
一 个元素,即尾部元素,-2表示倒数第二个并以此
类推。该命令在获取元素时,start和end位置上的元
素也会被取出。如果start的值大于链表中元素 的数
量,空链表将会被返回。如果end的值大于元素的数
量,该命令则获取从start(包括start)开始,链表中剩
余的所有元素。
返回指
定范围
内元素
的列
表。
LPOP key  O(1) 返回并弹出指定Key关联的链表中的第一个元素,即
头部元素,。如果该Key不存,返回nil。
链表头
部的元
素。
LLEN key  O(1) 返回指定Key关联的链表中元素的数量,如果该Key
不存在,则返回0。如果与该Key关联的Value的类型
不是链表,则返回相关的错误信息。
链表中
元素的
数量。
LREM key
count value
O(N) 时间复杂度中N表示链表中元素的数量。在指定Key
关联的链表中,删除前 count个值等于value的元
素。如果count大于0,从头向尾遍历并删除,如果
count小于0,则从尾向头遍历并删除。如果count等
于0, 则删除链表中所有等于value的元素。如果指
定的Key不存在,则直接返回0。
返回被
删除的
元素数
量。
LSET key index
value
O(N) 时间复杂度中N表示链表中元素的数量。但是设定头
部或尾部的元素时,其时间复杂度为O(1)。设定链表
中指定位置的值为新值,其中0表示第一个元素,即
头部元素,-1表示尾部元素。如果索引值Index超出
了链表中元素的数量范围,该命令将返回相关的错误
信息。
LINDEX key
index
O(N) 时间复杂度中N表示在找到该元素时需要遍历的元素
数量。对于头部或尾部元素,其时 间复杂度为
O(1)。该命令将返回链表中指定位置(index)的元
素,index是0-based,表示头部元素,如果index
为-1,表示尾部元 素。如果与该Key关联的不是链
表,该命令将返回相关的错误信息。
返回请
求的元
素,如

index
超出范
围,则
返回
nil。
LTRIM key start
stop
O(N) N表示被删除的元素数量。该命令将仅保留指定范围
内的元素,从而保证链接中的元素 数量相对恒定。
start和stop参数都是0-based,0表示头部元素。和
其他命令一样,start和stop也可以为负值,-1表示
尾部元素。如 果start大于链表的尾部,或start大于
stop,该命令不错报错,而是返回一个空的链表,与
此同时该Key也将被删除。如果stop大于元素的数
量,则保留从start开始剩余的所有元素。
LINSERT key
BEFORE|AFTER
pivot value
O(N) 时间复杂度中N表示在找到该元素pivot之前需要遍历
的元素数量。这样意味着如 果pivot位于链表的头部
或尾部时,该命令的时间复杂度为O(1)。该命令的功
能是在pivot元素的前面或后面插入参数中的元素
value。如果 Key不存在,该命令将不执行任何操
作。如果与Key关联的Value类型不是链表,相关的
错误信息将被返回。
成功插
入后链
表中元
素的数
量,如
果没有
找到
pivot,

回-1,
如果
key不
存在,
返回
0。
RPUSH key
value [value ...]
O(1) 在指定Key所关联的List Value的尾部插入参数中给
出的所有Values。如果该Key不存在,该命令将在插
入之前创建一个与该Key关联的空链表,之后再将数
据从链表的尾部插入。如果该键的Value不是链表类
型,该命令将返回相关的错误信息。
插入后
链表中
元素的
数量。
RPUSHX key
value
O(1) 仅有当参数中指定的Key存在时,该命令才会在其所
关联的List Value的尾部插入参数中给出的Value,否
则将不会有任何操作发生。
插入后
链表中
元素的
数量。
RPOP key  O(1) 返回并弹出指定Key关联的链表中的最后一个元素,
即尾部元素,。如果该Key不存,返回nil。
链表尾
部的元
素。
RPOPLPUSH
source
destination
O(1) 原子性的从与source键关联的链表尾部弹出一个元
素,同时再将弹出的元素插入 到与destination键关
联的链表的头部。如果source键不存在,该命令将
返回nil,同时不再做任何其它的操作了。如果
source和 destination是同一个键,则相当于原子性
的将其关联链表中的尾部元素移到该链表的头部。
返回弹
出和插
入的元
素。

三、命令示例:

1. LPUSH/LPUSHX/LRANGE:

#在Shell提示符下启动redis客户端工具。
/>redis-cli
redis 127.0.0.1:6379>del mykey
(integer) 1

#mykey键并不存在,该命令会创建该键及与其关联的List,之后在将参数中的values从左到右依次插入。
redis 127.0.0.1:6379>lpush mykey a b c d
(integer) 4

#取从位置0开始到位置2结束的3个元素。
redis 127.0.0.1:6379> lrange mykey 0 2
1) "d"
2) "c"
3) "b"

#取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "d"
2) "c"
3) "b"
4) "a"

#mykey2键此时并不存在,因此该命令将不会进行任何操作,其返回值为0。
redis 127.0.0.1:6379> lpushx mykey2 e
(integer) 0

#可以看到mykey2没有关联任何List Value。
redis 127.0.0.1:6379>lrange mykey2 0 -1
(empty list or set)

#mykey键此时已经存在,所以该命令插入成功,并返回链表中当前元素的数量。
redis 127.0.0.1:6379> lpushx mykey e
(integer) 5

#获取该键的List Value的头部元素。
redis 127.0.0.1:6379> lrange mykey 0 0
1) "e"

2. LPOP/LLEN:

redis 127.0.0.1:6379>lpush mykey a b c d
(integer) 4
redis 127.0.0.1:6379>lpop mykey
"d"
redis 127.0.0.1:6379>lpop mykey
"c"

#在执行lpop命令两次后,链表头部的两个元素已经被弹出,此时链表中元素的数量是2
redis 127.0.0.1:6379>llen mykey
(integer) 2

3. LREM/LSET/LINDEX/LTRIM:

#为后面的示例准备测试数据。
redis 127.0.0.1:6379>lpush mykey a b c d a c
(integer) 6

#从头部(left)向尾部(right)变量链表,删除2个值等于a的元素,返回值为实际删除的数量。
redis 127.0.0.1:6379> lrem mykey 2 a
(integer) 2

#看出删除后链表中的全部元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "c"
2) "d"
3) "c"
4) "b"

#获取索引值为1(头部的第二个元素)的元素值。
redis 127.0.0.1:6379> lindex mykey 1
"d"

#将索引值为1(头部的第二个元素)的元素值设置为新值e。
redis 127.0.0.1:6379> lset mykey 1 e
OK

#查看是否设置成功。
redis 127.0.0.1:6379> lindex mykey 1
"e"

#索引值6超过了链表中元素的数量,该命令返回nil。
redis 127.0.0.1:6379> lindex mykey 6
(nil)

#设置的索引值6超过了链表中元素的数量,设置失败,该命令返回错误信息。
redis 127.0.0.1:6379>lset mykey 6 hh
(error) ERR index out of range

#仅保留索引值0到2之间的3个元素,注意第0个和第2个元素均被保留。
redis 127.0.0.1:6379> ltrim mykey 0 2
OK

#查看trim后的结果。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "c"
2) "e"
3) "c"

4. LINSERT:

#删除该键便于后面的测试。
redis 127.0.0.1:6379> del mykey
(integer) 1

#为后面的示例准备测试数据。
redis 127.0.0.1:6379>lpush mykey a b c d e
(integer) 5

#在a的前面插入新元素a1。
redis 127.0.0.1:6379> linsert mykey before a a1
(integer) 6

#查看是否插入成功,从结果看已经插入。注意lindex的index值是0-based。
redis 127.0.0.1:6379>lindex mykey 0
"e"

#在e的后面插入新元素e2,从返回结果看已经插入成功。
redis 127.0.0.1:6379> linsert mykey after e e2
(integer) 7

#再次查看是否插入成功。
redis 127.0.0.1:6379> lindex mykey 1
"e2"

#在不存在的元素之前或之后插入新元素,该命令操作失败,并返回-1。
redis 127.0.0.1:6379>linsert mykey after k a
(integer) -1

#为不存在的Key插入新元素,该命令操作失败,返回0。
redis 127.0.0.1:6379> linsert mykey1 after a a2
(integer) 0

5. RPUSH/RPUSHX/RPOP/RPOPLPUSH:

#删除该键,以便于后面的测试。
redis 127.0.0.1:6379> del mykey
(integer) 1

#从链表的尾部插入参数中给出的values,插入顺序是从左到右依次插入。
redis 127.0.0.1:6379>rpush mykey a b c d
(integer) 4

#通过lrange的可以获悉rpush在插入多值时的插入顺序。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "a"

1.4.4 Set 类型及操作

一、概述:

       在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存 在等操作。需要说明的是,这些操作的时间复杂度为O(1),即常量时间内完成次操作。Set可包含的最大元素数量是4294967295。和List类型不同的是,这一点和C++标准库中的set容器是完全相同的。换句话说,如果多次添加相同元素,Set 中将仅保留该元素的一份拷贝。和List类型相比,Set类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计算操作,如 unions、intersections和differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销。

  • 无序性:集合里面数据是没顺序区分。
  • 确定性:集合里面数据个数是确定的。
  • 唯一性:集合里面数据不能彼此重复。

 二、相关命令列表

命令原型 时间复
杂度
命令描述  返回值
SADD key
member
[member ...]
O(N) 时间复杂度中的N表示操作的成员数量。如果在插
入的过程用,参数中有的成员在 Set中已经存在,
该成员将被忽略,而其它成员仍将会被正常插入。
如果执行该命令之前,该Key并不存在,该命令将
会创建一个新的Set,此后再将参数中 的成员陆续
插入。如果该Key的Value不是Set类型,该命令将
返回相关的错误信息。
本次操
作实际
插入的
成员数
量。
SCARD key  O(1)  获取Set中成员的数量。 返回
Set中
成员的
数量,
如果该
Key并
不存
在,返
回0。
SISMEMBER key
member
O(1) 判断参数中指定成员是否已经存在于与Key相关联
的Set集合中
1表示
已经存
在,0
表示不
存在,
或该
Key本
身并不
存在。
SMEMBERS key O(N) 时间复杂度中的N表示Set中已经存在的成员数量。
获取与该Key关联的Set中所有的成员。
返回
Set中
所有的
成员。
SPOP key  O(1) 随机的移除并返回Set中的某一成员。 由于Set中元
素的布局不受外部控制,因此无法像List那样确定哪
个元素位于Set的头部或者尾部。
返回移
除的成
员,如
果该
Key并
不存
在,则
返回
nil。
SREM key
member
[member ...]
O(N) 时间复杂度中的N表示被删除的成员数量。从与Key
关联的Set中删除参数中指定的成员,不存在的参数
成员将被忽略,如果该Key并不存在,将视为空Set
处理。
从Set
中实际
移除的
成员数
量,如
果没有
则返回
0。
SRANDMEMBER
key
O(1) 和SPOP一样,随机的返回Set中的一个成员,不同
的是该命令并不会删除返回的成员。
返回随
机位置
的成
员,如
果Key
不存在
则返回
nil。
SMOVE source
destination
member
O(1) 原子性的将参数中的成员从source键移入到
destination键所关联的 Set中。因此在某一时刻,
该成员或者出现在source中,或者出现在
destination中。如果该成员在source中并不存在,
该命令将不会再 执行任何操作并返回0,否则,该
成员将从source移入到destination。如果此时该成
员已经在destination中存在,那么该命令仅是 将该
成员从source中移出。如果和Key关联的Value不是
Set,将返回相关的错误信息。
1表示
正常移
动,0
表示
source
中并不
包含参
数成
员。
SDIFF key [key
...]
O(N) 时间复杂度中的N表示所有Sets中成员的总数量。
返回参数中第一个Key所关联的Set和其后所有Keys
所关联的Sets中成员的差异。如果Key不存在,则
视为空Set。
差异结
果成员
的集
合。
SDIFFSTORE
destination key
[key ...]
O(N) 该命令和SDIFF命令在功能上完全相同,两者之间唯
一的差别是SDIFF返回差异的结果成员,而该命令将
差异成员存储在destination关联的Set中。如果
destination键已经存在,该操作将覆盖它的成员。
返回差
异成员
的数
量。
SINTER key [key
...]
O(N*M) 时间复杂度中的N表示最小Set中元素的数量,M则
表示参数中Sets的数量。该命令将返回参数中所有
Keys关联的Sets中成员的交集。因此如果参数中任
何一个Key关联的Set为空,或某一Key不存在,那
么该命令的结果将为空集。
交集结
果成员
的集
合。
SINTERSTORE
destination key
[key ...]
O(N*M) 该命令和SINTER命令在功能上完全相同,两者之间
唯一的差别是SINTER返回交集的结果成员,而该命
令将交集成员存储在destination关联的Set中。如
果destination键已经存在,该操作将覆盖它的成
员。
返回交
集成员
的数
量。
SUNION key
[key ...]
O(N) 时间复杂度中的N表示所有Sets中成员的总数量。
该命令将返回参数中所有Keys关联的Sets中成员的
并集。
并集结
果成员
的集
合。
SUNIONSTORE
destination key
[key ...]
O(N) 该命令和SUNION命令在功能上完全相同,两者之
间唯一的差别是SUNION返回并集的结果成员,而
该命令将并集成员存储在destination关联的Set
中。如果destination键已经存在,该操作将覆盖它
的成员。
返回并
集成员
的数
量。

三、命令示例:

1. SADD/SMEMBERS/SCARD/SISMEMBER:

#在Shell命令行下启动Redis的客户端程序。
/> redis-cli

#插入测试数据,由于该键myset之前并不存在,因此参数中的三个成员都被正常插入。
redis 127.0.0.1:6379>sadd myset a b c
(integer) 3

#由于参数中的a在myset中已经存在,因此本次操作仅仅插入了d和e两个新成员。
redis 127.0.0.1:6379>sadd myset a d e
(integer) 2

#判断a是否已经存在,返回值为1表示存在。
redis 127.0.0.1:6379>sismember myset a
(integer) 1

#判断f是否已经存在,返回值为0表示不存在。
redis 127.0.0.1:6379>sismember myset f
(integer) 0

#通过smembers命令查看插入的结果,从结果可以,输出的顺序和插入顺序无关。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
4) "b"
5) "e"

#获取Set集合中元素的数量。
redis 127.0.0.1:6379>scard myset
(integer) 5

2. SPOP/SREM/SRANDMEMBER/SMOVE:

#删除该键,便于后面的测试。
redis 127.0.0.1:6379>del myset
(integer) 1

#为后面的示例准备测试数据。
redis 127.0.0.1:6379>sadd myset a b c d
(integer) 4

#查看Set中成员的位置。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
4) "b"

#从结果可以看出,该命令确实是随机的返回了某一成员。
redis 127.0.0.1:6379>srandmember myset
"c"

#Set中尾部的成员b被移出并返回,事实上b并不是之前插入的第一个或最后一个成员。
redis 127.0.0.1:6379>spop myset
"b"

#查看移出后Set的成员信息。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"

#从Set中移出a、d和f三个成员,其中f并不存在,因此只有a和d两个成员被移出,返回为2。
redis 127.0.0.1:6379>srem myset a d f
(integer) 2

#查看移出后的输出结果。
redis 127.0.0.1:6379>smembers myset
1) "c"

#为后面的smove命令准备数据。
redis 127.0.0.1:6379>sadd myset a b
(integer) 2
redis 127.0.0.1:6379>sadd myset2 c d
(integer) 2

#将a从myset移到myset2,从结果可以看出移动成功。
redis 127.0.0.1:6379>smove myset myset2 a
(integer) 1

#再次将a从myset移到myset2,由于此时a已经不是myset的成员了,因此移动失败并返回0。
redis 127.0.0.1:6379>smove myset myset2 a
(integer) 0

#分别查看myset和myset2的成员,确认移动是否真的成功。
redis 127.0.0.1:6379>smembers myset
1) "b"
redis 127.0.0.1:6379> smembers myset2
1) "c"
2) "d"
3) "a"

3. SDIFF/SDIFFSTORE/SINTER/SINTERSTORE:

#为后面的命令准备测试数据。
redis 127.0.0.1:6379>sadd myset a b c d
(integer) 4
redis 127.0.0.1:6379> sadd myset2 c
(integer) 1
redis 127.0.0.1:6379>sadd myset3 a c e
(integer) 3

#myset和myset2相比,a、b和d三个成员是两者之间的差异成员。再用这个结果继续和myset3进行差异比
较,b和d是myset3不存在的成员。
redis 127.0.0.1:6379>sdiff myset myset2 myset3
1) "d"
2) "b"

#将3个集合的差异成员存在在diffkey关联的Set中,并返回插入的成员数量。
redis 127.0.0.1:6379>sdiffstore diffkey myset myset2 myset3
(integer) 2

#查看一下sdiffstore的操作结果。
redis 127.0.0.1:6379>smembers diffkey
1) "d"
2) "b"

#从之前准备的数据就可以看出,这三个Set的成员交集只有c。
redis 127.0.0.1:6379>sinter myset myset2 myset3
1) "c"

#将3个集合中的交集成员存储到与interkey关联的Set中,并返回交集成员的数量。
redis 127.0.0.1:6379> sinterstore interkey myset myset2 myset3
(integer) 1

#查看一下sinterstore的操作结果。
redis 127.0.0.1:6379>smembers interkey
1) "c"

#获取3个集合中的成员的并集。
redis 127.0.0.1:6379>sunion myset myset2 myset3
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"

#将3个集合中成员的并集存储到unionkey关联的set中,并返回并集成员的数量。
redis 127.0.0.1:6379>sunionstore unionkey myset myset2 myset3
(integer) 5

#查看一下suiionstore的操作结果。
redis 127.0.0.1:6379>smembers unionkey
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"

四、应用范围:

1). 可以使用Redis的Set数据类型跟踪一些唯一性数据,比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性。
2). 充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的 Set中,而购买另外一种电子产品的客户ID被存储在另外一个Set中,如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的 intersections命令就可以充分发挥它的方便和效率的优势了。

案例:

1、设计四个好友

[root@localhost ~]# redis-cli
127.0.0.1:6379> set it_user:id:1:username tom
OK
127.0.0.1:6379> set it_user:id:1:email [email protected]
OK
127.0.0.1:6379> set it_user:id:2:username john
OK
127.0.0.1:6379> set it_user:id:2:email [email protected]
OK
127.0.0.1:6379> set it_user:id:3:username bob
OK
127.0.0.1:6379> set it_user:id:3:email [email protected]
OK
127.0.0.1:6379> set it_user:id:4:username smith
OK
127.0.0.1:6379> set it_user:id:4:email [email protected]
OK
127.0.0.1:6379> keys it_user:id*
1) "it_user:id:4:username"
2) "it_user:id:1:username"
3) "it_user:id:2:username"
4) "it_user:id:2:email"
5) "it_user:id:1:email"
6) "it_user:id:3:email"
7) "it_user:id:4:email"
8) "it_user:id:3:username"

2、设定好友集合

1号好友为2号和3号
127.0.0.1:6379> sadd set:user:id:1:friend 2
(integer) 1
127.0.0.1:6379> sadd set:user:id:1:friend 3
(integer) 1
127.0.0.1:6379> SMEMBERS set:user:id:1:friend
1) "2"
2) "3"
 
4号好友为3号
127.0.0.1:6379> sadd set:user:id:4:friend 3
(integer) 1
127.0.0.1:6379> SMEMBERS set:user:id:4:friend
1) "3"

3、好友关系

共同好友(交集)
127.0.0.1:6379> SINTER set:user:id:1:friend set:user:id:4:friend
1) "3"
 
全部好友(并集)
127.0.0.1:6379> sunion set:user:id:1:friend set:user:id:4:friend
1) "2"
2) "3"
推荐好友(差集)
127.0.0.1:6379> SDIFF set:user:id:1:friend set:user:id:4:friend
1) "2"

一个简单的实例 sns的常用功能,获取共同好友

Redis 简介_第5张图片

1.4.5 zset 类型及操作

一、概述:

       Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中。它们之间的主要差别是Sorted- Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然而需要额外指出的是,尽管 Sorted-Sets中的成员必须是唯一的,但是分数(score)却是可以重复的。

       在Sorted-Set中添加、删除或更新一个成员都是非常快速的操作,其时间复杂度为集合中成员数量的对数。由于Sorted-Sets中的成员在集 合中的位置是有序的,因此,即便是访问位于集合中部的成员也仍然是非常高效的。事实上,Redis所具有的这一特征在很多其它类型的数据库中是很难实现 的,换句话说,在该点上要想达到和Redis同样的高效,在其它数据库中进行建模是非常困难的。

二、相关命令列表:

命令原型  时间复杂度  命令描述 返回值
ZADD key score
member [score]
[member]
O(log(N)) 时间复杂度中的N表示Sorted-Sets中成
员的数量。添加参数中指定的所有 成员
及其分数到指定key的Sorted-Set中,在
该命令中我们可以指定多组
score/member作为参数。如果在添加时
参数中的某一成员已经存 在,该命令将
更新此成员的分数为新值,同时再将该
成员基于新值重新排序。如果键不存
在,该命令将为该键创建一个新的
Sorted-Sets Value,并将
score/member对插入其中。如果该键已
经存在,但是与其关联的Value不是
Sorted-Sets类型,相关的错误信息将被
返回。
本次操
作实际
插入的
成员数
量。
ZCARD key  O(1) 获取与该Key相关联的Sorted-Sets中包
含的成员数量。
返回
Sorted-
Sets中
的成员
数量,
如果该
Key不
存在,
返回
0。
ZCOUNT key min max O(log(N)+M) 时间复杂度中的N表示Sorted-Sets中成
员的数量,M则表示min和max之间元素
的数量。该命令用于获取分数(score)在
min和max之间的成员数量。针对min和
max参数需要额外说明的是,-inf和+inf
分别表示Sorted-Sets中分数的最高值和
最低值。缺省情况下,min和max表示的
范围是闭区间范围,即min <= score <=
max内的成员将被返回。然而我们可以
通过在min和max的前面添加"("字符来表
示开区间,如(min max表示min < score
<= max,而(min (max表示min < score
< max。
分数指
定范围
内成员
的数
量。
ZINCRBY key
increment member
O(log(N)) 时间复杂度中的N表示Sorted-Sets中成
员的数量。该命令将为指定Key 中的指定
成员增加指定的分数。如果成员不存
在,该命令将添加该成员并假设其初始
分数为0,此后再将其分数加上
increment。如果Key不存,该命令 将创
建该Key及其关联的Sorted-Sets,并包
含参数指定的成员,其分数为increment
参数。如果与该Key关联的不是Sorted-
Sets类型,相关的错误信息将被返回。
以字符
串形式
表示的
新分
数。
ZRANGE key start
stop [WITHSCORES]
O(log(N)+M) 时间复杂度中的N表示Sorted-Set中成员
的数量,M则表示返回的成员数 量。该
命令返回顺序在参数start和stop指定范
围内的成员,这里start和stop参数都是
0-based,即0表示第一个成员,-1表示
最后一 个成员。如果start大于该Sorted-
Set中的最大索引值,或start > stop,此
时一个空集合将被返回。如果stop大于
最大索引值,该命令将返回从start到集
合的最后一个成员。如果命令中带有可
选参数WITHSCORES选项,该命令在返
回的结果中将包含每个成员的分数值,
如value1,score1,value2,score2...。
返回索
引在
start和
stop之
间的成
员列
表。
ZRANGEBYSCORE key
min max
[WITHSCORES] [LIMIT
offset count]
O(log(N)+M) 时间复杂度中的N表示Sorted-Set中成员
的数量,M则表示返回的成员数 量。该
命令将返回分数在min和max之间的所有
成员,即满足表达式min <= score <=
max的成员,其中返回的成员是按照其
分数从低到高的顺序返回,如果成员具
有相同的分数,则按成员的字典顺序返
回。可选参数LIMIT用于限制返回成员的
数量范围。可选参数offset表示从符合条
件的第offset个成员开始返回,同时返回
count个成员。可选参数WITHSCORES的
含义参照 ZRANGE中该选项的说明。最
后需要说明的是参数中min和max的规则
可参照命令ZCOUNT。
返回分
数在指
定范围
内的成
员列
表。
ZRANK key member  O(log(N)) 时间复杂度中的N表示Sorted-Set中成员
的数量。Sorted-Set中的成员都是按照分
数从低到高的顺序存储,该命令将返回
参数中指定成员的位置值,其中0表示第
一个成员,它是Sorted-Set中分数最低的
成员。
如果该
成员存
在,则
返回它
的位置
索引
值。否
则返回
nil。
ZREM key member
[member ...]
O(M log(N)) 时间复杂度中N表示Sorted-Set中成员的
数量,M则表示被删除的成员数量。该命
令将移除参数中指定的成员,其中不存
在的成员将被忽略。如果与该Key关联的
Value不是Sorted-Set,相应的错误信息
将被返回。
实际被
删除的
成员数
量。
ZREVRANGE key start
stop [WITHSCORES]
O(log(N)+M) 时间复杂度中的N表示Sorted-Set中成员
的数量,M则表示返回的成员数量。该命
令的功能和ZRANGE基本相同,唯一的差
别在于该命令是通过反向排序获取指定
位置的成员,即从高到低的顺序。如果
成员具有相同的分数,则按降序字典顺
序排序。
返回指
定的成
员列
表。
ZREVRANK key
member
O(log(N)) 时间复杂度中的N表示Sorted-Set中成员
的数量。该命令的功能和ZRANK基本相
同,唯一的差别在于该命令获取的索引
是从高到低排序后的位置,同样0表示第
一个元素,即分数最高的成员。
如果该
成员存
在,则
返回它
的位置
索引
值。否
则返回
nil。
ZSCORE key member  O(1) 获取指定Key的指定成员的分数。 如果该
成员存
在,以
字符串
的形式
返回其
分数,
否则返
回nil。
ZREVRANGEBYSCORE
key max min
[WITHSCORES] [LIMIT
offset count]
O(log(N)+M) 时间复杂度中的N表示Sorted-Set中成员
的数量,M则表示返回的成员数量。该命
令除了排序方式是基于从高到低的分数
排序之外,其它功能和参数含义均与
ZRANGEBYSCORE相同。
返回分
数在指
定范围
内的成
员列
表。
ZREMRANGEBYRANK
key start stop
O(log(N)+M) 时间复杂度中的N表示Sorted-Set中成员
的数量,M则表示被删除的成员数量。删
除索引位置位于start和stop之间的成
员,start和stop都是0-based,即0表示
分数最低的成员,-1表示最后一个成员,
即分数最高的成员。
被删除
的成员
数量。
ZREMRANGEBYSCORE
key min max
O(log(N)+M) 时间复杂度中的N表示Sorted-Set中成员
的数量,M则表示被删除的成员数量。删
除分数在min和max之间的所有成员,即
满足表达式min <= score <= max的所有
成员。对于min和max参数,可以采用开
区间的方式表示,具体规则参照
ZCOUNT。
被删除
的成员
数量。

三、命令示例:

1. ZADD/ZCARD/ZCOUNT/ZREM/ZINCRBY/ZSCORE/ZRANGE/ZRANK:

#在Shell的命令行下启动Redis客户端工具。
/>redis-cli

#添加一个分数为1的成员。
redis 127.0.0.1:6379> zadd myzset 1 "one"
(integer) 1

#添加两个分数分别是2和3的两个成员。
redis 127.0.0.1:6379>zadd myzset 2 "two" 3 "three"
(integer) 2

#0表示第一个成员,-1表示最后一个成员。WITHSCORES选项表示返回的结果中包含每个成员及其分数,否则
只返回成员。
redis 127.0.0.1:6379>zrange myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"

#获取成员one在Sorted-Set中的位置索引值。0表示第一个位置。
redis 127.0.0.1:6379>zrank myzset one
(integer) 0

#成员four并不存在,因此返回nil。
redis 127.0.0.1:6379>zrank myzset four
(nil)

#获取myzset键中成员的数量。
redis 127.0.0.1:6379> zcard myzset
(integer) 3

#返回与myzset关联的Sorted-Set中,分数满足表达式1 <= score <= 2的成员的数量。
redis 127.0.0.1:6379>zcount myzset 1 2
(integer) 2

#删除成员one和two,返回实际删除成员的数量。
redis 127.0.0.1:6379>zrem myzset one two
(integer) 2

#查看是否删除成功。
redis 127.0.0.1:6379>zcard myzset
(integer) 1

#获取成员three的分数。返回值是字符串形式。
redis 127.0.0.1:6379>zscore myzset three
"3"

#由于成员two已经被删除,所以该命令返回nil。
redis 127.0.0.1:6379>zscore myzset two
(nil)

#将成员one的分数增加2,并返回该成员更新后的分数。
redis 127.0.0.1:6379>zincrby myzset 2 one
"3"

#将成员one的分数增加-1,并返回该成员更新后的分数。
redis 127.0.0.1:6379>zincrby myzset -1 one
"2"

#查看在更新了成员的分数后是否正确。
redis 127.0.0.1:6379>zrange myzset 0 -1 WITHSCORES
1) "one"
2) "2"
3) "two"
4) "2"
5) "three"
6) "3"

2. ZRANGEBYSCORE/ZREMRANGEBYRANK/ZREMRANGEBYSCORE

redis 127.0.0.1:6379>del myzset
(integer) 1
redis 127.0.0.1:6379>zadd myzset 1 one 2 two 3 three 4 four
(integer) 4

#获取分数满足表达式1 <= score <= 2的成员。
redis 127.0.0.1:6379> zrangebyscore myzset 1 2
1) "one"
2) "two"

#获取分数满足表达式1 < score <= 2的成员。
redis 127.0.0.1:6379>zrangebyscore myzset (1 2
1) "two"

#-inf表示第一个成员,+inf表示最后一个成员,limit后面的参数用于限制返回成员的自己,
#2表示从位置索引(0-based)等于2的成员开始,去后面3个成员。
redis 127.0.0.1:6379>zrangebyscore myzset -inf +inf limit 2 3
1) "three"
2) "four"

#删除分数满足表达式1 <= score <= 2的成员,并返回实际删除的数量。
redis 127.0.0.1:6379>zremrangebyscore myzset 1 2
(integer) 2

#看出一下上面的删除是否成功。
redis 127.0.0.1:6379>zrange myzset 0 -1
1) "three"
2) "four"

#删除位置索引满足表达式0 <= rank <= 1的成员。
redis 127.0.0.1:6379>zremrangebyrank myzset 0 1
(integer) 2

#查看上一条命令是否删除成功。
redis 127.0.0.1:6379>zcard myzset
(integer) 0

3. ZREVRANGE/ZREVRANGEBYSCORE/ZREVRANK:

#为后面的示例准备测试数据。
redis 127.0.0.1:6379>del myzset
(integer) 0
redis 127.0.0.1:6379>zadd myzset 1 one 2 two 3 three 4 four
(integer) 4

#以位置索引从高到低的方式获取并返回此区间内的成员。
redis 127.0.0.1:6379>zrevrange myzset 0 -1 WITHSCORES
1) "four"
2) "4"
3) "three"
4) "3"
5) "two"
6) "2"
7) "one"
8) "1"

#由于是从高到低的排序,所以位置等于0的是four,1是three,并以此类推。
redis 127.0.0.1:6379>zrevrange myzset 1 3
1) "three"
2) "two"
3) "one"

#由于是从高到低的排序,所以one的位置是3。
redis 127.0.0.1:6379>zrevrank myzset one
(integer) 3

#由于是从高到低的排序,所以four的位置是0。
redis 127.0.0.1:6379>zrevrank myzset four
(integer) 0

#获取分数满足表达式3 >= score >= 0的成员,并以相反的顺序输出,即从高到底的顺序。
redis 127.0.0.1:6379>zrevrangebyscore myzset 3 0
1) "three"
2) "two"
3) "one"

#该命令支持limit选项,其含义等同于zrangebyscore中的该选项,只是在计算位置时按照相反的顺序计算
和获取。
redis 127.0.0.1:6379> zrevrangebyscore myzset 4 0 limit 1 2
1) "three"
2) "two"

四、应用范围:

1). 可以用于一个大型在线游戏的积分排行榜。每当玩家的分数发生变化时,可以执行ZADD命令更新玩家的分数,此后再通过ZRANGE命令获取积分TOP TEN的用户信息。当然我们也可以利用ZRANK命令通过username来获取玩家的排行信息。最后我们将组合使用ZRANGE和ZRANK命令快速的 获取和某个玩家积分相近的其他用户的信息。
2). Sorted-Sets类型还可用于构建索引数据。

1.5 key 操作命令

一、概述:

       在前面主要讲述的是与Redis数据类型相关的命令,如String、List、Set、Hashes和Sorted-Set。这些命 令都具有一个共同点,即所有的操作都是针对与Key关联的Value的。下面主要讲述与Key相关的Redis命令。学习这些命令对于学习 Redis是非常重要的基础,也是能够充分挖掘Redis潜力的利器。

二、相关命令列表:

命令原型  时间复杂度  命令描述  返回值
KEYS pattern  O(N) 时间复杂度中的N表示数据库中Key的数
量。获取所有匹配pattern参数的Keys。需
要说明的是,在我们的正常操作中应该尽
量避免对该命令的调用,因为对于大型数
据库而言,该命令是非常耗时的,对Redis
服务器的性能打击也是比较大的。pattern
支持glob-style的通配符格式,如*表示任
意一个或多个字符,?表示任意字符,[abc]
表示方括号中任意一个字母。
匹配模
式的键
列表。
DEL key [key ...]  O(N) 时间复杂度中的N表示删除的Key数量。从
数据库删除中参数中指定的keys,如 果指
定键不存在,则直接忽略。还需要另行指
出的是,如果指定的Key关联的数据类型不
是String类型,而是List、Set、Hashes和
Sorted Set等容器类型,该命令删除每个键
的时间复杂度为O(M),其中M表示容器中
元素的数量。而对于String类型的Key,其
时间复杂度为O(1)。
实际被
删除的
Key数
量。
EXISTS key  O(1)  判断指定键是否存在 1表示存
在,0表
示不存
在。
MOVE key db  O(1)  将当前数据库中指定的键Key移动到参数中
指定的数据库中。如果该Key在目标数据库
中已经存在,或者在当前数据库中并不存
在,该命令将不做任何操作并返回0。
移动成
功返回
1,否则
0。
RENAME key
newkey
O(1)  为指定指定的键重新命名,如果参数中的
两个Keys的命令相同,或者是源Key不存
在,该命令都会返回相关的错误信息。如
果newKey已经存在,则直接覆盖。
RENAMENX key
newkey
O(1)  如果新值不存在,则将参数中的原值修改
为新值。其它条件和RENAME一致。
1表示修
改成
功,否
则0。
PERSIST key O(1)  如果Key存在过期时间,该命令会将其过期
时间消除,使该Key不再有超时,而是可以
持久化存储。
1表示
Key的过
期时间
被移
出,0表
示该Key
不存在
或没有
过期时
间。
EXPIRE key
seconds
O(1)  该命令为参数中指定的Key设定超时的秒
数,在超过该时间后,Key被自动的删除。
如果该Key在超时之前被修改,与该键关联
的超时将被移除。
1表示超
时被设
置,0则
表示Key
不存
在,或
不能被
设置。
EXPIREAT key
timestamp
O(1)  该命令的逻辑功能和EXPIRE完全相同,唯
一的差别是该命令指定的超时时间是绝对
时间,而不是相对时间。该时间参数是
Unix timestamp格式的,即从1970年1月1
日开始所流经的秒数。
1表示超
时被设
置,0则
表示Key
不存
在,或
不能被
设置。
TTL key O(1)  获取该键所剩的超时描述。 返回所
剩描
述,如
果该键
不存在
或没有
超时设
置,则

回-1。
RANDOMKEY  O(1) 从当前打开的数据库中随机的返回一个
Key。
返回的
随机
键,如
果该数
据库是
空的则
返回
nil。
TYPE key  O(1) 获取与参数中指定键关联值的类型,该命
令将以字符串的格式返回。
返回的
字符串

string、
list、
set、
hash和
zset,
如果key
不存在
返回
none。
SORT key [BY
pattern] [LIMIT
offset count]
[GET pattern
[GET pattern
...]] [ASC|DESC]
[ALPHA]
[STORE
destination]
O(N+M*log(M)) 这个命令相对来说是比较复杂的,因此我
们这里只是给出最基本的用法,有兴趣的
网友可以去参考redis的官方文档。
返回排
序后的
原始列
表。

三、命令示例:

1. KEYS/RENAME/DEL/EXISTS/MOVE/RENAMENX:

#在Shell命令行下启动Redis客户端工具。
/> redis-cli

#清空当前选择的数据库,以便于对后面示例的理解。
redis 127.0.0.1:6379>flushdb
OK

#添加String类型的模拟数据。
redis 127.0.0.1:6379>set mykey 2
OK
redis 127.0.0.1:6379>set mykey2 "hello"
OK

#添加Set类型的模拟数据。
redis 127.0.0.1:6379>sadd mysetkey 1 2 3
(integer) 3

#添加Hash类型的模拟数据。
redis 127.0.0.1:6379>hset mmtest username "stephen"
(integer) 1

#根据参数中的模式,获取当前数据库中符合该模式的所有key,从输出可以看出,该命令在执行时并不区分与
Key关联的Value类型。
redis 127.0.0.1:6379>keys my*
1) "mysetkey"
2) "mykey"
3) "mykey2"

#删除了两个Keys。
redis 127.0.0.1:6379>del mykey mykey2
(integer) 2

#查看一下刚刚删除的Key是否还存在,从返回结果看,mykey确实已经删除了。
redis 127.0.0.1:6379>exists mykey
(integer) 0

#查看一下没有删除的Key,以和上面的命令结果进行比较。
redis 127.0.0.1:6379>exists mysetkey
(integer) 1

#将当前数据库中的mysetkey键移入到ID为1的数据库中,从结果可以看出已经移动成功。
redis 127.0.0.1:6379>move mysetkey 1
(integer) 1

#打开ID为1的数据库。
redis 127.0.0.1:6379> select 1
OK

#查看一下刚刚移动过来的Key是否存在,从返回结果看已经存在了。
redis 127.0.0.1:6379[1]>exists mysetkey
(integer) 1

#在重新打开ID为0的缺省数据库。
redis 127.0.0.1:6379[1]>select 0
OK

#查看一下刚刚移走的Key是否已经不存在,从返回结果看已经移走。
redis 127.0.0.1:6379>exists mysetkey
(integer) 0

#准备新的测试数据。
redis 127.0.0.1:6379>set mykey "hello"
OK

#将mykey改名为mykey1
redis 127.0.0.1:6379> rename mykey mykey1
OK

#由于mykey已经被重新命名,再次获取将返回nil。
redis 127.0.0.1:6379>get mykey
(nil)

#通过新的键名获取。
redis 127.0.0.1:6379>get mykey1
"hello"

#由于mykey已经不存在了,所以返回错误信息。
redis 127.0.0.1:6379>rename mykey mykey1
(error) ERR no such key

#为renamenx准备测试key
redis 127.0.0.1:6379>set oldkey "hello"
OK
redis 127.0.0.1:6379>set newkey "world"
OK

#由于newkey已经存在,因此该命令未能成功执行。
redis 127.0.0.1:6379>renamenx oldkey newkey
(integer) 0

#查看newkey的值,发现它也没有被renamenx覆盖。
redis 127.0.0.1:6379>get newkey
"world"

2. PERSIST/EXPIRE/EXPIREAT/TTL:

#为后面的示例准备的测试数据。
redis 127.0.0.1:6379>set mykey "hello"
OK

#将该键的超时设置为100秒。
redis 127.0.0.1:6379>expire mykey 100
(integer) 1

#通过ttl命令查看一下还剩下多少秒。
redis 127.0.0.1:6379>ttl mykey
(integer) 97

#立刻执行persist命令,该存在超时的键变成持久化的键,即将该Key的超时去掉。
redis 127.0.0.1:6379>persist mykey
(integer) 1

#ttl的返回值告诉我们,该键已经没有超时了。
redis 127.0.0.1:6379>ttl mykey
(integer) -1

#为后面的expire命令准备数据。
redis 127.0.0.1:6379> del mykey
(integer) 1
redis 127.0.0.1:6379>set mykey "hello"
OK

#设置该键的超时被100秒。
redis 127.0.0.1:6379>expire mykey 100
(integer) 1

#用ttl命令看一下当前还剩下多少秒,从结果中可以看出还剩下96秒。
redis 127.0.0.1:6379>ttl mykey
(integer) 96

#重新更新该键的超时时间为20秒,从返回值可以看出该命令执行成功。
redis 127.0.0.1:6379>expire mykey 20
(integer) 1

#再用ttl确认一下,从结果中可以看出果然被更新了。
redis 127.0.0.1:6379>ttl mykey
(integer) 17

#立刻更新该键的值,以使其超时无效。
redis 127.0.0.1:6379>set mykey "world"
OK

#从ttl的结果可以看出,在上一条修改该键的命令执行后,该键的超时也无效了。
redis 127.0.0.1:6379>ttl mykey
(integer) -1

3. TYPE/RANDOMKEY/SORT:

#由于mm键在数据库中不存在,因此该命令返回none。
redis 127.0.0.1:6379>type mm
none

#mykey的值是字符串类型,因此返回string。
redis 127.0.0.1:6379>type mykey
string

#准备一个值是set类型的键。
redis 127.0.0.1:6379>sadd mysetkey 1 2
(integer) 2

#mysetkey的键是set,因此返回字符串set。
redis 127.0.0.1:6379>type mysetkey
set

#返回数据库中的任意键。
redis 127.0.0.1:6379>randomkey
"oldkey"

#清空当前打开的数据库。
redis 127.0.0.1:6379>flushdb
OK

#由于没有数据了,因此返回nil。
redis 127.0.0.1:6379>randomkey
(nil)

1.6 客户端操作

1.6.1 php客户端

php 操作redis

1、安装php-redis
[root@localhost ~]# yum install php-redis

2、准备php环境
[root@localhost ~]# yum install httpd php -y

3、启动测试apache和php协同
[root@localhost ~]# vim /var/www/html/phpinfo.php

[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl enable httpd

4、测试
连接到 redis 服务
[root@localhost ~]# vim /var/www/html/ping.php
connect('127.0.0.1', 6379);
 echo "Connection to server sucessfully";
    //查看服务是否运行
 echo "Server is running: " . $redis->ping();
?>
[root@localhost ~]# elinks -dump http://localhost/ping.php
 Connection to server sucessfullyServer is running: +PONG
Redis PHP String(字符串) 实例
[root@localhost ~]# vim /var/www/html/string.php
connect('127.0.0.1', 6379);
 echo "Connection to server sucessfully";
 
//设置 redis 字符串数据
 $redis->set("linux", "Linux Redis test");

 // 获取存储的数据并输出
 echo "Stored string in redis:: " .  $redis->get("linux");
?>
[root@localhost ~]# elinks -dump http://localhost/string.php
 Connection to server sucessfullyStored string in redis:: Linux Redis test

Redis PHP List(列表) 实例
[root@localhost ~]# vim /var/www/html/list.php
connect('127.0.0.1', 6379);
 echo "Connection to server sucessfully";
 //存储数据到列表中
 $redis->lpush("test-list", "Redis");
 $redis->lpush("test-list", "Mongodb");
 $redis->lpush("test-list", "Mysql");
 // 获取存储的数据并输出
 $arList = $redis->lrange("test-list", 0 ,5);
 echo "Stored string in redis";
 print_r($arList);
?>
[root@localhost ~]# elinks -dump http://localhost/list.php
 Connection to server sucessfullyStored string in redisArray ( [0] => Mysql
 [1] => Mongodb [2] => Redis )
Redis PHP Keys 实例
[root@localhost ~]# vim /var/www/html/keys.php
connect('127.0.0.1', 6379);
 echo "Connection to server sucessfully";
 // 获取数据并输出
 $arList = $redis->keys("*");
 echo "Stored keys in redis:: ";
 print_r($arList);
?>
[root@localhost ~]# elinks -dump http://localhost/keys.php
 Connection to server sucessfullyStored keys in redis:: Array ( [0] =>
 test-list [1] => linux )

1.6.2 python

1、安装python-redis
 [root@localhost ~]# yum install python-redis -y

2、基本操作
 [root@localhost ~]# vim python_redis.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

#载入模块
import redis

#连接redis数据库
r = redis.Redis(host='127.0.0.1', port=6379,db=0)

#往redis中写数据
r.set('nvshen', 'hehe')
r['diaosi'] = 'yy'
r.set('xueba', 'xuexi')
r['xuezha'] = 'wan'

#查看对应的值
print 'nvshen', r.get('nvshen')

#查看数据库中有多少个key,多少条数据
print r.dbsize()

#将数据保存到硬盘中(保存时阻塞)
r.save()

#查看键值是否存在
print r.exists("doubi")

#列出所有键值
print r.keys()

#删除键值对应的数据
print r.delete('diaosi')
print r.delete('xuezha')

#删除当前数据库所有数据
r.flushdb()
[root@localhost ~]# python python_redis.py
nvshen hehe
4
False
['xuezha', 'xueba', 'diaosi', 'nvshen']
1
1

1.6.3 GUI 工具

redis-desktop-manager

RESP.app (formerly Redis Desktop Manager) - GUI for Redis ® available on Windows, macOS, iPad and Linux.

基本介绍

       redis desktop manager是一款功能强大的redis数据库管理软件,可以帮助用户轻松快速的查看与操控整个数据库。redis desktop manager不仅拥有十分简洁直观的操作界面,而且所有功能信息一目了然,是广大用户必备的数据库管理神器。
       redis desktop manager具有操作简单、方便快捷、功能完善、性能稳定等优点,支持用户采用可视化操作界面对数据库进行各方面工作,不管是新手用户还是专业的开发人员,该软件都是你管理数据库的最佳帮手。
       Redis Desktop Manager for windows是一款可以跨平台的redis可视化工具,兼容win、mac等操作系统,该工具可以说很大程度上弥补了memcached这类key/value存储的不足,为Java、C/C++、C#、PHP、JavaScript、Perl、Object-C、Python、Ruby、Erlang等开发语言提供了便利的客户端。

软件特点

C++ 编写,响应迅速,性能好。但不支持数据库备份与恢复

软件功能

一、新建连接
输入redis主机host,端口号port,再起个生动形象,简明达意的别名。
二、该工具支持根据筛选条件查询key,addnewkey,reload等。
三、支持常用redis操作
针对目标key执行rename,delete,addrow,reloadvalue操作。
四、命令控制台操作!

配置方法

Redis 简介_第6张图片

 配置 Redis DeskTop Manager
启动Redis服务端的时候会有默认端口6379,这里用默认端口配置连接。
配置如下:
1)定一个名称,随意
2)服务端地址,域名或ID,
3)Redis 端口,默认 6379
4)如果设置了连接密码,那么需要设置密码
配置好之后点击 Test Connection 按钮,看是否可以连接成功,如果失败请检查一下配置信息

你可能感兴趣的:(NoSQL,redis)