Redis数据库

本文介绍了Redis数据库的安装步骤,包括Linux系统下的安装及Windows平台的安装方法。详细讲解了Redis的配置,如端口、密码、内存管理和持久化方案。此外,文章探讨了Redis的特性和使用场景,如缓存、排行榜系统和计数器应用,并概述了Redis的五种主要数据类型:字符串、哈希、列表、集合和有序集合,以及它们的操作命令和应用场景。最后,文章提及了Redis的事务特性,指出其不具备传统数据库的ACID属性,但提供了一定的批处理能力。

Redis数据库的介绍与安装

主要内容:(1)了解NoSQL数据库:为什么要抛弃关系型数据库?为什么NoSQL数据库的读写速度远超MySQL?
(2)安装Redis数据库;
(3)Redis相关配置:端口号;密码;占用内存大小;持久化方案

一、Redis的安装:
1、Redis官网只提供了Linux系统对应的Redis程序,在window平台上使用Redis需要从其他网站下载:链接: link.
2、编写启动脚本:
在Redis目录下创建一个批处理文件start.bat,用来启动Redis的时候加载配置文件,文件内容:redis-server redis.windows.conf
3、Redis命令行客户端:redis-cli.exe在这里插入图片描述
4、安装图像客户端:
RedisDesktopManager是目前最优秀的Redis图形客户端工具
5、使用Redis数据库时需要代开Redis数据库,点击start.bat文件

二、redis介绍:
Redis是一种基于键值对(key-value)的NoSQL数据库,Redis中的值可以是由string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理位置信息)等多种数据结构和算法组成。Redis可以将内存的数据利用快照和日志的形式保存到硬盘上,数据不会“丢失”。Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能

2.1 Redis的特性
(1)速度快:Redis的所有数据都放在内存中;Redis是用C语言实现的;Redis使用了单线程架构
(2)基于键值对的数据结构服务器
(3)丰富的功能
(4)简单稳定
(5)客户端语言多
(6)持久化
在这里插入图片描述
(7)主从复制
(8)高可用和分布式

2.2 Redis使用场景
2.2.1 Redis可以做什么:
(1)缓存
(2)排行榜系统
(3)计数器应用
(4)社交网络
(5)消息队列系统

2.2.2 Redis不可以做什么:大规模数据和冷数据

三、Redis配置参数:
redis配置文件:redis.windows.conf
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Redis常用数据结构

主要内容:(1)Redis的五种数据类型:无条件查询记录;字段的计算和字段的别名;
(2)Redis的Key命令:数据排序、分页、去除重复记录

一、预备
1.1 全局命令
(1)查看所有键:keys *
(2)键总数:dbsize
dbsize命令在计算键总数时不会遍历所有键,而是直接获取Redis内置的键总数变量,所以dbsize的时间复杂度是O(1)。而keys命令会遍历所有键,时间复杂度为O(n)
(3)检查键是否存在:exists key如果键存在返回1,不存在返回0
(4)删除键:del key [key ... ]返回结果为成功删除键的个数。假设删除一个不存在的键,返回0
(5)键过期:expire key secondsRedis支持对键添加过期时间,当超过过期时间后,会自动删除键
ttl命令会返回键的剩余过期时间,有3种返回值:
a、大于等于0的整数:键剩余过期时间
b、-1:键没设置过期时间
c、-2:键不存在
(6)键的数据结构类型:type key

1.2 单线程架构
Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务

1.2.1 为什么单线程还能那么快:
第一,纯内存访问,Redis将所有数据放在内存中,这是Redis达到每秒万级别访问的重要基础;
第二,非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转化为事件,不在网络I/O上浪费过多的时间
第三,单线程避免了线程切换和竞态产生的消耗,Redis是面向快速执行场景的数据库

二、Redis的五种数据类型:
在这里插入图片描述
2.1、字符串类型:
String类型可以保存普通文字,也可以保存序列化的二进制数据;
String类型最大可以存储512M数据

(1)常用命令

redis > SET email scott@163.com
redis > GET email
redis > DEL email

【注】set命令的几个选项:
ex seconds:为键设置秒级过期时间
px millisenconds:为键设置毫秒级过期时间
nx :键必须存在,才可以设置成功,用于添加
xx:与nx相反,键必须存在,才可以设置成功,用于更新
setex和setxx的作用和ex和nx选项是一样的

在这里插入图片描述
在这里插入图片描述
【注】学会使用批量操作,有助于提高业务处理效率,但每次批量操作所发送的命令数不是无节制的,如果数量过多可能造成Redis阻塞或者网络拥塞

计数:incr keyincr命令用于对值做自增操作,返回结果分为三种情况:
a、值不是整数,返回错误
b、值是整数,返回自增后的结果
c、键不存在,按照值为0自增,返回结果为1

【注】除了incr命令,Redis提供了decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数)在这里插入图片描述在这里插入图片描述

(2)不常用命令
在这里插入图片描述
字符串长度:strlen key,每个中文占3个字符;
设置并返回原值:getset key valuegetset 和set一样会设置值,但不同的是,它同时会返回键原来的值;
设置指定位置的字符:setrange key offeset value
获取部分字符串:getrange key start endstart 和end分别是开始和结束的偏移量,偏移量从0开始计算

2.1.2 典型使用场景
(1)缓存功能
(2)计数
(3)共享session
(4)限速

2.2 、哈希类型:
当我们觉得VALUES需要保存更复杂的结构化数据,这时候可以使用哈希类型:在这里插入图片描述
【注】哈希类型中的映射关系叫作field-value,注意这里的value是指field对应的值,不是键对应的值

2.2.1 哈希指令:
(1)设置值:hset key field value
在这里插入图片描述
(2)获取值:hget key field
在这里插入图片描述
【注】当使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能。如果只需要获取部分field,可以使用hmget,如果一定要获取全部的field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型。
(3) 其他:
在这里插入图片描述
(4)获取所有value:hvals key
删除field:hdel key field [field ...]
hdel会删除一个或多个field,返回结果为成功删除field的个数
在这里插入图片描述在这里插入图片描述
2.2.2 内部编码

哈希类型的内部编码有两种:
ziplist(压缩列表)——当field个数比较少且没有大的value时:ziplist使用更加紧凑的结构实现多个元素的连续存储,所以再节省内存方面比hashtable更加优秀;
hashtable(哈希表)—— 当有value大于64字节或者field个数超过512:当哈希类型无法满足ziplist的条件时,Redis使用hashtable作为内部实现,读写时间复杂度为O(1)

2.2.3 使用场景

将关系型数据表记录的数据用哈希类型存储,可以更加直观、并且在更新操作上会更加便捷
【注】哈希表是稀疏的,而关系型数据库是完全结构化的,例如哈希表的每个键可以有不同的field,而关系型数据库一旦添加新的列,所有行都要为其设置值(即使为NULL);
关系型数据库可以做复杂的关系查询,而Redis去模拟关系型复杂查询开发困难,维护成本高

2.3、列表类型
当我们需要向VALUE保存序列化的数据,可以使用列表类型,用来存储多个有序的字符串。列表中的每个字符串称为元素,一个列表最多可以存储2^31 - 1个元素

2.3.1 列表指令:

(1)添加操作:

redis > RPUSH  dname 技术部 后勤部 售后部  # 在最右侧添加元素
redis > LPUSH dname 秘书处 # 在最左侧(开头)添加元素
redis > LSET dname 2 # 修改第几个元素值
redis > LRANGE dname 0 -1  #显示列表数据 开始索引——结束索引,从左到右获取列表的所有元素(-1代表全部查找出来)

补:向某个元素前或后插入元素:linsert key before|after pivot valuelinsert命令会从列表中找到等于pivot的元素,在其前(before)或者后(after)插入一个新的元素value

(2)查找
a、获取指定范围内的元素列表:lrange key stert endlrange操作会获取列表指定范围所有的元素。索引下标有两个特点:第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到N。第二,lrange中的end包含了自身,这个和很多编程语言不包含end不太相同
b、获取列表指定索引下标的元素:lindex key index
c、获取列表长度:llen key
在这里插入图片描述

(3)删除
在这里插入图片描述
a、删除指定元素:lrem key count value
lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:
count > 0 ,从左到右,删除最多count个元素;
count < 0 ,从右到左,删除最多count绝对值个元素;
count = 0 ,删除所有

b、按照索引范围修剪列表:ltrim key start end

在这里插入图片描述

(4)修改
修改指定索引下标的元素:lset key index newValue

(5)阻塞操作
阻塞式弹出如下:blpop key [key ...] timeout;brpop key [key ...] timeout
blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同

2.3.2 内部编码

ziplist(压缩列表)——当元素个数比较少且没有大元素时:Redis会选用ziplist来作为列表的内部实现来减少内存的使用;
linkedlist(链表)—— 当某个元素超过64字节或者元素个数超过512个:当列表无法满足ziplist的条件时,Redis使用linkedlist作为内部实现

2.3.3 使用场景

消息队列;
文章列表;
【注】实际上列表的使场景很多,在选择时可以参考:
a、lpush + lpop = Stack(栈)
b、lpush + rpop = Queue(队列)
c、lpsh + ltrim = Capped Collection(有限集合)
d、lpush + brpop = Message Queue(消息队列)

2.4 、集合类型:
如果我们需要列表中的元素不可以重复,可以使用集合类型:

redis > SADD empno 8000
redis > SADD empno 8001
redis > SADD empno 8002
redis > SMEMBERS empno

Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集

2.4.1 集合指令:

(1)集合内操作

a、添加元素sadd key element [element ...]返回结果为成功添加元素的个数
b、删除元素:srem key element [element ...]返回结果为成功删除元素的个数
c、计算元素个数:scard keyscard的时间复杂度为O(1),它不会遍历集合所有元素,而是直接用Redis内部的变量
d、判断元素是否在集合中:sismember key element在集合内返回1,否则返回0
e、随机从集合返回指定个数元素:srandmember key [count]count是可选参数,不写默认1
f、从集合随机弹出元素:spop keysrandmember和spop都是随机从集合选出元素,不同的是spop命令执行后,元素会从集合中删除,而srandmember不会
g、获取所有元素:smembers key
【注】smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻塞Redis的可能性,这时候可以使用sscan来完成

在这里插入图片描述在这里插入图片描述

(2)集合间操作
a、求多个集合的交集:sinter key [key ...]
b、求多个集合的并集:suinon key [key ...]
c、求多个集合的差集:sdiff key [key ...]
d、将交集、并集、差集的结果保存:sinterstore destination key [key ...] suionstore destination key [key ...] sdiffstore destination key [key ...]

2.4.2 内部编码

集合类型的内部编码有两种:
intset(整数集合)——当元素个数较少且都为整数时,内部编码为intset
hashtable(哈希表)—— 当元素超过512个或者当某个元素不为整数时,内部编码变为hashtable

2.4.3 使用场景

标签
sadd = Tagging(标签)
spop/srandmember = Random item(生成随机数,比如抽奖)
sadd + sinter = Social Graph(社交需求)

2.5 、有序集合类型:

有序集合是带有排序功能的集合,Redis会按照元素分数值(score)排序(与列表使用索引下标作为排序依据不同)。有序集合中的元素不能重复,但是score可以重复

数据结构是否允许重复元素是否有序有序实现方式应用场景
列表索引下标时间轴、消息队列
集合标签、社交等
有序集合分值排行榜系统、社交等
redis > ZADD keyword 0 "鹿晗" 0 "张朝阳" 0 "马云"
redis > ZINCRBY keyword 1 "鹿晗"
redis > ZINCRBY keyword 5 "马云"
redis > ZINCRBY keyword 2 "张朝阳"
redis > ZREVRANGE keyword 0 -1

2.5.1 有序集合指令:

(1)集合内
a、添加成员:zadd key score member
【注】:Redis 3.2 为zadd命令添加了nx、xx、ch、incr四个选项:
nx:member必须不存在,才可以设置成功,用于添加;
xx:member必须存在,才可以设置成功,用于更新;
ch:返回此次操作后,有序集合元素和分数发生变化的个数;
incr:对score做增加,相当于zincrby

b、计算成员个数:zcard key
c、计算某个成员的分数:zscore key member
d、计算成员的排名:zrank key member zrevrank key member
【注】:
在这里插入图片描述
e、删除成员:zrem key member [member ...]返回结果为成功删除的个数;
在这里插入图片描述
f、增加成员的分数:zincrby key increment member
g、返回指定排名范围的成员:zrank key start end [withscores] zrevrank key start end [withscores]有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。若加上withscores选项,同时会返回成员的分数;
在这里插入图片描述
h、返回指点分数范围的成员:
在这里插入图片描述
i、返回指定分数范围成员个数:zcount key min max

(2)集合间的操作
a、交集:zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum | min |max]
说明:destination:交集计算结果保存到这个键;
numkeys:需要做交集计算键的个数;
key [key …]:需要做交集计算的键;
weights weight [weight …]:每个键的权重,在做交集计算中,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1;
aggregate sum | min |max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum

b、并集:zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum | min |max]

2.5.2:内部编码:

skiplist(跳跃表)——当元素个数较少且每个元素较小时:当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因此此时ziplist的读写效率会下降;
ziplist(压缩列表)——当元素个数超过128个:Redis会选用ziplist来作为列表的内部实现来减少内存的使用;
当某个元素大于64字节时,内部编码也会变成hashtable;

2.5.3:使用场景:

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面:按照时间、按照播放量、按照获得的赞数
(1)添加用户赞数
(2)取消用户赞数
(3)展示获得赞数最多的用户
(4)展示用户信息以及用户分数

三、Redis的Key命令(键管理)

3.1 单个键管理:

(1)键重命名:rename key newkey
a、如果在rename之前,键已经存在,那么它的值也将被覆盖;
b、为了防止被强行rename,Redis提供了renamenx命令,确保只有newkey不存在时候才被覆盖;
【注】由于重命名期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞Redis的可能性;

(2)随机返回一个键:randomkey

(3)键过期:expire key seconds键在seconds秒后过期expireat key timestamp键在秒级时间戳timestamp后过期

ttl命令和pttl都可以查询键的剩余过期时间,但是pttl精度更高可以达到毫秒级别,有3种返回值:大于等于0的整数:键剩余的过期时间(ttl是秒,pttl是毫秒);-1:键没有设置过期时间;-2:键不存在

【注】a、如果expire key不存在,返回结果为0;
b、如果过期时间为负值,键会立即被删除,犹如使用del命令一样;
c、persist命令可以将键的过期时间清楚;
d、对于字符串类型键,执行set命令会去掉过期时间,这个问题很容易在开发中被忽视;
e、Redis不支持二级数据结构(例如哈希表、列表)内部元素的过期功能,例如不能对列表类型的一个元素做过期时间设置;
f、setex命令作为set + expire的组合,不但是原子执行,同时减少了一次网络通讯时间

(4)迁移键:
迁移键的功能非常重要,因为有时我们只想把部分数据由一个Redis迁移到另一个Redis

a、move : move key dbmove命令用于在Redis内部进行迁移数据
b、dump + restore :dump key restore key ttl valuedump + restore可以实现在不同的Redis实例之间进行数据迁移的功能,整个迁移过程分为两步:
1)在原Redis上,dump命令会将键值序列化,格式采用的是RDB格式;
2)在目标Redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间
【注】第一:整个迁移过程并非原子性的,而是通过客户端分步完成的;
第二:迁移过程是开启了两个客户端连接,所以dump的结果不是在源Redis和目标Redis之间进行传输

c、migrate :migrate host port key |"" destination-db timeout [copy] [replace] [keys key [key ...]]
第一,整个过程是原子执行的,不需要在多个Redis实例上开启客户端的,只需要在源Redis上执行migrate命令即可;
第二,migrate命令的数据传输直接在源Redis和目标Redis上完成的;
第三,目标Redis完成restore后会发送OK给源Redis,源Redis接收后会根据migrate对应的选项来决定是否在源Redis上删除对应的键
【参数说明】:
host :目标Redis的IP地址;
port :目标Redis的端口;
key |"" :要迁移的键,如果当前需要迁移多个键,此处为空字符串 “ ”;
destination-db :目标Redis的数据索引,例如要迁移0号数据库,就是0;
timeout :迁移的超时时间;
[copy] :添加此项,迁移后不删除源键;
[replace] :添加此项,不管Redis是否存在该键都会正常迁移进行数据覆盖;
[keys key [key …]] :迁移多个键

命令作用域原子性支持多个键
moveRedis实例内部
dump + restoreRedis实例之间
migrateRedis实例之间

3.2 遍历键:
Redis提供了两个命令遍历所有的键,分别是keys和scan

1、全量遍历键:keys pattern
【注】为了遍历所有的键,pattern直接使用星号,这是因为pattern使用的是glob风格的通配符:
a、 * 代表匹配任意字符
b、? 代表匹配一个字符
c、[ ] 代表匹配部分字符,例如[1,10]代表匹配1到10的任意数字
d、 \x 用来做转义,例如要匹配星号、问号需要进行转义

【注2】:如果Redis包含了大量的键,执行keys命令很可能或造成Redis阻塞,所以一般建议不要在生产环境下使用keys命令,但有时确实有遍历所有键的需求,可以在以下情况下使用:在一个不对外提供服务的Redis从节点上执行,这样不会阻塞到客户端的请求,但是会影响主从复制;如果确认键值总数确实比较少,可以执行该命令;使用scan命令渐进式的遍历所有键,可以有效防止阻塞;

2、渐进式遍历:
scan:scan cursor [match pattern] [count number]
a、:cursor是必须参数,实际上cursor是一个游标,第一次遍历从0开始,每次scan遍历完都会返回当前游标的值,知道游标为0,表示遍历结束;
b、:match pattern 是可选参数,它的作用是做模式的匹配,这点和keys的模式匹配很像;
c、:count number 是可选参数,它的作用是表明每次要遍历的键的个数,默认值是10,此参数可以适当增大;

【注】:渐进式遍历可以有效的解决keys命令可能产生的阻塞问题,但是scan并非完美无瑕,如果在scan的过程中如果有键的变化(增加、删除、修改),那么遍历效果可能会出现如下问题:新增的键可能没有遍历到,遍历出了重复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键,这些是我们需要注意的

3.3 数据库管理:
1、切换数据库:select dbindex
2、flushdb/flushall:flushdb/flushall命令用于清除数据库,两者的区别是flushdb只清除当前数据库,flushall清除所有数据库
【注】:flushdb/flushall命令可以非常方便的清理数据,但也带来两个问题:
a、flushdb/flushall会将所有数据清除,一旦误操作后果不堪设想;
b、如果当前数据库键值比较多,flushdb/flushall存在阻塞Redis的可能性

在这里插入图片描述在这里插入图片描述在这里插入图片描述

Redis事务特性

主要内容:(1)Redis事务机制:Redis的事务机制是什么原理?Redis的事务具备ACID属性吗?Redis的事务能用来做什么?
(2)管理事务的命令:WATCH、UNWATCH、MULTI、EXEC、DISCARD

1、数据库事务机制:
数据库引入事务机制是为了防止对数据文件直接操作的时候出现意外宕机,引发数据的错乱

undo和redo日志保证了业务操作的原子性

(1)Redis是异步单线程执行,也就是一个线程对应所有的客户端。哪个客户端上传了命令,线程就会执行,所以并不能保证一个客户端的多个命令,不会被其他客户端的命令插队

(2)Redis事务的特点:
Redis的事务跟数据库的事务是有着明显差异的,它并不满足数据库事务的ACID属性。Redis的事务更像是批处理执行在这里插入图片描述

2、事务管理:

(1)如何保证事务的一致性?——为了保证事务的一致性,在开启事务之前必须要用WATCH命令监视要操作的记录

redis > WATCH kill_num  kill_user

(2)如何开始事务?
1)利用MULTI命令可以开启一个事务:redis > MULTI
2)开启事务后的所有操作都不会立即执行,只有执行EXEC命令的时候才会批处理执行

redis > INCR kill_num
redis > RPUSH kill_user 9502
redis > EXEC

(3)如何取消事务?
Redis并没有事务的回滚机制,所以并不能保证原子性
事务在没有提交执行前,是可以取消事务的。如果事务已经提交执行,就无法取消了

redis > MULTI
redis > ......
redis > DISCARD

注:Redis命令文档链接:link

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值