Redis数据类型
经过前面介绍,我们知道 Redis 是 Key-Value 类型缓存型数据库,Redis 为了存储不同类型的数据,提供了五种常用数据类型,如下所示:
- string(字符串)
- hash(哈希散列)
- list(列表)
- set(集合)
- zset(sorted set:有序集合)
注意:这里指的数据类型是 Value(值) 的数据类型,而非 key。
string字符串
String 是 Redis 最基本的数据类型。字符串是一组字节,在 Redis 数据库中,字符串具有二进制安全(binary safe)特性,这意味着它的长度是已知的,不由任何其他终止字符决定的,一个字符串类型的值最多能够存储 512 MB 的内容。
二进制安全:是一种主要用于字符串操作函数的计算机编程术语。只关心二进制化的字符串,不关心具体的字符串格式,严格的按照二进制的数据存取。这保证字符串不会因为某些操作而遭到损坏。
下面我们使用 SET 命令储存一个字符串,然后使用 GET 命令查看它:
127.0.0.1:6379> set website "www.biancheng.net"
OK
127.0.0.1:6379> get website
"www.biancheng.net"
在上述事例,我们使用 Redis 存储了一个键为 website,值为 www.baincheng.net 的 string 类型数据。
当然您也使用 MSET 命令一次性存储多个值,并使用 MGET 命令查询多个 key,如下所示:
127.0.0.1:6379> MSET name www.biancheng.net topic Redis
OK
127.0.0.1:6379> MGET name topic
1) "www.biancheng.net"
2) "Redis"
hash散列
hash 散列是由字符串类型的 field 和 value 组成的映射表,您可以把它理解成一个包含了多个键值对的集合。由于 Hash 类型具有上述特点,所以一般被用来存储对象。
下面使用 HMSET 命令来存储一个包含了用户基本信息的对象,如下所示:
127.0.0.1:6379> HMSET userid:1 username xiaoming password 123456 website www.biancheng.net
OK
127.0.0.1:6379> HGETALL userid:1
1) "username"
2) "xiaoming"
3) "password"
4) "123456"
5) "website"
6) "www.biancheng.net"
上述示例中,我们是使用到了 HMSET 和 HGETALL 命令,前者可以同时设置多个字段,后者用来查询全部字段。
注意:一个 Hash 中最多包含 2^32-1 个键值对。
list列表
Redis List 中的元素是字符串类型,其中的元素按照插入顺序进行排列,允许重复插入,最多可插入的元素个数为 2^32 -1 个(大约40亿个),您可以添加一个元素到列表的头部(左边)或者尾部(右边)。
下面使用 LPUSH 和 LRANGE 命令对 List 数据类型进行简单演示:
#LPUSH 列表添加元素命令
127.0.0.1:6379> LPUSH biancheng Java
(integer) 1
127.0.0.1:6379> LPUSH biancheng Python
(integer) 2
127.0.0.1:6379> LPUSH biancheng C
(integer) 3
127.0.0.1:6379> LPUSH biancheng SQL
(integer) 4
127.0.0.1:6379> LPUSH biancheng Redis
(integer) 5
127.0.0.1:6379> LPUSH biancheng Golang
(integer) 6
#LRANGE 查看列表元素
#最开始插入的在最后,最后插入位于第一个位置,和队列相似。
127.0.0.1:6379> LRANGE biancheng 0 6
1) "Golang"
2) "Redis"
3) "SQL"
4) "C"
5) "Python"
6) "Java"
注意:Redis 的列表类型同样遵循索引机制。
set集合
Redis Set 是一个字符串类型元素构成的无序集合。在 Redis 中,集合是通过哈希映射表实现的,所以无论是添加元素、删除元素,亦或是查找元素,它们的时间复杂度都为 O(1)。
下面通过 SADD 命令添加 string 元素到 Set 集合中,若添加成功则返回 1,如果元素已经存在,则返回 0。示例如下:
127.0.0.1:6379> SADD www.biancheng.net HTML
(integer) 1
127.0.0.1:6379> SADD www.biancheng.net Pandas
(integer) 1
127.0.0.1:6379> SADD www.biancheng.net NumPy
(integer) 1
127.0.0.1:6379> SADD www.biancheng.net Matplotlib
(integer) 1
127.0.0.1:6379> SADD www.biancheng.net JS
(integer) 1
127.0.0.1:6379> SADD www.biancheng.net HTML
(integer) 0
127.0.0.1:6379> SADD www.biancheng.net HTML
(integer) 0
#SMEMBERS命令查看集合中元素,元素会无序排列
127.0.0.1:6379> SMEMBERS www.biancheng.net
1) "Matplotlib"
2) "HTML"
3) "JS"
4) "Pandas"
5) "NumPy"
由于 Set 集合中的成员具有唯一性,所以重复插入 HTML 元素不会成功,集合的同样可容纳 2^32 -1 个元素。
zset有序集合
Redis zset 是一个字符串类型元素构成的有序集合,集合中的元素不仅具有唯一性,而且每个元素还会关联一 个 double 类型的分数,该分数允许重复。Redis 正是通过这个分数来为集合中的成员排序。
下面通过 zadd 命令添加元素到集合,若元素存在于集合中,则不能添加成功。示例如下:
127.0.0.1:6379> del biancheng
(integer) 1
127.0.0.1:6379> zadd biancheng 0 Python
(integer) 1
127.0.0.1:6379> zadd biancheng 1 Java
(integer) 1
127.0.0.1:6379> zadd biancheng 2 C++
(integer) 1
127.0.0.1:6379> zadd biancheng 3 MySQL
(integer) 1
127.0.0.1:6379> zadd biancheng 4 Redis
(integer) 1
#重复元素无法添加成功
127.0.0.1:6379> zadd biancheng 4 Redis
(integer) 0
#重复分值添加成功
127.0.0.1:6379> zadd biancheng 4 GOLANG
(integer) 1
#查看指定成员的分值
127.0.0.1:6379> ZSCORE biancheng Redis
"4"
查看zset中的所有成员
127.0.0.1:6379> zrange biancheng 0 4
1) "Python"
2) "Java"
3) "C++"
4) "MySQL"
5) "GOLANG"
6) "Redis"
除了上述五种类型之外,Redis 还支持 HyperLogLog 类型,以及 Redis 5.0 提供的 Stream 类型。在后续章节会做相应介绍。
在线练习工具:Try Redis 查看更多命令:Command reference – Redis
Redis命令行模式
在《Redis数据类型》一节,我们使用了大量的 Redis 命令。从本节开始我们将对各种数据类型的常用命令做详细讲解。
Redis 命令用于在 Redis 服务器上执行一些操作,而命令运行的方式是通过客户端命令行来执行的,这种方式也被称为“命令行模式”。因此想要在 Redis 服务器上运行命令,您首先需要开启一个 Redis 客户端。操作方法如下:
在 CMD 命令行输入以下命令启动一个 Redis 客户端:
redis-cli
注意:在开启客户端之前,你要确定 Redis 服务器已经开启。开启方式在下载安装一节已经做了介绍,这里不再赘述。
本地服务器运行命令
本地服务器指的是,Redis 服务器和客户端安装在同一台计算机上,本教程中 Redis 运行环境都是以本地服务器来运行的。
在计算机上打开一个 Redis 客户端输入以下命令,验证客户端与Redis 服务器是否成功连接。
C:\Users\Administrator>redis-cli
127.0.0.1:6379> PING
PONG
127.0.0.1:6379>
通过执行命令 PING,以检查服务器是否正在运行,结果返回 PONG,说明已经成功连接了本地 Redis 服务器。
远程服务器上运行命令
远程服务器顾名思义指的是服务器安装在另外一台计算机上,而非本地。这台远程计算机可以是局域网中的一台,也可以是 Internet 联网状态下的远程计算机。Redis 提供了连接远程服务器的命令,格式如下:
C:\Users\Administrator>redis-cli -h host -p port -a password
参数说明:
- -h:用于指定远程 Redis 服务器的 IP 地址;
- -p:用于指定 Redis 远程服务器的端口号;
- -a:可选参数,若远程服务器设置了密码,则需要输入。
下面示例展示了如何连接到 Redis 远程服务器。
服务器在主机 IP 是 192.168.31.1,端口号为 6379 ,密码为 123456。
C:\Users\Administrator>redis-cli -h 127.0.0.1 -p 6379 -a 123456
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING
PONG
命令行自动提示功能
Redis 拥有强大的命令行提示功能,支持Tab
键自动补全,并且您也可以通过HELP
命令查看帮助信息,如下所示:
127.0.0.1:6379> HELP SET
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
Redis key键
Redis 是一种键值(key-value)型的缓存型数据库,它将数据全部以键值对的形式存储在内存中,并且 key 与 value 一一对应。这里的 key 被形象的称之为密钥,Redis 提供了诸多操作这把“密钥”的命令,从而实现了对存储数据的管理。
您可以把 key 看成 value 的变量,通过检索 key 就可以找到对应的 value 值。为了更加全面的了解 key,我们将从以下三个维度做深入讲解:
- key 的类型
- key 的命名规范
- key 的过期时间
了解key的特点
1) key的类型
key 的类型对应着 value 的类型,同样也有五种(string、list、hash、set、zset)。如果 key 指向的是一个字符串类型的值,那么 key 的类型就是字符串。我们可以通过TYPE
命令来查看 key 的类型,示例如下:
# 字符串
redis> SET weather "sunny"
OK
redis> TYPE weather
string
# 列表
redis> LPUSH book_list "programming in scala"
(integer) 1
redis> TYPE book_list
list
# 集合
redis> SADD pat "dog"
(integer) 1
redis> TYPE pat
set
2) key的命名规范
key 的命名需要遵循以下规则:
- key 取值不可以太长,否则会影响 value 的查找效率,并且浪费内存空间。
- key 取值也不能过短,否则会使得 key 可读性变差。
在 key 的取值上, Redis 官方建议使用“见名知意”的字符串格式,因为这样便于我们理解 key 的含义。比如要现在存放一个用户的姓名,其信息如下:
id | name |
01 | XiaoHong |
我们使用一个 key 来存储用户的名字,key 的设置如下所示:
127.0.0.1:6379> set user:id:01:username XiaoHong
OK
上述示例,自定义了uesr:id:01:username
这个 key,通过 key 不仅可以知道用户的 id,还可以知道这个 key 是用来存储用户名字的。注意,这里的:
只是起到分割符的作用,并不是固定的语法格式。
注意:在符合业务场景情况下,key 要尽可能的简单明了,您可以使用单词的缩写,或者自定义缩写格式。
在 Redis 中,我们也可以将一个空字符串设置成 key,示例如下:
127.0.0.1:6379> SET "" c.biancheng.net
OK
127.0.0.1:6379> GET ""
"c.biancheng.net"
key 的类型并不局限于字符串,在 Redis 中 key 具有二进制安全的特性,这意味着它可以使用任何二进制序列,但是这种 key 过于复杂一般不建议采用。总之,“见名知意”就是 key 最佳的命名规范。
对于相同数据类型而言,如果您对已经存在的 key 重新设置了新的 value,那么原来的 value 就会被覆盖掉。因此,您可以用这种方法来修改 key 存储的值。
3) key过期时间
Redis 允许你为 key 设置一个过期时间(使用 EXPIRE 等命令),也就是“到点自动删除”,这在实际业务中是非常有用的,一是它可以避免使用频率不高的 key 长期存在,从而占用内存资源;二是控制缓存的失效时间。
Redis 会把每个设置了过期时间的 key 存放到一个独立的字典中,并且会定时遍历这个字典来删除到期的 key。除了定时遍历之外,它还会使用“惰性策略”来删除过期的 key。所谓“惰性策略”指的是当客户端访问这个 key 的时候,Redis 对 key 的过期时间进行检查,如果过期了就立即删除。Redis 使用两种方式相结合的方法来处理过去的 key。
过期时间,有许多的应用场景,比如购物 App 会在特定的时间节点推出相关的活动,比如双十一、双十二、618购物节等,这些活动都是一年一度如期开办,因此当下一期举行时,上一期的活动的数据就没有意义了,在这种情景下就可以给 key 设置一个过期时间,从而减少无用数据占用内存资源。
Redis key命令格式
了解完 key 的相关规范,接下来看一下和 key 相关的命令,它的语法格式如下所示:
了解完 key 的相关规范,接下来看一下和 key 相关的命令,它的语法格式如下所示:
redis 127.0.0.1:6379> COMMAND KEY_NAME
- COMMAND:表示 key 的命令;
- KEY_NAME:表示 key 的名字。
通过示例进一步说明,DEL
代表删除命令,而 www.biancheng.net 是键。如果成功删除了键,则将的返回整数 1,否则将返回整数 0。示例如下:
redis 127.0.0.1:6379> SET www.biancheng.net "编程帮你好"
OK
#删除key
redis 127.0.0.1:6379> DEL www.biancheng.net
(integer) 1
#若键不存在删除失败
redis 127.0.0.1:6379> DEL age
(integer) 0
Redis键命令汇总
下表对常用的 Redis 键命令做了简单的总结:
Redis 键命令
命令 | 说明 |
若键存在的情况下,该命令用于删除键。 | |
用于序列化给定 key ,并返回被序列化的值。 | |
用于检查键是否存在,若存在则返回 1,否则返回 0。 | |
设置 key 的过期时间,以秒为单位。 | |
该命令与 EXPIRE 相似,用于为 key 设置过期时间,不同在于,它的时间参数值采用的是时间戳格式。 | |
设置 key 的过期,以毫秒为单位。 | |
PEXPIREAT key | 与 PEXPIRE 相似,用于为 key 设置过期时间,采用以毫秒为单位的时间戳格式。 |
此命令用于查找与指定 pattern 匹配的 key。 | |
将当前数据库中的 key 移动至指定的数据库中(默认存储为 0 库,可选 1-15中的任意库)。 | |
该命令用于删除 key 的过期时间,然后 key 将一直存在,不会过期。 | |
PTTL key | 用于检查 key 还剩多长时间过期,以毫秒为单位。 |
用于检查 key 还剩多长时间过期,以秒为单位。 | |
从当前数据库中随机返回一个 key。 | |
修改 key 的名称。 | |
RENAMENX key newkey | 如果新键名不重复,则将 key 修改为 newkey。 |
基于游标的迭代器,用于迭代数据库中存在的所有键,cursor 指的是迭代游标。 | |
该命令用于获取 value 的数据类型。 |
常用命令演示
下面对一些较难理解的命令做实例演示:
1) DUMP序列化
该命令用于将键对应的值做序列化处理,实例如下:
127.0.0.1:6379> SET num 12
OK
127.0.0.1:6379> DUMP num
"\x00\xc0\x0c\t\x00\xec\xd8\xa9\x9d\b\x82\xdfd"
上面介绍了两种设置过期时间的方法,它们都可以实现过期时间设置,key 过期后将自动被删除。
3) PEXPIREAT设置过期时间
以时间戳格式设置过期时间,并以毫秒为单位。
127.0.0.1:6379> set www.biancheng.net Python
OK
127.0.0.1:6379> PEXPIREAT www.biancheng.net 12000000000
(integer) 1
设置成功返回 1,若 key 不存在或者不能为其设置过期时间,则返回 0。
4) KEYS命令查找键
查找指定模式的键。
redis 127.0.0.1:6379> SET course1 redis
OK
redis 127.0.0.1:6379> SET course2 php
OK
redis 127.0.0.1:6379> SET course3 python
OK
127.0.0.1:6379> keys course*
1) "course1"
2) "course2"
3) "course3"
#获取所有key
127.0.0.1:6379> keys *
1) "course1"
2) "course2"
3) "course3"
4) "num"
5) "www.biancheng.net"
注意:keys * 会返回当前库中所有的键。
5) SCAN cursor
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 否则将无法继续跌代。如果新游标返回 0 则表示迭代结束。
SCAN 命令的语法格式如下:
SCAN cursor [MATCH pattern] [COUNT count]
参数说明:
- cursor :指定游标,从 0 开始新的迭代。
- pattern:指定匹配的模式。
- count:返回多少个元素,默认值为 10 。
SCAN 令可以迭代数据库中的所有键,如果想针对特定的数据类型迭代,那么命令自然也要做相应的变化。如下所示:
- SSCAN 命令用于迭代集合键中的元素。
- HSCAN 命令用于迭代哈希键中的键值对。
- ZSCAN 命令用于迭代有序集合中的元素。
该命令的使用示例如下:
127.0.0.1:6379> SCAN 0
1) "3"
2) 1) "name"
2) "website"
3) "biancheng2"
4) "www.biancheng.net"
5) "biancheng3"
6) "biancheng1"
7) "course2"
8) "topic"
9) "course1"
10) "age"
127.0.0.1:6379> SCAN 3
1) "0"
2) 1) "biancheng"
2) "course3"
3) "userid:1"
4) "num"
6) TTL命令
在 key 设置过期时间的情况下,使用该命令检查 key 剩余的过期时间。
当键没有设置过期时间,表示是永久有效时,TTL 命令返回 -1;当键过期或者被删除时,TTL 命令返回 -2。示例如下:
127.0.0.1:6379> SET www.biancheng.net hello
OK
127.0.0.1:6379> ttl www.biancheng.net
(integer) -1
127.0.0.1:6379> SET user:1 Jack EX 120
OK
127.0.0.1:6379> TTL user:1
(integer) 108
127.0.0.1:6379> DEL user:1
(integer) 1
127.0.0.1:6379> TTL user:1
(integer) -2
如果想了解更多命令,请参考:http://doc.redisfans.com/