【Redis 的相关知识补充】
默认端口是6379
默认有16个数据库,0~15,0是第一个数据库
使用select <dbid>来切换数据库,如 : select 1,切换到了第二个库
统一密码管理,所有库的密码相同
exists key:判断某个key是否存在
type key:查看你的key是什么类型
del key:删除指定的key数据
unlink key:根据value删除非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后续异步中操作
expire key 10 : 为指定的key设置有效期 10s
ttl key :查看指定的key还有多少秒过期,-1:永不过期 -2:表示已过期
dbsize:查看当前数据库的key数量
flushdb:清空当前库
flushall:清空所有库
Redis是单线程+多路IO复用技术
多路复用是指使用一个线程来检测多个文件描述符(socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则遇到阻塞超时,得到就绪状态进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)
串行VS多线程+锁(memcached)VS单线程+多路复用(redis)
(与memcache三不同:支持多数据类型,支持持久化,单线程+多路复用)
我肯定遥遥领先
【Redis的数据结构陈述】
首先,这个Redis有十大数据类型 >>>>>>>>是一个key-value类型数据库
这里的数据类型都是value类型,key类型的都是字符串,所以value的类型多种多样
*******好好好,我不废话了,我开始跟你讲讲这些**********
因为 我比较菜。所以就从最基础的五大数据类型开始讲解
分别是 String、List、hash、set、zset
1.String
就是个普通字符串,是Redis的最基本数据类型(),一个key对应一个value,String类型的二进制是最安全的,可以包含jpg图片已经序列化对象,一个Redis字符串但是value的最大长度不能不能超过512M
【几点说明】
Value类型的String分类
string:普通字符串
int:整数类型、可以做自增自减操作
float:浮点类型、也可以做自增自减操作
***********使用场景:缓存、计数、共享session、限速
String类型的常见命令:
Set :添加键值对
NX:当数据库中key不存在时,可以将key-value添加到数据库
XX:当数据库key存在时,可以将key-value添加到数据库,与NX参数互斥
EX:key的超时秒数
PX:key的超时毫秒数,与EX互斥
Value中包含空格、特殊字符,需要双引号包裹
常见命令概览 没有的,自己查去
get:获取值 get key
apend :追加值
将给定的key,追加到原值末尾,并显示添加后的长度
strlen :获取值长度
setnx:key不存在时,设置key的 值
清空db 方便测试 1,site不存在,返回1表示设置成功 再次通过setnx设置site,由于已经存在了,返回0
incr :原子递增1
将key中存储的值增1 ,只能对数字值进行操作,如果key不存在会新建一个,值为1.
decr:原子递减1
将key存储的值递减1.只能对数字值进行操作,如果为空,则值为-1
incrby/decrby:递增或者递减指定的数字
将key中存储的数字递增指定的步长,若key不存在,则相当于在原值为0的基础上递增指定的步长
mset:同时设置多个key-value
mget:获取多个key对应的值
msetnx:当多个key不存在时,则设置成功
原子性的,要么都成功,要么都失败
- 当k1,k2都不存在的时候,同时设置k1和k2,由于k1在上条命令操作已经存在,此操作失败
- 获取k1,k2,k2不存在
- 当k2、k3不存在的时候,同时设置k2和k3设置成功
- 最后获取k1,k2,k3的值
getrange: [start,end]
获取值的范围,类似Java中的subString >返回一段区间中的字符串.
setrange: setrange <key> <起始位置><value>
覆盖指定位置的值
setex:设置键值&过期时间(秒)
: setex <key> <过期时间(秒)> <value>
设置k1的值为V1,有效期100s
getset:以新换旧,设置新值同时返回旧值
: get <key> <value>
设置name 为ready ,然后将name设置为tom 返回name的旧值
设置age为30,若age未被设置过,返回旧值为null
GETRANGE key start end 截取指定长度字符串
key 是要截取的字符串所对应的键名。
start 是截取的起始位置,以 0 为基准,表示字符串中的第一个字符。
end 是截取的结束位置,同样以 0 为基准,表示截取到字符串中的最后一个字符。
2.LIst(集合)
可以说是简单的字符串列表,可以用来存储多个有序的,在Redis里面,我可以把它搞成,栈、队列、阻塞队列,所有list命令都用l开头,Redis不区分大小写。同时也可以理解为一个底层的双端链表,按照插入排序,对两端的操作性很高,通过下标索引操作中间节点性能较差,但可以很好的添加一个元素到头部(左边)或者尾部(右边),最多可以包含2^32 -1个元素
特征:有序、元素可以重复、插入和删除块、查询速度一般
***********使用场景:消息队列、文章列表、评论列表
**********List类型的常见命令
- lpush/rpush:从左边或者右边插入一个或多个值
【语法】
lpush/rpush <key1> <value1> <key2> <value> ...
lrange <key> <star> <stop>
返回指定区间内的元素(闭区间),也可以使用负数作为下标,-1表示列表的最后一个元素,-2表示列表的倒数第二个元素, 返回值:一个列表,包含指定区间元素
【例子】
- 列表的左边插入四个元素
- 从左边取出索引位于[1,2]范围内的元素
lpop/rpop:从左边或者右边弹出多个元素
Lpop/rpop <key> <count> 值在键在,值光键亡
Count :可以省略,默认值为1 lpop/rpop操作后,弹出来的值可以在列表中删除
集合course右边加入6个元素,左边弹出一个元素
右边弹出一个元素,弹出2个元素
rpoplpush:从一个列表弹出一个元素放到另外一个列表中
rpoplpush sourse destination
从source的右边弹出一个元素放到destination列表的左边
【示例】
列表k1的右边添加3个元素[1,2,3],从左到右输出k1列表中的元素
列表k2的右边添加3个元素[4,5,6]从左到右输出k2列表中的元素
从k1的右边弹出一个元素放到k2的左边
K1剩下2个元素了
K2中变成4个元素了
lindex:获取指定所有位置元素(从左到右)
lindex key index index 就是参数,写第几个 第几个就n-1
返回值:
列表中下标为index的元素,如果index参数的值不在列表的区间范围内(out of range)或者key不是列表类型的元素,返回一个错误,返回nil
列表放入四个元素,返回索引位置2 的元素,返回索引200的元素,没有
最后返回最后一个元素
llen:获取列表长度
llen key
返回列表key的长度、如果key不存在,则key被解释为一个空列表,返回0,如果key不是列表类型,返回一个错误
linsert:在某个值的前或者后面插入一个值
【语法】
linsert <key> before|after <value> <newvalue>
将newvalue插入到列表key中,位于值value之前/之后,当value不存在于列表key时,不执行任何操作,当key不存在时,key被视为空列表,不执行任何操作,如果key不是列表类型,返回一个错误
返回值:
如果命令执行成功,返回插入操作完成后列表的长度。如果没找到value 返回-1,当key不存在或者空列表,返回0
在xxx元素前面插入lucy,由于xxx元素不存在,插入失败返回-1 最后列出列表所有元素
lrem:删除指定数量的某个元素
【语法】:lrem key count value
根据参数count的值,移除列表中参数value相等的元素
count的值可以是以下几种:
- count>0:从表头开始向表尾搜索,移除value相等的元素,数量为count
- count<0:从表尾开始向表头搜索,移除与value相等的元素,数量为count的绝对值
- count=0:移除表中所有与value相等的值
返回值:被移除的元素数量
因为不存在key被视作空表(empty list),所以当key不存在时,总是返回0
从k1集合中从左边删除2个v2
lset:替换指定位置的值
lset:<key> <index> <value>
将列表key下标为index的元素的值设为value
当index参数超出范围,或对一个空列表(key 不存在)进行lset时,返回一个错误
返回值:操作成功返回ok,否则返回错误信息
在name集合中放入3个元素并全部输出
将集合中的第二个元素替换为liy 然后再次输出name集合
索引超出范围就报错,course集合不存在就报错
3. hash (哈希表)
一个key-value的结构(键值对集合),也叫散列,它对应的数据结构是:ziplist(压缩列表)、hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplst,否则使用hashtable。其value是一个无序字典,类似于Java中的hash的Map<string,Object>,每个hash可以存储2^32 -1个键值对
使用场景:
缓存用户信息、
缓存对象
******常用hash命令
hset:设置多个field的值 hset key field value [field value …]
将哈希表key中的域field的值设为value。如果key不存在,一个新的哈希表被创建并进行hset操作,如果field已经存在于哈希表中,旧值将被覆盖
返回值:
如果field是哈希表中的一个新建域,并且值设置成功,返回1。如果哈希表中域field已经存在旧值已被新值覆盖,返回0。
hget:获取指定field的值 hget key field
hgetall:返回hash表所有的域和值 hgetall key
hexists:判断给定的field是否存在 返回值1存在0不存在
【语法】:hexists key field
hkeys:列出所有的field hkeys key
hvals:列出所有的value hkeys key
hlen:返回field的数量
在哈希表user中设置2个域,name和age,name的值为ready,age的值为30
列出user的所有field 获取user中的所有field的值列表
返回user中的key 数量
hincrby:filed的值加上指定的增量 hincrby key field increment
为哈希表key中的域field的值加上增量increment,增量也可以为负数,相当于对给定域进行减法操作。如果key不存在,一个新的哈希表会被创建并执行hincrby命令,如果域field不存在,那么在执行命令前,域的值被初始化为0。对于一个储存字符串的域field执行hincrby命令将造成一个错误
返回值:执行命令后,哈希表key中域field的值
【几点说明:】
Hash表siteInfo 中有2个域{site:”itsoku.com”,pv:1000}
获取siteInfo中pv的值,并增加10,获取siteInfo
siteInfo中的Uv值增加500,uv这个域不存在则会先添加。然后再执行hincrby
hsetnx:当filed不存在的时候,设置filed的值
hsetnx key field value
将哈希表key中的域field的值设置为value,当且仅当域field不存在,若域field已经存在,该操作无效。如果key不存在,一个新的哈希表被创建并执行hsetnx命令。
返回值:设置成功,返回1
如果给定域已经存在且没有操作被执行,返回0
【示范】:
解释:
创建user 包含2个域 name age,name已经存在,设置失败,返回0
name依旧是ready,address不存在设置成功(1) 最后输出一下address的值
4. set(集合)
set的值是不能重读的(具有唯一性),用来保存多个字符串元素,集合中不允许有重复的元素,并且集合中的元素是无序的,集合对象的编码可以是 intset 或者 hashtable,底层是一个value为null的哈希表,所以添加,删除,查找的复杂度都是 O(1),随着数据的增加,查找数据的时间不变(也就是说不管查找多少数据,时间是一样的),集合中最大的成员数为 2^32 – 1
***********使用场景:标签(tag)、共同关注
*******set常用命令整理
sadd:添加一个或多个元素
sadd <key> <value1> <value2> …
集合中放入五个元素会自动去重,所以有效为3个
smembers:取出所有元素
【语法】:smembers <key>
sismember:判断集合中是否有某个值
sismember <key> <value> 1:有 0:没有
判断k1集合是否包含v1,1 是否包含v5
scard:返回集合中元素的个数
scard <key> 返回集合key的基数(集合中的元素)key不存在时返回0
srem:删除多个元素 srem key member [member…]
移除集合key中的一个或多个member元素,不存在的member元素会被忽略。
当key不是集合类型,返回一个错误。
返回值:被成功移除的元素的数量,不包括被忽略的元素
解释:
添加4个元素到course集合中并获取,删除course集合中的Java和C,再次获取
【例子】
spop:随机弹出多个值
spop <key> <count> 随机从key集合中弹出count个元素,count默认值为1
返回值:被移除的随机元素,当key不存在或key时空集时候,返回nil
解释:向course集合中添加4个元素,并获取输出
随机弹出一个元素,同时删除被弹出元素,然后随机弹出2个元素
最后弹出剩下元素
srandmember:随机获取多个元素,不会从集合中删除
srandmember <key> <count>
从key指定的集合中随机返回count个元素,count可以不指定,默认值是1
和sqop的区别:
都可以随机获取多个元素,srandmember不会删除元素,sqop会删除元素
返回值:只提供key参数时,返回一个元素;如果集合为空,返回nil
如果提供了count参数:那么返回一个数组,如果集合为空,返回空数组
【例子】
解释:
向集合course中添加四个元素,获取并输出,随机获取3个元素并输出,但原有元素不会被删除,最后输出course中所有的元素,元素个数没有变化
smove:将某个原创从一个集合移动到另一个集合
smove <source> <destination> member
将member元素从sourse集合移动到destination集合
Smove是原子性操作
如果source集合不存在或者不包含指定的member元素,则smove命令不执行任何操作,仅返回0.否则,member元素已经从source集合中被移除,并添加到destination集合中去。
当destination集合已经包含member元素,smove命令只是简单地将source集合中的member元素删除
当source或destination不是集合类型时,返回一个错误
【返回值】:如果member元素被成功移除,返回1.
如果member元素不是source集合的成员,并且没有任何操作对destination集合执行,那么返回0
解释:向2个集合中添加元素,然后将course 1 的JS移动到course2
然后输出2个集合,原有集合移动的元素就少了
sinter:取多个集合的交集
sinter key [key …]
解释:分别向3个集合添加元素,最后返回交集
sinterstore:将多个集合的交集放到一个新的集合中
sinterstore destination key [key…]
这个命令类似于sinter命令,但它将结果保存到destination集合,而不是简单地返回结果集
【返回值】;结果集中的成员数量
sunion:取出多个集合的并集,自动去重
sunion key [key…]
>>>>>>>>>返回3个集合的并集,会自动去重
sunionstore:将多个集合的并集放到一个新的集合中
sinterstore destination key [key…]
这个命令类似于sunion命令。但它将结果保存到destination集合,而不是简单的返回结果集。 【返回值】:结构集中的成员数量
sdiff:取多个集合的差集
sdiff key [key …]
返回一个集合的全部成员,该集合是所有集合之间的差集,不存在的key被视为空集
返回course1有的,但是course2和course3没有的元素
【例子】:
sdiffstore:将多个集合的差放到一个新的集合中
sdiffstore:
5.Zset(有序集合)
和普通集合set非常类似,是一个没有重复元素的字符串集合。不同的地方在于有序集合的某个成员都关联了一个double类型的评分(score),就是个排序的依据,redis正是通过score来为集合中的成员进行从小到大的排序(升序)。集合的成员是唯一的,但是评分是可以重复的,
******常用Zset命令介绍
zadd:添加元素
zadd <key> <score1> <member1> <score2> <member2>
将一个或者多个member元素及其score值加入到有序集 key 当中。如果某个member已经是有序集成员,那么更新这个member的score值,并通过重新插入这个member元素,保证该member在正确的位置上。
score值可以是整数值和双精度浮点数
如果key不存在,创建一个空的有序集并执行zadd操作,当key不存在则创建一个空的有序集并执行zadd操作。当key存在但不是有序集类型时,返回一个错误。
【返回值】:被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员
【解释】:创建名称为topn的zset 添加了五个元素
zrange :score 升序,获取指定索引范围的元素
【语法】:zrange key start top [withscores]
【相关参数说明】
返回存储在有序集合key中的指定范围的元素,返回的元素可以认为是按照score从最低到最高的排列,如果得分相同,如果得分相同,将按排序
下标参数start和stop都以0为底,0是第一个成员 -1是最后一个成员,规则自己推
zrange key 0 -1:可以获取所有元素
Withscores:让成员和它的socre值一并返回,返回列表value,score1,……value,scoreN的格式来表示
【返回值】:指定区间内,带有score值(可选)的有序集成员的列表
【示例】
解释:
- 创建名称topn的zset,添加了5个元素
- 按score升序,返回key中的所有元素值
- 按score升序,返回key中的所有元素值以及score
- 返回索引范围[2,4]内的3个元素
zrevrange :score 降序、、获取指定索引范围的元素
【语法】 zrevrange key start stop [withsocres]
【相关参数解释】
- 返回存储在有序集合key中指定范围的元素。返回的元素可以认为是anscore最高到最低排列,如果得分相同,就按字典顺序排序 、、、、、、下标参数start和stop都以0为底,规则略
- Withscores:让成员和它的socre值一并返回,返回列表value,score1,……value,scoreN的格式来表示
【解释】:
创建名称为zset的tpon,分别按照score降序获取所有元素、获取前三名
zrangebyscore:按照score升序,返回指定score范围内的数据
语法:zrangdebyscore key min max [withsocres][LIMIT offset count]
【相关解释】:
返回有序集key中,所有socre值介于min和max之间(包括等于min和max)的成员,有序集成员按照score值递增(升序)排列
具有相同的score值的成员按字典序来排列(该属性是有序集提供的,不需要额外的计算)。
可选的LIMIT参数指定返回结果的数量以及区间(就像SQL中的SELECT LIMIT OFFFSET,count),注意当offset很大时。定位offset的操作需要遍历整个有序集,最坏复杂度O(N)时间
可选的withscoresc参数决定结果集单单返回有序集的成员,还是将有序集成员以及score值一起返回。
【解释】;score升序,获取[70,90]区间中的元素的值
Score升序,获取socre位于[70,90]区间中的元素值及score
*最后一句:#相当于:
select value,score from topn集合 where score>=70 and score<=90 order by score asc limit 1 2
zrevrangebyscore:按照score降序,返回指定score范围内的数据
语法: zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
【相关命令解释】
返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。
具有相同 score 值的成员按字典序的逆序排列。
除了成员按 score 值递减的次序排列这一点外, zrevrangebyscore 命令的其他方面和zrangebyscore 命令一样。
【代码示例】
解释: 1)score降序,获取score位于[70,90]区间中的元素值
2)然后score降序,获取score位于[70,90]区间中的元素值以及score
zincrby:为指定元素的score加上指定的增量
【语法】:zincrby key increment member
【相关语法解释】
为有序集 key 的成员 member 的 score 值加上增量 increment 。可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于ZADD key increment member 。
当 key 不是有序集类型时,返回一个错误。
score 值可以是整数值或双精度浮点数。
【示例】
解释: 1)向集合topx中添加3个元素并输出
2)对集合中的元素java的值score加5,变95了然后输出验证
zrem:删除集合中的多个元素
【语法】: zrem key member [member…]
【参数解释】
- 移除有序集key中的一个或多个成员,不存在的成员将被忽略
- 当key存在但不是有序集类型时,返回一个错误
【示例】
解释:向集合topx添加3个元素并输出,之后删除集合中的2个元素 c、c++ 然后并输出结果
zremrangebyrank:根据索引范围删除元素
【语法】 zremrangebyrank key start stop
移除有序集key中,指定排名rank区间内的所有成员
区间分别以下标参数start和stop指出,包含start和stop在内。
下标参数start和stop都以0为底,略
【示例】
解释:
向集合中添加元素并输出,然后删除索引范围[0,1]的数据,然后输出topx中所有的元素
zremrangebyscore:根据score的范围删除元素
【语法】:
zremrangebyscore key min max
移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员
【示例】:
解释:
添加元素并输出,删除score位于[70,80]的元素,输出剩下元素
zcount:统计指定socre范围内元素的个数
【语法】:zcount key min max
返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的
成员的数量
【示例】
解释: 统计score位于[80,100]区间中的元素个数
zrank :按照socre升序,返回某个元素在集合中的排名
【语法】:zrank key member
返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
排名以 0 为底,也就是说, score 值最小的成员排名为 0 。
【示例】
解释:
获取元素c的排名,返回1表示排名2 ,输出集合,并查看排名
zrevrank :按照socre降序,返回某个元素在集合中的排名
【解释】:
返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。排名以0为底,最大的0号位。
【示例】:
解释:
score排序,java的排名 0---》1
zscore:返回集合中的指定元素的socre
【语法】:zscore key member
返回有序集key中,成员示member的socre值。如果member元素不是有序集key的成员,或key不存在,返回nil。
【示例】
解释:获取集合 topx中的java的socre
【zest总结】
SortedSet(zset)是redis提供的一个非常特别的数据结构,内部使用到了2种数据结构。
1、hash表
类似于java中的Map<String,score>,key为集合中的元素,value为元素对应的score,可以用来快速定位元素定义的score,时间复杂度为O(1)
2、跳表
跳表(skiplist)是一个非常优秀的数据结构,实现简单,插入、删除、查找的复杂度均为O(logN)。类似java中的ConcurrentSkipListSet,根据score的值排序后生成的一个跳表,可以快速按照位置的顺序或者score的顺序查询元素。
这里我们来看一下跳表的原理:首先从考虑一个有序表开始:
从该有序表中搜索元素 < 23, 43, 59 > ,需要比较的次数分别为 < 2, 4, 6 >,总共比较的次数为 2 + 4 + 6= 12 次。有没有优化的算法吗? 链表是有序的,但不能使用二分查找。类似二叉搜索树,我们把一些节点提取出来,作为索引。得到如下结构:
这里我们把 < 14, 34, 50, 72 > 提取出来作为一级索引,这样搜索的时候就可以减少比较次数了。我们还可以再从一级索引提取一些元素出来,作为二级索引,变成如下结构:
这里元素不多,体现不出优势,如果足够多,这种索引结构的优势就会体现的非常明显。
关于对Redis的五大数据类型总结