php7实践指南-ch16PHP与Redis数据库安装配置

Redis是一种kev->value的缓存型数据库,使用内存存储数据,写入读取的速度非常快,常用于高速缓存。在一些高并发、大流量的网站系统中,常将Redis作为消息队列使用,用于减轻MySQL的读写压力。并且Redis提供的数据类型能够满足绝大多数应用场景,支持数据持久化、主从同步等。

16.1 关系型数据库与非关系型数据库

在第15章我们详细介绍过MySQL数据库的使用。MySQL是一种关系型数据库,我们可以把关系型数据库看成一个Excel表格,其中存储行、列的对应关系。关系型数据库能满足编程中一般的存储查询需求,随着网站业务量的增加,我们还需要存储许多数据,并且要求能够很快地将数据查询出来。这时关系型数据库MySQL就会稍显吃力。当网站的用户并发性非常高(高并发读写往往达到每秒上万次请求)时,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈,因为MySQL的数据存储是写入到磁盘上的。同时网站每天产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据表中查询的效率也是非常低的。

为了解决以上问题,NoSQL出现了。此后非关系型、分布式数据存储得到了快速发展,它们不保证关系数据的ACID特性。NoSQL概念在2009年被提了出来。NoSQL最常见的解释是“non-relational”,“Not Only SQL”也被很多人接受。(“NoSQL”一词最早于1998年被用于一个轻量级的关系数据库的名字。)

针对关系型数据库的不足,出现了很多NoSQL产品。这些数据库中很大一部分都是针对某些特定应用需求出现的,对于该类应用具有极高的性能。依据结构化方法以及应用场合的不同,主要分为以下几类:

● 面向高性能并发读写的key-value数据库 主要特点是具有极高的并发读写性能。Redis、Tokyo Cabinet、Flare就是这类数据库的代表。

● 面向海量数据访问的面向文档数据库 这类数据库的特点是可以在海量的数据中快速查询数据,典型代表为MongoDB和CouchDB。

● 面向可扩展性的分布式数据库 相对于传统数据库存在的可扩展性缺陷,这类数据库可以适应数据量的增加以及数据结构的变化。

16.2 Redis的安装使用

本书只介绍NoSQL数据库中的一种,即Redis数据库。Redis是一个高级开源的key-value数据库存储系统。支持string、list、set、zset、hash 5种数据存储类型,支持对数据的多种操作,能够满足绝大部分业务需求。Redis中的数据都是缓存在内存中的,比读取存储在硬盘上的数据速度要快很多。Redis支持数据的持久化操作,可通过配置周期性地将内存中的数据写入磁盘,提高了数据的安全性。Redis还支持主从同步,更好地解决了高并发的问题。

Redis支持多种语言的客户端调用,如PHP、Python、Ruby等。Redis支持在Linux、Windows、MacOS系统中运行,但在实际应用场景中推荐使用Linux系统。本节介绍的Redis使用是在CentOS上运行的。

在Linux系统上安装Redis

可在Redis官方网站(http://redis.io/)下载到Redis安装包。Redis采用“主版本号.次版本号.补丁版本号”的命名规则。在次版本号的位置上,使用偶数表示稳定版本,如1.2、2.0、2.2、2.4。奇数代表测试版本,比如版本号2.9.x代表测试版本,那么3.0将会是2.9.x的稳定版本。目前Redis的稳定版本是3.2.3。

配置文件的主要参数说明如下:

●Daemonize是否以后台进程运行,默认为no。

● Pidfile若以后台进程运行,则需指定一个pid,默认为/var/run/redis.pid。

● Bind绑定主机IP,默认值为127.0.0.1。

● Port监听端口,默认为6379。

● Timeout超时时间,默认为300(秒)。

● Loglevel日志记录等级,有4个可选值,即debug、verbose(默认值)、notice、warning。

● Logfile日志记录方式,默认值为stdout。

● Databases可用数据库数,默认值为16,默认数据库为0。

● save <seconds> <changes> 指出在多长时间内有多少次更新操作就将数据同步到数据文件。

可以多个条件配合使用,比如默认配置文件中就设置了以下3个条件:


save 900 1
save 300 10
save 60 10000

(15分钟)内至少有1个key被改变。

(5分钟)内至少有300个key被改变。

60秒内至少有10000个key被改变。

● Rdbcompression存储至本地数据库时是否压缩数据,默认为yes。

● Dbfilename本地数据库文件名,默认值为dump.rdb。

● Dir本地数据库存放路径,默认值为./。

● slaveof <masterip> <masterport> 当本机为从服务时,设置主服务的IP及端口。

● masterauth <master-password> 当本机为从服务时,设置主服务的连接密码。

● requirepass连接密码。

● maxclients最大客户端连接数,默认不限制。

         ● maxmemory <bytes> 设置最大内存,达到最大内存设置后,Redis会先尝试清除已到期或即将到期的Key,当用此方法处理后仍达到最大内存设置,将无法再进行写入操作。

        ● appendonly是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面的save条件来同步的,所以有的数据会在一段时间内只存在于内存中,默认值为no。

● appendfilename更新日志文件名,默认值为appendonly.aof。

     ● appendfsync更新日志条件,共有3个可选值。no表示等操作系统进行数据缓存同步到磁盘,always表示每次更新操作后手动调用fsync()将数据写到磁盘,everysec表示每秒同步一次(默认值)。

● vm-enabled是否使用虚拟内存,默认值为no。

● vm-swap-file虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享。

●vm-max-memory将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置得多小,所有索引数据都是内存存储的(Redis的索引数据就是keys),也就是说,当vm-max-memory设置为0时,其实是所有value都存在于磁盘,默认值为0。

d:\Program Files\Redis>redis-server.exe
[4344] 26 Jan 09:41:40.452 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
[4344] 26 Jan 09:41:40.452 # Redis version=5.0.10, bits=64, commit=1c047b68, modified=0, pid=4344, just started
[4344] 26 Jan 09:41:40.456 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server.exe /path/to/redis.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 5.0.10 (1c047b68/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 4344
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[4344] 26 Jan 09:41:40.479 # Server initialized
[4344] 26 Jan 09:41:40.481 * DB loaded from disk: 0.000 seconds
[4344] 26 Jan 09:41:40.482 * Ready to accept connections

在启动Redis时可指定使用的配置文件,Redis支持多个端口启动,只需在配置文件中设置port的值不同,然后分别在启动Redis服务时指定对应配置文件即可,例如:

如果需要在端口6380启动Redis,只需在文件/etc/redis.conf中设置port为6380即可。

使用redis-cli可用来对Redis进行操作。

至此,我们已经介绍完了如何下载、安装、启动Redis。

16.3 Redis数据类型

字符串(String)

set 命令 set命令用于设置给定 key 的值。如果 key 已经存储其他值,set 就覆写旧值,且无视类型。

get 命令 Get 命令用于获取指定 key 的值。如果 key 不存在,返回 nil 。如果key 储存的值不是字符串类型,返回一个错误。

127.0.0.1:6379> LPUSH db redis mongodb mysql
(integer) 3
127.0.0.1:6379> GET db
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379>

getrange 命令用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。 

127.0.0.1:6379> GETRANGE mykey 0 3
"this"
127.0.0.1:6379> GETRANGE mykey 0 -1
"this is my test key"

getset 命令用于设置指定 key 的值,并返回 key 的旧值。 

127.0.0.1:6379> GETSET db mongodb
(nil)
127.0.0.1:6379> GET db
"mongodb"
127.0.0.1:6379> GETSET db redis
"mongodb"
127.0.0.1:6379> GET db
"redis"

mget 命令返回所有(一个或多个)给定 key 的值。 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。

127.0.0.1:6379> SET key1 "hello"
OK
127.0.0.1:6379> SET key2 "world"
OK
127.0.0.1:6379> mget key1 key2 someOtherKey
1) "hello"
2) "world"
3) (nil)

setex 命令为指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。.

127.0.0.1:6379> setex mykey 60 redis
OK
127.0.0.1:6379> ttl mykey
(integer) 55
127.0.0.1:6379> get mykey
"redis"

 setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值。 

127.0.0.1:6379> exists job
(integer) 0
127.0.0.1:6379> setnx job "programmer"
(integer) 1
127.0.0.1:6379> setnx job "code-famer"
(integer) 0
127.0.0.1:6379> get  job
"programmer"

setrange 命令用指定的字符串覆盖给定 key 所储存的字符串值,覆盖的位置从偏移量 offset 开始。

127.0.0.1:6379> set keys "
Invalid argument(s)
127.0.0.1:6379> set keys "Hello World"
OK
127.0.0.1:6379> setrange keys 6 "Redis"
(integer) 11
127.0.0.1:6379> get keys
"Hello Redis"
127.0.0.1:6379>

strlen 命令用于获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错误。

127.0.0.1:6379> set mykey "hello world"
OK
127.0.0.1:6379> strlen mykey
(integer) 11
127.0.0.1:6379> strlen nonexisting
(integer) 0
127.0.0.1:6379>

 mset 命令用于同时设置一个或多个 key-value 对。

127.0.0.1:6379> mset key1 "Hello" key2 "World"
OK
127.0.0.1:6379> get key1
"Hello"
127.0.0.1:6379> get key2
"World"

msetnx 命令用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。

# 对不存在的 key 进行 MSETNX

redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1

redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"


# MSET 的给定 key 当中有已存在的 key

redis> MSETNX rmdbs "Sqlite" language "python"  # rmdbs 键已经存在,操作失败
(integer) 0

redis> EXISTS language                          # 因为 MSET 是原子性操作,language 没有被设置
(integer) 0

redis> GET rmdbs                                # rmdbs 也没有被修改
"MySQL"

psetex 命令以毫秒为单位设置 key 的生存时间。

127.0.0.1:6379> psetex mykey 5000 "Hello"
OK
127.0.0.1:6379> PTTL mykey
(integer) 2160

Incr 命令将 key 中储存的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。

127.0.0.1:6379> set page_view 20
OK
127.0.0.1:6379> get page_view
"20"
127.0.0.1:6379> incr page_view
(integer) 21
127.0.0.1:6379>

Incrby 命令将 key 中储存的数字加上指定的增量值。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。

# key 存在且是数字值

redis> SET rank 50
OK

redis> INCRBY rank 20
(integer) 70

redis> GET rank
"70"


# key 不存在时

redis> EXISTS counter
(integer) 0

redis> INCRBY counter 30
(integer) 30

redis> GET counter
"30"


# key 不是数字值时

redis> SET book "long long ago..."
OK

redis> INCRBY book 200
(error) ERR value is not an integer or out of range

 Incrbyfloat 命令为 key 中所储存的值加上指定的浮点数增量值。如果 key 不存在,那么incrbyfloat 会先将 key 的值设为 0 ,再执行加法操作。

# 值和增量都不是指数符号

redis> SET mykey 10.50
OK

redis> INCRBYFLOAT mykey 0.1
"10.6"


# 值和增量都是指数符号

redis> SET mykey 314e-2
OK

redis> GET mykey                # 用 SET 设置的值可以是指数符号
"314e-2"

redis> INCRBYFLOAT mykey 0      # 但执行 INCRBYFLOAT 之后格式会被改成非指数符号
"3.14"


# 可以对整数类型执行

redis> SET mykey 3
OK

redis> INCRBYFLOAT mykey 1.1
"4.1"


# 后跟的 0 会被移除

redis> SET mykey 3.0
OK

redis> GET mykey                                    # SET 设置的值小数部分可以是 0
"3.0"

redis> INCRBYFLOAT mykey 1.000000000000000000000    # 但 INCRBYFLOAT 会将无用的 0 忽略掉,有需要的话,将浮点变为整数
"4"

redis> GET mykey
"4"

decr 命令将 key 中储存的数字值减一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 decr 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。

# 对存在的数字值 key 进行 DECR

redis> SET failure_times 10
OK

redis> DECR failure_times
(integer) 9


# 对不存在的 key 值进行 DECR

redis> EXISTS count
(integer) 0

redis> DECR count
(integer) -1


# 对存在但不是数值的 key 进行 DECR

redis> SET company YOUR_CODE_SUCKS.LLC
OK

redis> DECR company
(error) ERR value is not an integer or out of range

 decrby 命令将 key 所储存的值减去指定的减量值。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 decrby 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有符号数字表示之内。

哈希(Hash)

hash 特别适合用于存储对象

​ Redis哈希对象常常用来缓存一些对象信息,如用户信息、商品信息、配置信息等

 hdel 命令用于删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HDEL myhash field1
(integer) 1
redis 127.0.0.1:6379> HDEL myhash field2
(integer) 0

 hexists 命令用于查看哈希表的指定字段是否存在。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HEXISTS myhash field1
(integer) 1
redis 127.0.0.1:6379> HEXISTS myhash field2
(integer) 0

hget 命令用于返回哈希表中指定字段的值。

# 字段存在

redis> HSET site redis redis.com
(integer) 1

redis> HGET site redis
"redis.com"


# 字段不存在

redis> HGET site mysql
(nil)

 hgetall 命令用于返回哈希表中,所有的字段和值。

redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
redis> 

 hincrby 命令用于为哈希表中的字段值加上指定增量值。增量也可以为负数,相当于对指定字段进行减法操作。如果哈希表的 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。如果指定的字段不存在,那么在执行命令前,字段的值被初始化为 0 。对一个储存字符串值的字段执行 HINCRBY 命令将造成一个错误。本操作的值被限制在 64 位(bit)有符号数字表示之内。

redis> HSET myhash field 5
(integer) 1
redis> HINCRBY myhash field 1
(integer) 6
redis> HINCRBY myhash field -1
(integer) 5
redis> HINCRBY myhash field -10
(integer) -5
redis> 

hincrbyfloat 命令用于为哈希表中的字段值加上指定浮点数增量值。如果指定的字段不存在,那么在执行命令前,字段的值被初始化为 0 。

redis> HSET mykey field 10.50
(integer) 1
redis> HINCRBYFLOAT mykey field 0.1
"10.6"
redis> HINCRBYFLOAT mykey field -5
"5.6"
redis> HSET mykey field 5.0e3
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2
"5200"
redis> 

hkeys 命令用于获取哈希表中的所有域(field)。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HSET myhash field2 "bar"
(integer) 1
redis 127.0.0.1:6379> HKEYS myhash
1) "field1"
2) "field2"

 hlen 命令用于获取哈希表中字段的数量。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HSET myhash field2 "bar"
(integer) 1
redis 127.0.0.1:6379> HLEN myhash
(integer) 2

 hmget 命令用于返回哈希表中,一个或多个给定字段的值。如果指定的字段不存在于哈希表,那么返回一个 nil 值。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HSET myhash field2 "bar"
(integer) 1
redis 127.0.0.1:6379> HMGET myhash field1 field2 nofield
1) "foo"
2) "bar"
3) (nil)

 hmset 命令用于同时将多个 field-value (字段-值)对设置到哈希表中。此命令会覆盖哈希表中已存在的字段。如果哈希表不存在,会创建一个空哈希表,并执行 HMSET 操作。

redis 127.0.0.1:6379> HMSET myhash field1 "Hello" field2 "World"
OK
redis 127.0.0.1:6379> HGET myhash field1
"Hello"
redis 127.0.0.1:6379> HGET myhash field2
"World"

 hset 命令用于为哈希表中的字段赋值 。如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。如果字段已经存在于哈希表中,旧值将被覆盖。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
OK
redis 127.0.0.1:6379> HGET myhash field1
"foo"

redis 127.0.0.1:6379> HSET website google "www.g.cn"       # 设置一个新域
(integer) 1

redis 127.0.0.1:6379>HSET website google "www.google.com" # 覆盖一个旧域
(integer) 0

 hsetnx 命令用于为哈希表中不存在的的字段赋值 。如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。如果字段已经存在于哈希表中,操作无效。如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。

redis 127.0.0.1:6379> HSETNX myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HSETNX myhash field1 "bar"
(integer) 0
redis 127.0.0.1:6379> HGET myhash field1
"foo"

redis 127.0.0.1:6379> HSETNX nosql key-value-store redis
(integer) 1

redis 127.0.0.1:6379> HSETNX nosql key-value-store redis       # 操作无效, key-value-store 已存在
(integer) 0

hvals 命令返回哈希表所有域(field)的值。

redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HSET myhash field2 "bar"
(integer) 1
redis 127.0.0.1:6379> HVALS myhash
1) "foo"
2) "bar"

# 空哈希表/不存在的key

redis 127.0.0.1:6379> EXISTS not_exists
(integer) 0

redis 127.0.0.1:6379> HVALS not_exists
(empty list or set)

hscan 命令用于迭代哈希表中的键值对。

语法

redis HSCAN 命令基本语法如下:

HSCAN key cursor [MATCH pattern] [COUNT count]
  • cursor - 游标。
  • pattern - 匹配的模式。
  • count - 指定从数据集里返回多少元素,默认值为 10 。

 

返回值

返回的每个元素都是一个元组,每一个元组元素由一个字段(field) 和值(value)组成。

实例

> HMSET sites google "google.com" runoob "runoob.com" weibo "weibo.com" 4 "taobao.com"
OK
> HSCAN sites 0 match "run*"
1) "0"
2) 1) "runoob"
2) "runoob.com"

Redis 列表(List)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

 blpop 命令移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

redis 127.0.0.1:6379> BLPOP list1 100

brpop 命令移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

redis> DEL list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BRPOP list1 list2 0
1) "list1"
2) "c"

brpoplpush 命令从列表中取出最后一个元素,并插入到另外一个列表的头部; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

# 非空列表

redis> BRPOPLPUSH msg reciver 500
"hello moto"                        # 弹出元素的值
(3.38s)                             # 等待时长

redis> LLEN reciver
(integer) 1

redis> LRANGE reciver 0 0
1) "hello moto"


# 空列表

redis> BRPOPLPUSH msg reciver 1
(nil)
(1.34s)

lindex 命令用于通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

redis 127.0.0.1:6379> LPUSH mylist "World"
(integer) 1

redis 127.0.0.1:6379> LPUSH mylist "Hello"
(integer) 2

redis 127.0.0.1:6379> LINDEX mylist 0
"Hello"

redis 127.0.0.1:6379> LINDEX mylist -1
"World"

redis 127.0.0.1:6379> LINDEX mylist 3        # index不在 mylist 的区间范围内
(nil)

 linsert 命令用于在列表的元素前或者后插入元素。当指定元素不存在于列表中时,不执行任何操作。当列表不存在时,被视为空列表,不执行任何操作。如果 key 不是列表类型,返回一个错误。

redis> RPUSH mylist "Hello"
(integer) 1
redis> RPUSH mylist "World"
(integer) 2
redis> LINSERT mylist BEFORE "World" "There"
(integer) 3
redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"
redis> 

Redis Llen 命令用于返回列表的长度。 如果列表 key 不存在,则 key 被解释为一个空列表,返回 0 。 如果 key 不是列表类型,返回一个错误。

redis 127.0.0.1:6379> RPUSH list1 "foo"
(integer) 1
redis 127.0.0.1:6379> RPUSH list1 "bar"
(integer) 2
redis 127.0.0.1:6379> LLEN list1
(integer) 2

Redis Lpop 命令用于移除并返回列表的第一个元素。

redis 127.0.0.1:6379> RPUSH list1 "foo"
(integer) 1
redis 127.0.0.1:6379> RPUSH list1 "bar"
(integer) 2
redis 127.0.0.1:6379> LPOP list1
"foo"

lpush 命令将一个或多个值插入到列表头部。 如果 key 不存在,一个空列表会被创建并执行 lpush操作。 当 key 存在但不是列表类型时,返回一个错误。

l注意:在Redis 2.4版本以前的 LPUSH 命令,都只接受单个 value 值。

127.0.0.1:6379> LPUSH list1 "foo"
(integer) 1
127.0.0.1:6379> LPUSH list1 "bar"
(integer) 2
127.0.0.1:6379> LRANGE list1 0 -1
1) "bar"
2) "foo"

Redis Lpushx 将一个值插入到已存在的列表头部,列表不存在时操作无效。

127.0.0.1:6379> lpush list1 "foo" "bar"
(integer) 2
127.0.0.1:6379> lpushx list2 "bar"
(integer) 0
127.0.0.1:6379> lrange list1 0 -1
1) "bar"
2) "foo"
127.0.0.1:6379> lra

Redis Lrange 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LRANGE mylist 0 0
1) "one"
redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist -100 100
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist 5 10
(empty list or set)
redis> 

Redis Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。

COUNT 的值可以是以下几种:

  • count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
  • count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
  • count = 0 : 移除表中所有与 VALUE 相等的值。
redis> RPUSH mylist "hello"
(integer) 1
redis> RPUSH mylist "hello"
(integer) 2
redis> RPUSH mylist "foo"
(integer) 3
redis> RPUSH mylist "hello"
(integer) 4
redis> LREM mylist -2 "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "foo"
redis> 

Redis Lset 通过索引来设置元素的值。

当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。

redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 4
redis 127.0.0.1:6379> LSET mylist 0 "bar"
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1: "bar"
2) "hello"
3) "foo"
4) "hello"

Redis Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist "bar"
(integer) 4
redis 127.0.0.1:6379> LTRIM mylist 1 -1
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"
3) "bar"

rpop 命令用于移除列表的最后一个元素,返回值为移除的元素。

redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> RPOP mylist
"three"
redis> LRANGE mylist 0 -1
1) "one"
2) "two"
redis> 

 rpoplpush 命令用于移除列表的最后一个元素,并将该元素添加到另一个列表并返回。

redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist "bar"
(integer) 3
redis 127.0.0.1:6379> RPOPLPUSH mylist myotherlist
"bar"
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"

rpush 命令用于将一个或多个值插入到列表的尾部(最右边)。

如果列表不存在,一个空列表会被创建并执行 RPUSH 操作。 当列表存在但不是列表类型时,返回一个错误。

注意:在 Redis 2.4 版本以前的 RPUSH 命令,都只接受单个 value 值。

redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist "bar"
(integer) 3
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"
3) "bar"

Redis Rpushx 命令用于将一个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效。

redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 2
redis 127.0.0.1:6379> RPUSHX mylist2 "bar"
(integer) 0
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"

Redis 集合(Set)

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

Redis Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。

假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合。

当集合 key 不是集合类型时,返回一个错误。

注意:在 Redis2.4 版本以前, SADD 只接受单个成员值。

redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 0
redis 127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "foo"

Redis Scard 命令返回集合中元素的数量。

redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 0
redis 127.0.0.1:6379> SCARD myset
(integer) 2

Redis Sdiff 命令返回第一个集合与其他集合之间的差异,也可以认为说第一个集合中独有的元素。不存在的集合 key 将视为空集。

差集的结果来自前面的 FIRST_KEY ,而不是后面的 OTHER_KEY1,也不是整个 FIRST_KEY OTHER_KEY1..OTHER_KEYN 的差集。

实例:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFF key1 key2
1) "a"
2) "b"
redis> 

Redis Sdiffstore 命令将给定集合之间的差集存储在指定的集合中。如果指定的集合 key 已存在,则会被覆盖。

redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SDIFFSTORE destset myset myset2
(integer) 2
redis 127.0.0.1:6379> SMEMBERS destset
1) "foo"
2) "bar"

Redis Sinter 命令返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。

redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SINTER myset myset2
1) "hello"

Redis Sinterstore 命令将给定集合之间的交集存储在指定的集合中。如果指定的集合已经存在,则将其覆盖。

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SINTERSTORE myset myset1 myset2
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset
1) "hello"

Redis Sismember 命令判断成员元素是否是集合的成员。

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "world"
(integer) 0

Redis Smembers 命令返回集合中的所有的成员。 不存在的集合 key 被视为空集合。

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset1
1) "World"
2) "Hello"

Redis Smove 命令将指定成员 member 元素从 source 集合移动到 destination 集合。

SMOVE 是原子性操作。

如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。

当 destination 集合已经包含 member 元素时, SMOVE 命令只是简单地将 source 集合中的 member 元素删除。

当 source 或 destination 不是集合类型时,返回一个错误。

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "foo"
(integer) 1
redis 127.0.0.1:6379> SMOVE myset1 myset2 "bar"
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset1
1) "World"
2) "Hello"
redis 127.0.0.1:6379> SMEMBERS myset2
1) "foo"
2) "bar"

Redis Spop 命令用于移除集合中的指定 key 的一个或多个随机元素,移除后会返回移除的元素。

该命令类似 Srandmember 命令,但 SPOP 将随机元素从集合中移除并返回,而 Srandmember 则仅仅返回随机元素,而不对集合进行任何改动。

redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SPOP myset
"one"
redis> SMEMBERS myset
1) "three"
2) "two"
redis> SADD myset "four"
(integer) 1
redis> SADD myset "five"
(integer) 1
redis> SPOP myset 3
1) "five"
2) "four"
3) "two"
redis> SMEMBERS myset
1) "three"
redis> 

Redis Srandmember 命令用于返回集合中的一个随机元素。

从 Redis 2.6 版本开始, Srandmember 命令接受可选的 count 参数:

  • 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
  • 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。

该操作和 SPOP 相似,但 SPOP 将随机元素从集合中移除并返回,而 Srandmember 则仅仅返回随机元素,而不对集合进行任何改动。

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SRANDMEMBER myset1
"bar"
redis 127.0.0.1:6379> SRANDMEMBER myset1 2
1) "Hello"
2) "world"

Redis Srem 命令用于移除集合中的一个或多个成员元素,不存在的成员元素会被忽略。

当 key 不是集合类型,返回一个错误。

在 Redis 2.4 版本以前, SREM 只接受单个成员值。

redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SREM myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SREM myset1 "foo"
(integer) 0
redis 127.0.0.1:6379> SMEMBERS myset1
1) "bar"
2) "world"

Redis Sunion 命令返回给定集合的并集。不存在的集合 key 被视为空集。

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNION key1 key2
1) "a"
2) "c"
3) "b"
4) "e"
5) "d"
redis> 

Redis Sunionstore 命令将给定集合的并集存储在指定的集合 destination 中。如果 destination 已经存在,则将其覆盖。

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNIONSTORE key key1 key2
(integer) 5
redis> SMEMBERS key
1) "c"
2) "b"
3) "e"
4) "d"
5) "a"
redis> 

Redis Sscan 命令用于迭代集合中键的元素,Sscan 继承自 Scan

> SADD myset1 "Google"
(integer) 1
> SADD myset1 "Runoob"
(integer) 1
> SADD myset1 "Taobao"
(integer) 1
> SSCAN myset1 0 match R*
1) "0"
2) 1) "Runoob"

Redis 有序集合(sorted set)

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

redis 127.0.0.1:6379> ZADD runoobkey 1 redis
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 2 mongodb
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql
(integer) 0
redis 127.0.0.1:6379> ZADD runoobkey 4 mysql
(integer) 0
redis 127.0.0.1:6379> ZRANGE runoobkey 0 10 WITHSCORES

1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "4"

在以上实例中我们通过命令 ZADD 向 redis 的有序集合中添加了三个值并关联上分数。

 

Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。

如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。

分数值可以是整数值或双精度浮点数。

如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。

当 key 存在但不是有序集类型时,返回一个错误。

注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 1 "uno"
(integer) 1
redis> ZADD myzset 2 "two" 3 "three"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
redis> 

Redis Zcard 命令用于计算集合中元素的数量。

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZCARD myzset
(integer) 2
redis> 

Redis Zcount 命令用于计算有序集合中指定分数区间的成员数量。

redis 127.0.0.1:6379> ZADD myzset 1 "hello"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 1 "foo"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 2 "world" 3 "bar"
(integer) 2
redis 127.0.0.1:6379> ZCOUNT myzset 1 3
(integer) 4

Redis Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。

默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。

# 有序集 mid_test
redis 127.0.0.1:6379> ZADD mid_test 70 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 70 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 99.5 "Tom"
(integer) 1

# 另一个有序集 fin_test
redis 127.0.0.1:6379> ZADD fin_test 88 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 75 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 99.5 "Tom"
(integer) 1

# 交集
redis 127.0.0.1:6379> ZINTERSTORE sum_point 2 mid_test fin_test
(integer) 3

# 显示有序集内所有成员及其分数值
redis 127.0.0.1:6379> ZRANGE sum_point 0 -1 WITHSCORES     
1) "Han Meimei"
2) "145"
3) "Li Lei"
4) "158"
5) "Tom"
6) "199"

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis数据库可以通过以下几种方式进行安装。 在Windows上安装Redis,可以按照以下步骤进行操作: 1. 下载Redis安装包并解压缩。 2. 配置环境变量,将Redis安装路径添加到系统的PATH变量。 3. 验证安装是否成功,可以通过命令行输入redis-cli命令来连接Redis。 4. 连接Redis后,可以进行一些简单的测试,比如设置一个key并进行操作。 在Linux上安装Redis,有两种方式可以选择: 1. 源码安装方式:首先检查是否安装了gcc编译器,如果没有则需要安装。然后下载Redis的压缩包并解压缩,编译并检验安装。最后修改配置文件以配置Redis。 2. 命令方式安装:通过命令搜索可安装Redis版本,然后使用相应的命令进行安装安装完成后,可以检查安装是否成功,并找到配置文件的位置。 另外,如果需要连接远程的Redis数据库,可以通过修改Redis配置文件redis.conf来实现。将bind 127.0.0.1改为bind 0.0.0.0,将protected-mode yes改为protected-mode no。然后运行Redis管理工具即可连接远程数据库。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [Windows、Linux下安装Redis图文教程](https://blog.csdn.net/chen15369337607/article/details/125353358)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Redis安装教程(超详细)](https://blog.csdn.net/X_lsod/article/details/123263429)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值