NoSQL之Redis

1、关系数据库 VS 非关系型数据库

(1) 关系型数据库

关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。
SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。
主流的关系型数据库包括Oracle、MySQL、SQL Server、Microsoft Access、DB2、PostgreSQL等。
以上数据库在使用的时候必须先建库建表设计表结构,然后存储数据的时候按表结构去存,如果数据与表结构不匹配就会存储失败。

(2) 非关系型数据库

NoSQL(NoSQL = Not Only SQL ),意思是"不仅仅是SQL",是非关系型数据库的总称。
除了主流的关系型数据库外的数据库,都认为是非关系型。
不需要预先建库建表定义数据存储表结构,每条记录可以有不同的数据类型和字段个数(比如微信群聊里的文字、图片、视频、音乐等)。
主流的NoSQL数据库有Redis、MongBD、Hbase、Memcached、ElasticSearch、TSDB等。

(3)关系型数据库和非关系型数据库区别

1)数据存储方式不同

关系型和非关系型数据库的主要差异是数据存储的方式。关系型数据天然就是表格式的,因此存储在数据表的行和列中。数据表可以彼此关联协作存储,也很容易提取数据。
与其相反,非关系型数据不适合存储在数据表的行和列中,而是大块组合在一起。非关系型数据通常存储在数据集中,就像文档、键值对或者图结构。你的数据及其特性是选择数据存储和提取方式的首要影响因素。

2)扩展方式不同

SQL和NoSQL数据库最大的差别可能是在扩展方式上,要支持日益增长的需求当然要扩展。
要支持更多并发量,SQL数据库是纵向扩展,也就是说提高处理能力,使用速度更快速的计算机,这样处理相同的数据集就更快了。因为数据存储在关系表中,操作的性能瓶颈可能涉及很多个表,这都需要通过提高计算机性能来克服。虽然SQL数据库有很大扩展空间,但最终肯定会达到纵向扩展的上限。
而NoSQL数据库是横向扩展的。因为非关系型数据存储天然就是分布式的,NoSQL数据库的扩展可以通过给资源池添加更多普通的数据库服务器(节点)来分担负载。

3)对事务性支持不同

关系型数据库遵循ACID规则(原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability))。
NoSQL数据库遵循BASE原则(基本可用(Basically Availble)、软/柔性事务(Soft-state)、最终一致性(Eventual Consistency))。
由于关系型数据库的数据强一致性,所以对事务的支持很好。关系型数据库支持对事务原子性细粒度控制,并且易于回滚事务。
NoSQL数据库是在CAP(一致性、可用性、分区容忍度)中任选两项,因为基于节点的分布式系统中,不可能同时全部满足,所以对事务的支持不是很好。

(4)非关系型数据库产生背景

可用于应对Web2.0纯动态网站类型的三高问题(高并发、高性能、高可用)。
(1)High performance------对数据库高并发读写需求
(2)Huge Storage------对海量数据高效存储与访问需求
(3)High Scalability && High Availability------对数据库高可扩展性与高可用性需求

关系型数据库和非关系型数据库都有各自的特点与应用场景,两者的紧密结合将会给Web2.0的数据库发展带来新的思路。让关系型数据库关注在关系上和对数据的一致性保障,非关系型数据库关注在存储和高效率上。例如,在读写分离的MySQL数据库环境中,可以把经常访问的数据存储在非关系型数据库中,提升访问速度。

2、Redis简介

(1) Redis概述

Redis(远程字典服务器) 是一个开源的、使用C语言编写的NoSQL数据库。
Redis基于内存运行并支持持久化,采用key-value(键值对)的存储形式,是目前分布式架构中不可或缺的一环。

Redis服务器程序是单进程模型,也就是在一台服务器上可以同时启动多个Redis进程,Redis的实际处理速度则是完全依靠于主进程的执行效率。若在服务器上只运行一个Redis进程,当多个客户端同时访问时,服务器的处理能力是会有一定程度的下降;若在同一台服务器上开启多个Redis进程,Redis在提高并发处理能力的同时,会给服务器的CPU造成很大压力。即:在实际生产环境中,需要根据实际的需求来决定开启多少个Redis进程。若对高并发要求更高一些,可能会考虑在同一台服务器上开启多个进程。若CPU资源比较紧张,采用单进程即可。

(2)Redis的优点

(1)具有极高的数据读写速度:数据读取的速度最高可达到10000次/s,数据写入速度最高可达到81000次/s。
(2)支持丰富的数据类型:支持key-value、Strings、Lists、Hashes、Sets及Sorted Sets等数据类型操作。
(3)支持数据的持久化:可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
(4)原子性:Redis所有操作都是原子性的。
(5)支持数据备份:即master-salve模式的数据备份。

(3)Redis使用场景

Redis作为基于内存运行的数据库,是一个高性能的缓存,一般应用在Session缓存、队列、排行榜、计数器、最近最热文章、最近最热评论、发布订阅等。
Redis适用于数据实时性要求高、数据存储有过期和淘汰特征的、不需要持久化或者只需要保证弱一致性、逻辑简单的场景。
我们通常会将部分数据放入缓存中,来提高访问速度,然后数据库承担存储的工作。

(4)关于Redis的高频问题

哪些数据适合放入缓存中?

  • 即时性:例如查询最新的物流状态信息。
  • 数据一致性要求不高:例如门店信息,修改后,数据库中已经改了,五分钟后缓存中才是最新的,但不影响功能使用。
  • 访问量大且更新频率不高,例如网站首页的广告信息,访问量大,但是不会经常变化。
    Redis为什么这么快?

Redis是一款纯内存结构,避免了磁盘I/O等耗时操作。
Redis命令处理的核心模块为单线程,不存在多线程切换而消耗CPU,不用考虑各种锁的问题,不存在加锁、释放锁的操作,没有因为可能出现死锁而导致性能消耗。
采用了I/O多路复用机制,大大提升了并发效率。

3、安装部署Redis

(1)系统初始化

复制代码
[root@zx1 ~]# systemctl stop firewalld
[root@zx1 ~]# setenforce 0
[root@zx1 ~]#

(2)修改内核参数

复制代码
[root@zx1 ~]# vim /etc/sysctl.conf
在文件末行添加此内容
vm.overcommit_memory = 1                   #内核允许超量使用内存直到用完为止,防止OOM杀死进程
net.core.somaxconn = 20480                 #指定处于监听状态的连接请求队列的最大长度

[root@zx1 ~]# sysctl -p                    #加载
vm.overcommit_memory = 1
net.core.somaxconn = 20480
[root@zx1 ~]#

(3)安装redis

复制代码
[root@zx1 ~]# yum install -y gcc gcc-c++ make
[root@zx1 ~]# cd /opt/
[root@zx1 opt]# ls
redis-7.0.13.tar.gz  rh
[root@zx1 opt]# tar xf redis-7.0.13.tar.gz
[root@zx1 opt]# cd redis-7.0.13/
[root@zx1 redis-7.0.13]# ls
00-RELEASENOTES  CODE_OF_CONDUCT.md  COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  sentinel.conf  tests   utils
BUGS             CONTRIBUTING.md     deps     Makefile  README.md  runtest     runtest-moduleapi  SECURITY.md       src            TLS.md
[root@zx1 redis-7.0.13]# make
[root@zx1 redis-7.0.13]# make PREFIX=/usr/local/redis install

(4)创建redis工作目录,并创建redis程序用户

复制代码
[root@zx1 redis-7.0.13]# cd /usr/local/redis
[root@zx1 redis]# mkdir conf log data
[root@zx1 redis]# cd /opt/redis-7.0.13/
[root@zx1 redis-7.0.13]# cp redis.conf /usr/local/redis/conf/
[root@zx1 redis-7.0.13]# useradd -M -s /sbin/nologin redis
[root@zx1 redis-7.0.13]# chown -R redis:redis /usr/local/redis

(5)将redis的可执行文件路径加入到系统环境变量中

复制代码
[root@zx1 redis-7.0.13]# vim /etc/profile
#在末行添加此行内容
export PATH=$PATH:/usr/local/redis/bin

[root@zx1 redis-7.0.13]# source !$
source /etc/profile
[root@zx1 redis-7.0.13]#

(6)修改redis.conf配置文件

复制代码
[root@zx1 redis-7.0.13]# vim /usr/local/redis/conf/redis.conf
bind 20.0.0.10					            #87行,添加监听的主机地址
protected-mode no					            #111行,将本机访问保护模式设置no。如果开启了,那么在没有设定bind ip且没有设密码的情况下,Redis只允许接受本机的响应
port 6379										#138行,Redis默认的监听6379端口
tcp-backlog 20480                               #147行,修改参数为20480,与内核参数一致
daemonize yes									#309行,设置为守护进程,后台启动
pidfile /usr/local/redis/log/redis_6379.pid		#341行,指定PID文件
logfile "/usr/local/redis/log/redis_6379.log"	#354行,指定日志文件
dir /usr/local/redis/data						#504行,指定持久化文件所在目录
requirepass abc123							    #1037行,增加一行,设置redis密码

(7)定义systemd服务管理脚本

复制代码
[root@zx1 redis-7.0.13]# cd /usr/lib/systemd/system
[root@zx1 system]# vim redis-server.service

[Unit]
Description=Redis Server
After=network.target
 
[Service]
User=redis
Group=redis
Type=forking
TimeoutSec=0
PIDFile=/usr/local/redis/log/redis_6379.pid
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

[root@zx1 system]# systemctl daemon-reload
[root@zx1 system]# systemctl start redis-server.service
[root@zx1 system]# netstat -lntp | grep 6379
tcp        0      0 20.0.0.10:6379          0.0.0.0:*               LISTEN      74703/redis-server
[root@zx1 system]# redis-cli -h 20.0.0.10 -p 6379 -a 'abc123'
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
20.0.0.10:6379> quit
[root@zx1 system]#

4、Redis命令工具

复制代码
[root@zx1 system]# cd /usr/local/redis/bin/
[root@zx1 bin]# ls
redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis-sentinel  redis-server
[root@zx1 bin]#

redis-server:Redis服务器启动命令
redis-benchmark:性能测试工具,用于检测Redis在本机的运行效率
redis-check-aof:修复有问题的AOF持久化文件
redis-check-rdb:修复有问题的RDB持久化文件
redis-cli:Redis客户端命令行工具
redis-sentinel:Redis哨兵集群使用

(1)redis-cli命令行工具

语法:redis-cli -h host -p port [-a password]
-h :指定远程主机
-p :指定Redis服务的端口号
-a :指定密码,未设置数据库密码可以省略-a选项
若不添加任何选项表示,则使用127.0.0.1:6379连接本机上的Redis数据库

复制代码
redis-cli -h 20.0.0.10 -p 6379 -a 'abc123'

(2)redis-benchmark测试工具

redis-benchmark是官方自带的Redis性能测试工具,可以有效的测试Redis服务的性能。

基本的测试语法:redis-benchmark [选项] [选项值]。
-h :指定服务器主机名。
-p :指定服务器端口。
-s :指定服务器 socket
-c :指定并发连接数。 
-n :指定请求数。
-d :以字节的形式指定 SET/GET 值的数据大小。
-k :1=keep alive 0=reconnect 。
-r :SET/GET/INCR 使用随机 key, SADD 使用随机值。
-P :通过管道传输<numreq>请求。
-q :强制退出 redis。仅显示 query/sec 值。
--csv :以 CSV 格式输出。
-l :生成循环,永久执行测试。
-t :仅运行以逗号分隔的测试命令列表。
-I :Idle 模式。仅打开 N 个 idle 连接并等待。

#向 IP 地址为 192.168.9.140、端口为 6379 的 Redis 服务器发送 100 个并发连接与 100000 个请求测试性能

复制代码
redis-benchmark -h 20.0.0.10 -p 6379 -a 'abc123' -c 100 -n 100000

#测试存取大小为 100 字节的数据包的性能

复制代码
redis-benchmark -h 20.0.0.10 -p 6379 -q -d 100 -a 'abc123'

5、Redis数据库常用命令(string)

set:存放数据,还可以修改数据,命令格式为set key value
get:获取数据,命令格式为get key

复制代码
20.0.0.10:6379> set a zhuxiang
OK
20.0.0.10:6379> get a
"zhuxiang"
20.0.0.10:6379> set a ctt
OK
20.0.0.10:6379> get a
"ctt"
20.0.0.10:6379>

(1) keys命令

复制代码
20.0.0.10:6379> keys *	            #查看当前数据库中所有键
20.0.0.10:6379> keys z*		        #查看当前数据库中以v开头的数据
20.0.0.10:6379> keys z????		    #查看当前数据库中以z头后面包含任意四位的数据
20.0.0.10:6379> keys z???????		#查看当前数据库中以z开头后面包含任意七位的数据

20.0.0.10:6379> keys *
1) "c"
2) "a"
3) "b"
20.0.0.10:6379>

(2)exists命令判断键值是否存在

复制代码
20.0.0.10:6379> keys *
1) "c"
2) "a"
3) "b"
20.0.0.10:6379> exists a
(integer) 1
20.0.0.10:6379> exists d
(integer) 0
#判断该键是否存在,存在返回1,否则返回0。

(3)设置键过期时间

  1. ttl 键 #查看键当前的过期时间,-1 永不过期,-2 已过期

  2. expire 键 时间 #已存在键设置时间

  3. setex 键 过期时间 内容 #创建键并设置过期时间

复制代码
20.0.0.10:6379> keys *
1) "c"
2) "a"
3) "b"
20.0.0.10:6379> ttl a
(integer) -1
20.0.0.10:6379> expire a 3
(integer) 1
20.0.0.10:6379> ttl a
(integer) -2
20.0.0.10:6379> setex d 5 scj
OK
20.0.0.10:6379> get d
"scj"
20.0.0.10:6379> ttl d
(integer) 1
20.0.0.10:6379> ttl d
(integer) -2
20.0.0.10:6379> get d
(nil)
20.0.0.10:6379>

(5)rename是对已有key进行重命名(覆盖)

rename 键 新键 #重命名键,会覆盖已存在的键

复制代码
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "a"
4) "b"
20.0.0.10:6379> rename a aa
OK
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "b"
4) "aa"
20.0.0.10:6379> get aa
"ctt"
20.0.0.10:6379>

renamenx 键 新键 #重命名键,不会覆盖已存在的键

复制代码
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "bb"
4) "a"
20.0.0.10:6379> renamenx bb b
(integer) 1
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "b"
4) "a"
20.0.0.10:6379> get b
"123"
20.0.0.10:6379> get a
"ctt"
20.0.0.10:6379> renamenx a b
(integer) 0
20.0.0.10:6379> get a
"ctt"
20.0.0.10:6379> get b
"123"
20.0.0.10:6379>

(5)dbsize命令统计当前数据库中key的数目

dbsize #统计当前库中键的总数

复制代码
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "b"
4) "a"
20.0.0.10:6379> dbsize
(integer) 4
20.0.0.10:6379>

(6)修改密码

  1. config set requirepass '密码' #设置redis密码

  2. config get requirepass #查看redis密码

  3. config set requirepass '' #设置redis空密码

复制代码
20.0.0.10:6379> config set requirepass '123456'
OK
20.0.0.10:6379> quit
[root@zx1 bin]# redis-cli -h 20.0.0.10 -p 6379 -a '123456'
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
20.0.0.10:6379>
20.0.0.10:6379> config get requirepass
1) "requirepass"
2) "123456"
20.0.0.10:6379>

(7)删除键

del 键 #删除键

复制代码
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "b"
4) "a"
20.0.0.10:6379> del a
(integer) 1
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "b"
20.0.0.10:6379>

(8)type查看数据类型

type 键 #查看键的数据类型

复制代码
20.0.0.10:6379> keys *
1) "d"
2) "c"
3) "b"
4) "a"
20.0.0.10:6379> type a
string
20.0.0.10:6379> type b
string
20.0.0.10:6379>

(9)append追加内容

append 键 追加内容

复制代码
20.0.0.10:6379> get a
"1"
20.0.0.10:6379> append a 23
(integer) 3
20.0.0.10:6379> get a
"123"
20.0.0.10:6379>

(10)strlen mykey获取字符长度

strlen mykey #获取指定Key的字符长度。

复制代码
20.0.0.10:6379> set aa 123456
OK
20.0.0.10:6379> get aa
"123456"
20.0.0.10:6379> strlen aa
(integer) 6
20.0.0.10:6379>

(11)incr、decr递增和递减

  1. incr mykey #该Key的值递增1

  2. decr mykey #该Key的值递减1 ##只能递增递减数字

  3. incrby mykey 10 #增加指定的整数

  4. decrby mykey 5 #减少指定的整数

复制代码
20.0.0.10:6379> set zx 10
OK
20.0.0.10:6379> get zx
"10"
20.0.0.10:6379> incr zx
(integer) 11
20.0.0.10:6379> get zx
"11"
20.0.0.10:6379> decr zx
(integer) 10
20.0.0.10:6379> get zx
"10"
20.0.0.10:6379> incrby zx 20
(integer) 30
20.0.0.10:6379> get zx
"30"
20.0.0.10:6379> decrby zx 5
(integer) 25
20.0.0.10:6379> get zx
"25"
20.0.0.10:6379>

(12)setnx

setnx mykey hello #若键并不存在,会创建键
setnx mykey hello #若键并存在,设置没有产生任何效果

(13)mset、mget批量设置键

mset key1 "hello" key2 "world" #批量设置了key1和key2两个键。
mget key1 key2 #批量获取了key1和key2两个键的值。
msetnx key3 "hello" key5 "world" #批量设置了key3和key5两个键,若已存在不会产生任何效果,若不存在则会创建

复制代码
20.0.0.10:6379> mset 1 aa 2 bb
OK
20.0.0.10:6379> mget 1 2
1) "aa"
2) "bb"
20.0.0.10:6379> msetnx 1 dd 2 cc
(integer) 0
20.0.0.10:6379> mget 1 2
1) "aa"
2) "bb"
20.0.0.10:6379>

6、Redis多数据库常用命令

Redis支持多数据库,Redis默认情况下包含16个数据库,数据库名称是用数字0-15来依次命名。
多数据库相互独立,互不干扰。

复制代码
[root@zx1 bin]# vim /usr/local/redis/conf/redis.conf

(1)切换库

select 库ID #切换库,默认库ID为 0~15

复制代码
20.0.0.10:6379> select 10
OK
20.0.0.10:6379[10]> select 0
OK
20.0.0.10:6379>

(2)移动库

move 键 库ID #移动键到指定的库,在原来库上创建相同的键名移动到刚制定的库,会执行失败,不能移动相同名字的键

复制代码
20.0.0.10:6379> keys *
1) "d"
2) "2"
3) "zx"
4) "c"
5) "b"
6) "1"
7) "a"
8) "aa"
20.0.0.10:6379> get aa
"123456"
20.0.0.10:6379> move aa 10
(integer) 1
20.0.0.10:6379> select 10
OK
20.0.0.10:6379[10]> keys *
1) "aa"
20.0.0.10:6379[10]> get aa
"123456"
20.0.0.10:6379[10]> select 0
OK
20.0.0.10:6379> keys *
1) "d"
2) "2"
3) "zx"
4) "c"
5) "b"
6) "1"
7) "a"
20.0.0.10:6379> set aa zx
OK
20.0.0.10:6379> get aa
"zx"
20.0.0.10:6379> move aa 10
(integer) 0
20.0.0.10:6379> select 10
OK
20.0.0.10:6379[10]> keys *
1) "aa"
20.0.0.10:6379[10]> get aa
"123456"
20.0.0.10:6379[10]>

(3)删除库

flushdb #清空当前库所有键(慎用)
flushall #清空所有库所有键(慎用)

7、List数据类型

概述:列表的元素类型为string,按照插入顺序排序,在列表的头部或尾部添加元素

(1)lpush、lrange

lpush mykey a b c d #mykey键并不存在,该命令会创建该键及与其关联的List,之后在将参数中的values从左到右依次插入。
lrange mykey 0 2 #取从位置0开始到位置2结束的3个元素。
lrange mykey 0 -1 #取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。

复制代码
20.0.0.10:6379> lrange mykey 0 2
(empty array)
20.0.0.10:6379> lpush mykey a b c d
(integer) 4
20.0.0.10:6379> lrange mykey 0 2
1) "d"
2) "c"
3) "b"
20.0.0.10:6379> lrange mykey 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
20.0.0.10:6379>

(2)lpushx

lpushx mykey2 zhangsan #mykey2键此时并不存在,因此lpushx命令将不会进行任何操作,其返回值为0。
lpushx mykey zhangsan lisi #mykey键此时已经存在,所以lpushx命令插入成功,并返回链表中当前元素的数量。

复制代码
20.0.0.10:6379> keys *
1) "mykey"
20.0.0.10:6379> lpushx mykey2 zhangsan
(integer) 0
20.0.0.10:6379> lpushx mykey zhangsan lisi
(integer) 6
20.0.0.10:6379> lrange mykey 0 2
1) "lisi"
2) "zhangsan"
3) "d"
20.0.0.10:6379> lrange mykey 0 -1
1) "lisi"
2) "zhangsan"
3) "d"
4) "c"
5) "b"
6) "a"
20.0.0.10:6379>

(3)lpop、llen删除、统计元素

lpop mykey #移除并返回mykey键的第一个元素,从左取'lisi'
llen mykey #统计元素的数量

复制代码
20.0.0.10:6379> lrange mykey 0 -1
1) "lisi"
2) "zhangsan"
3) "d"
4) "c"
5) "b"
6) "a"
20.0.0.10:6379> lpop mykey
"lisi"
20.0.0.10:6379> llen mykey
(integer) 5
20.0.0.10:6379>

(4)lrem

lrem mykey 1 a #从头部(left)向尾部(right)变量链表,删除1个值等于a的元素,返回值为实际删除的数量

复制代码
20.0.0.10:6379> lrange mykey 0 -1
1) "zhangsan"
2) "d"
3) "c"
4) "b"
5) "a"
20.0.0.10:6379> lrem mykey 1 a
(integer) 1
20.0.0.10:6379> lrange mykey 0 -1
1) "zhangsan"
2) "d"
3) "c"
4) "b"
20.0.0.10:6379> lpushx mykey a e a
(integer) 7
20.0.0.10:6379> lrange mykey 0 -1
1) "a"
2) "e"
3) "a"
4) "zhangsan"
5) "d"
6) "c"
7) "b"
20.0.0.10:6379> lrem mykey 1 a
(integer) 1
20.0.0.10:6379> lrange mykey 0 -1
1) "e"
2) "a"
3) "zhangsan"
4) "d"
5) "c"
6) "b"
20.0.0.10:6379> lpushx mykey a
(integer) 7
20.0.0.10:6379> lrem mykey 2 a
(integer) 2
20.0.0.10:6379> lrange mykey 0 -1
1) "e"
2) "zhangsan"
3) "d"
4) "c"
5) "b"
20.0.0.10:6379>

(5)lindex、lset、ltrim

lindex mykey 1 #获取索引值为1(头部的第二个元素)的元素值。
lset mykey 1 e #将索引值为1(头部的第二个元素)的元素值设置为新值e。
ltrim mykey 0 2 #仅保留索引值0到2之间的3个元素,注意第0个和第2个元素均被保留。

复制代码
20.0.0.10:6379> lrange mykey 0 -1
1) "e"
2) "zhangsan"
3) "d"
4) "c"
5) "b"
20.0.0.10:6379> lindex mykey 0
"e"
20.0.0.10:6379> lindex mykey 1
"zhangsan"
20.0.0.10:6379> lindex mykey 4
"b"
20.0.0.10:6379> lset mykey 1 zx
OK
20.0.0.10:6379> lindex mykey 1
"zx"
20.0.0.10:6379> ltrim mykey 0 2
OK
20.0.0.10:6379> lrange mykey 0 -1
1) "e"
2) "zx"
3) "d"
20.0.0.10:6379>

(6)linsert

linsert mykey before a a1 #在a的前面插入新元素a1。
linsert mykey after e e2 #在e的后面插入新元素e2,从返回结果看已经插入成功。

复制代码
20.0.0.10:6379> lrange mykey 0 -1
1) "e"
2) "zx"
3) "d"
20.0.0.10:6379> linsert mykey before e a
(integer) 4
20.0.0.10:6379> lrange mykey 0 -1
1) "a"
2) "e"
3) "zx"
4) "d"
20.0.0.10:6379> linsert mykey after e 11
(integer) 5
20.0.0.10:6379> lrange mykey 0 -1
1) "a"
2) "e"
3) "11"
4) "zx"
5) "d"
20.0.0.10:6379>

(7)rpush、rpop

rpush mykey a b c d #从链表的尾部插入参数中给出的values,插入顺序是从右到左依次插入。
RPOP mykey #移除并返回mykey键的第一个元素。
rpoplpush mykey mykey2 #将mykey的尾部元素c弹出,同时再插入到mykey2的头部(原子性的完成这两步操作)。

复制代码
20.0.0.10:6379> rpush mykey a b c d
(integer) 9
20.0.0.10:6379> lrange mykey 0 -1
1) "a"
2) "e"
3) "11"
4) "zx"
5) "d"
6) "a"
7) "b"
8) "c"
9) "d"
20.0.0.10:6379> rpop mykey
"d"
20.0.0.10:6379> lrange mykey 0 -1
1) "a"
2) "e"
3) "11"
4) "zx"
5) "d"
6) "a"
7) "b"
8) "c"
20.0.0.10:6379> rpush mykey2 zhang san li si
(integer) 4
20.0.0.10:6379> lrange mykey2 0 -1
1) "zhang"
2) "san"
3) "li"
4) "si"
20.0.0.10:6379> rpoplpush mykey mykey2
"c"
20.0.0.10:6379> lrange mykey2 0 -1
1) "c"
2) "zhang"
3) "san"
4) "li"
5) "si"
20.0.0.10:6379>

8、Hash数据类型(散列类型)

概述:

hash用于存储对象。可以采用这样的命名方式:对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。 如:存储 ID 为 2 的汽车对象。
如果Hash中包含很少的字段,那么该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储4294967295个键值对。

(1)hset、hget、hdel

hset myhash field1 "zhang" #给键值为myhash的键设置字段为field1,值为zhang。
hget myhash field1 #获取键值为myhash,字段为field1的值"zhang"
hdel myhash field2 #删除myhash键中字段名为field2的字段,删除成功返回1。
hmset 键 字段1 值1 字段2 值2 .... #插入多个字段、值
hkeys 键 #查看所有的字段
hvals 键 #查看所有字段的值

复制代码
20.0.0.10:6379> hget myhash field1
"zhang"
20.0.0.10:6379> hdel myhash filed2
(integer) 0
20.0.0.10:6379> hset myhash field2 "lisi"
(integer) 1
20.0.0.10:6379> hget myhash field2
"lisi"
20.0.0.10:6379> hdel myhash field2
(integer) 1
20.0.0.10:6379> hmset myhash field3 san field4 wangwu
OK
20.0.0.10:6379> hkeys myhash
1) "field1"
2) "field3"
3) "field4"
20.0.0.10:6379> hvals myhash
1) "zhang"
2) "san"
3) "wangwu"
20.0.0.10:6379>

9、Set数据类型(无序集合)

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

(1)sadd、smembers、scard

sadd 键 值1 值2 .... #元素不能重复
smembers 键 #查看元素,无序的
scard 键 #统计元素的数量

复制代码
20.0.0.10:6379> sadd myset zhangsan lisi wangwu
(integer) 3
20.0.0.10:6379> smembers myset
1) "wangwu"
2) "lisi"
3) "zhangsan"
20.0.0.10:6379> scard myset
(integer) 3
20.0.0.10:6379>

(2)srandmember、spop、srem、semove

srandmember 键 n #随便显示n个元素
spop 键 #随机显示并删除一个元素
srem 键 值1 值2 ... #删除指定的元素
smove 键1 键2 值 #将键1的元素移动到键2中

复制代码
20.0.0.10:6379> srandmember myset
"wangwu"
20.0.0.10:6379> srandmember myset
"zhangsan"
20.0.0.10:6379> srandmember myset
"wangwu"
20.0.0.10:6379> srandmember myset 2
1) "wangwu"
2) "zhangsan"
20.0.0.10:6379>
20.0.0.10:6379> spop myset
"wangwu"
20.0.0.10:6379> smembers myset
1) "lisi"
2) "zhangsan"
20.0.0.10:6379> srem myset lisi
(integer) 1
20.0.0.10:6379> smembers myset
1) "zhangsan"
20.0.0.10:6379> sadd myset2 zx
(integer) 1
20.0.0.10:6379> smembers myset2
1) "zx"
20.0.0.10:6379> smove myset2 myset zx
(integer) 1
20.0.0.10:6379> smembers myset
1) "zx"
2) "zhangsan"
20.0.0.10:6379>

10、zset(有序集合)

概述:

a、有序集合,元素类型为String,元素具有唯一性,不能重复。
b、每个元素都会关联一个double类型的分数score(表示权重),可以通过权重的大小排序,元素的score可以相同。

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

(1)zadd、zrange、zcard、zcount、zrem、zincrby、zscore、zrevrangebyscore

zadd 键 权重1 值1 权重2 值2 .... #score权重是可以重复的,元素值是不可以重复的
zrange 键 起始位置 终止位置 [withscores] #起始位置 0表示左边开始的第一个元素,终止位置 -1表示到最后一个元素;[withscores]添加会显示权重
zcard 键 #统计元素的数量
zcount 键 起始权重 终止权重 #统计指定权重范围的元素数量
zrem 键 值1 值2 ... #删除指定的元素
zincrby 键 权重 值 #添加新的元素或增加指定元素的权重
zscore 键 值 #查看指定键的值的权重
zrevrangebyscore 键 起始权重 终止权重 [limit N M] #按score从大到小查看
zrangebyscore myzset 5 10 #获取权重在5-10之间内容
zrangebyscore myzset (5 10 #获取权重在5-10之间内容,不包含5
zrangebyscore myzset -inf +inf limit 2 3 #-inf表示第一个成员(位置索引值最低的,即0),+inf表示最后一个成员(位置索引值最高的),limit后面的参数用于限制返回成员的值,2表示从位置索引等于2的成员开始,取后面3个成员。

复制代码
20.0.0.10:6379> zadd myzset 1 zhangsan
(integer) 1
20.0.0.10:6379> zadd myzset 2 lisi
(integer) 1
20.0.0.10:6379> zadd myzset 3 wangwu 4 liuqi
(integer) 2
20.0.0.10:6379> zrange myzset 0 -1
1) "zhangsan"
2) "lisi"
3) "wangwu"
4) "liuqi"
20.0.0.10:6379> zrange myzset 0 -1 withscores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
5) "wangwu"
6) "3"
7) "liuqi"
8) "4"
20.0.0.10:6379> zcount myzset 1 3
(integer) 3
20.0.0.10:6379> zrange myzset 0 -1
1) "zhangsan"
2) "lisi"
3) "wangwu"
4) "liuqi"
20.0.0.10:6379> zrem myzset wangwu
(integer) 1
20.0.0.10:6379> zrange myzset 0 -1
1) "zhangsan"
2) "lisi"
3) "liuqi"
20.0.0.10:6379>
20.0.0.10:6379> zincrby myzset 10 tanchen
"10"
20.0.0.10:6379> zrange myzset 0 -1
1) "zhangsan"
2) "lisi"
3) "liuqi"
4) "tanchen"
20.0.0.10:6379> zcount myzset 5 10
(integer) 1
20.0.0.10:6379> zrangebyscore myzset 5 10
1) "tanchen"
20.0.0.10:6379> zadd myzset 5 zx
(integer) 1
20.0.0.10:6379> zrangebyscore myzset (5 10
1) "tanchen"
20.0.0.10:6379> zrangebyscore myzset 5 10
1) "zx"
2) "tanchen"
20.0.0.10:6379> zadd myzset2 1 a 2 b 3 c 4 d 5 e
(integer) 5
0.0.0.10:6379> zrange myzset2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
20.0.0.10:6379> zrangebyscore myzset2 -inf +inf limit 2 2
1) "c"
2) "d"
20.0.0.10:6379>

(2)zrevrange

zrevrange 键 起始位置 终止位置 #降序查看
zrevrangebyscore 键 起始权重 终止权重 [limit N M] #按权重进行查看

复制代码
20.0.0.10:6379> zrange myzset2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
20.0.0.10:6379> zrevrange myzset2 0 -1
1) "e"
2) "d"
3) "c"
4) "b"
5) "a"
20.0.0.10:6379> zrevrangebyscore myzset2 4 3
1) "d"
2) "c"
20.0.0.10:6379>

11、常用命令总结

(1)string

set 键 值
get 键

(2)list

lpush 键 值1 值2 .... #从左边开始插入元素
rpush 键 值1 值2 .... #从右边开始插入元素
lrange 键 起始位置 终止位置 #起始位置 0表示左边开始的第一个元素,终止位置 -1表示到最后一个元素

(3)hash

hset 键 字段 值
hget 键 字段

(4)set

sadd 键 值1 值2 .... #元素不能重复
smembers 键 #查看元素,无序的

(5)zset

zadd 键 权重1 值1 权重2 值2 .... #score权重是可以重复的,元素值是不可以重复的
zrange 键 起始位置 终止位置 [withscores] #起始位置 0表示左边开始的第一个元素,终止位置 -1表示到最后一个元素

zrangebyscore 键 起始权重 终止权重 [limit N M] #查看指定权重范围的元素,按score从小到大,limit N M 表示只显示第N个之后的M个元素(不包括第N个元素)

相关推荐
白云偷星子7 小时前
MySQL笔记13
数据库·笔记·mysql
施嘉伟7 小时前
静默安装金仓数据库,到底有多简单?
数据库
Tapdata7 小时前
实时物化视图的新路径:从传统 Join 到跨源实时查询
数据库
optimistic_chen7 小时前
【Java EE进阶 --- SpringBoot】Mybatis - plus 操作数据库
数据库·spring boot·笔记·java-ee·mybatis·mybatis-plus
FJW0208148 小时前
关系型数据库大王Mysql——DDL语句操作示例
数据库·mysql
言之。8 小时前
Chroma 开源的 AI 应用搜索与检索数据库(即向量数据库)
数据库·人工智能·开源
来旺8 小时前
互联网大厂Java面试全解析及三轮问答专项
java·数据库·spring boot·安全·缓存·微服务·面试
摇滚侠8 小时前
Spring Boot 3零基础教程,yml文件中配置和类的属性绑定,笔记15
spring boot·redis·笔记
cr7xin9 小时前
基于Session和Redis实现短信验证码登录
数据库·redis·缓存
乌暮9 小时前
数据库--视图、索引
数据库