Redis学习笔记(二)

一、基础知识

在Redis中默认有16个数据库
使用vim xconfig/redis.conf 查看redis的配置文件,可以看到默认数据库数量,通过修改配置文件来修改默认数据库数量
在这里插入图片描述
默认使用的是第0个数据库
我们可以通过select命令切换数据库

127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> dbsize #查看数据库大小
(integer) 0
127.0.0.1:6379[3]> keys * # 查看当前数据库所有的key
1) "name"
2) "age"
127.0.0.1:6379[3]> 

清除当前数据库: flushdb

127.0.0.1:6379[3]> flushdb
OK
127.0.0.1:6379[3]> dbsize
(integer) 0

清除全部数据库内容:flushall

127.0.0.1:6379[3]> flushall
OK
127.0.0.1:6379[3]> dbsize
(integer) 0
127.0.0.1:6379[3]> select 2
OK
127.0.0.1:6379[2]> dbsize
(integer) 0
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> dbsize
(integer) 0

Redis是单线程的

官方表示,Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络宽带,既然可以使用单线程来实现,就使用单线程

Redis为什么那么快?

1.误区一:高性能的服务器一定是多线程的?
2.误区二:多线程(CPU上下文会切换)一定比单线程效率高!
核心:redis是将所有的数据全部放在内存中的,所有说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时操作),对于内存系统来说,如果没有上下文切换效率就是最高的。

二、五大数据类型

1.Redis-key的常用命令

命令描述
EXISTS key检查key是否存在
EXPIREkey seconds为指定key设置过期时间,单位(秒)
KEYS pattern按照指定格式查找key
MOVE key db将当前数据库的key的移动到指定数据库中
TTL key以秒为单位返回key的过期时间
TYPE key返回key的数据类型
RENAME key newkey修改key的名字
DEL key当key存在时,删除key

常用命令的测试
在这里插入图片描述

2.Strings(字符串)常用指令

命令描述
SET key value将key设定为指定字符串
GET key获取指定key的值
APPEND key value往key的末尾追加值,如果key不存在就先创建key
INCR key对key所存储的值进行原子加1操作,如果key不存在,就在操作之前创建key并设置为0(自增1)
DECR key对key对应的数字做减1操作。如果key不存在,那么在操作之前,这个key对应的值会被置为0(自减1)
INCRBY key number将key对应的数字加上number。如果key不存在,操作之前,key就会被置为0
DECRBY key number将key对应的数字减去number。如果key不存在,操作之前,key就会被置为0
STRLEN keykey对应的字符串value的长度,或者0(key不存在)

注意:incr、decr、incrby、decrby这些命令会将字符串值解析成整形,如果指定的key中存储的值不是字符串类型(fix:)或者存储的字符串类型不能表示为一个整数,
那么执行这个命令时服务器会返回一个错误(eq:(error) ERR value is not an integer or out of range)

测试常用命令

127.0.0.1:6379> set key1 10 # 设置key1的值为10
OK
127.0.0.1:6379> get key1 # 获取key1的值
"10"
127.0.0.1:6379> append key1 10 #在key1的末尾追加10这个字符串
(integer) 4
127.0.0.1:6379> get key1
"1010"
127.0.0.1:6379> append key2 zhangsan 
(integer) 8	# 当前没有key2,所以先创建之后再在key2的默认追加zhangsan
127.0.0.1:6379> get key2
"zhangsan"
127.0.0.1:6379> incr key1 # key1的值自增1
(integer) 1011
127.0.0.1:6379> decr key1 # key1的值自减1
(integer) 1010
127.0.0.1:6379> incrby key1 20 # key1的值加上20
(integer) 1030
127.0.0.1:6379> decrby key1 30 # key1的值减去20
(integer) 1000
127.0.0.1:6379> strlen key1 # key1的值的字符串长度为4
(integer) 4

字符串范围类型的命令(range)

命令描述
GETRANGE key start end根据指定的范围返回key对应的字符串值。可以用负数表示string尾巴下标,-1就是最后一个。(注意:当指定范围超出string长度,都把结果限制在string内。)
SETRANGE key offsett value覆盖key对应的string的一部分,从指定的offset处开始,覆盖value的长度。如果offset比当前key对应string还要长,那这个string后面就补0以达到offset。

测试命令

# 我们先设置key2的值为hello world 
127.0.0.1:6379> set key2 "hello world"
OK
127.0.0.1:6379> get key1
"1000"
# 打印出hello 注意:第一个是从0开始,最后一个是从-1开始
127.0.0.1:6379> GETRANGE key2 0 4
"hello"
# 打印出key2所对应的值
127.0.0.1:6379> GETRANGE key2 0 -1
"hello world"
# 将"hello world" 修改成"hello redis"
127.0.0.1:6379> SETRANGE key2 6 redis
(integer) 11
127.0.0.1:6379> get key2
"hello redis"

set的衍生命令

命令描述
SETEX key seconds value设置key对应字符串value,并且设置key在给定的seconds时间之后超时过期,单位为秒
SETNX key value将key设置值为value,如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做。SETNX是”SET if Not eXists”的简写。
# 设置key2的值为10,因为已经存在所以无法创建,返回0
# 此方法如果成功返回1,失败返回0
127.0.0.1:6379> setnx key2 10
(integer) 0
127.0.0.1:6379> setnx key3 "xiao"
(integer) 1
# 为key2设置一个过期时间
127.0.0.1:6379> setex key2 10 "li"
OK
# 显示过期时间
127.0.0.1:6379> ttl key2
(integer) 7

批量处理的命令

命令描述
MSET对应给定的keys到他们相应的values上。MSET是原子的,所以所有给定的keys是一次性set的。客户端不可能看到这种一部分keys被更新而另外的没有改变的情况。
MGET返回所有指定的key的value。对于每个不对应string或者不存在的key,都返回特殊值nil
MSETNX对应给定的keys到他们相应的values上。只要有一个key已经存在,MSETNX一个操作都不会执行
# 同时设置多个值
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
# 同时获取多个值
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
# msetnx是一个原子操作,要么都成功,要么都失败
127.0.0.1:6379> MSETNX k1 f k4 fsd
(integer) 0
# 因为k1已经存在值,所以执行失败
127.0.0.1:6379> get k1
"v1"

set的高阶用法

# 对象 
# 设置一个key为user:1 值为json字符来保存一个对象
127.0.0.1:6379> set user:1 {name:zhangsan,age:3}
OK
# 这里的key是一个巧妙的设计:user:{id}:{filed},如此设计再Redis是可以的
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"

Strings 的使用场景:value除了是字符串还可以是数字!

  • 计数器
  • 统计多单位的数量
  • 粉丝数
  • 对象缓存存储

3.Lists(列表)数据类型的常用命令

在Redis中,List可以通过指令实现栈、队列、阻塞队列。

Lists的大部分命令都是以L开头。

命令描述
LPUSH往列表的左边也就是头部插入一条元素(left push)
RPUSH往列表的右边也就是尾部插入一条元素(right push)
LRANGE返回存储在列表中指定范围的元素,从0开始计算,也可以是负数,-1代表最后一个,以此类推
LPOP移除并且返回列表的第一个元素。
RPOP移除并返回存于列表的最后一个元素。
LINDEX通过index索引去返回列表中的值
LLEN返回列表的长度
LREM从列表中移除出现了指定数量和指定value的元素
LTRIM通过下标截取指定长度的列表
RPOPLPUSH移除列表最后一个元素,并将它添加到一个新的列表中的第一个
LSET通过下标设置列表中的值,可以当作更新操作,当下标大于元素的数量将会报错
LINSERT将某个具体的value插入到列表中某个元素的前面或者后面
# 先清除以下之前测试留下的数据
127.0.0.1:6379> flushdb
OK
# 将多个数值插入到列表的头部
127.0.0.1:6379> LPUSH list one two three
(integer) 3
# 查看列表中所有的元素
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
# 查看指定范围的元素
127.0.0.1:6379> LRANGE list 0 1
1) "three"
2) "two"
# 向列表的尾部插入元素
127.0.0.1:6379> RPUSH list four
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
=====================================================
# 将列表中第一个元素移除
127.0.0.1:6379> LPOP list
"three"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
3) "four"
# 将列表中最后一个元素移除
127.0.0.1:6379> rpop list
"four"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
====================================================
# 返回第一个元素
127.0.0.1:6379> LINDEX list 0
"two"
# 没有第五个元素,返回nil
127.0.0.1:6379> LINDEX list 4
(nil)
====================================================
# list长度为2
127.0.0.1:6379> LLEN list
(integer) 2
=====================================================
# 我们先往列表里加一下数据用来测试
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "two"
5) "three"
6) "four"
7) "five"
8) "five"
# 从list的头部向尾部移除等于"two"的元素
# 当count>0时,从头往尾移除count个指定value的元素
# 当count<0时,从尾往头移除count个指定value的元素
# 当count=0时,移除所有指定value的元素
127.0.0.1:6379> lrem list 2 two
(integer) 2
# 移除后的列表
127.0.0.1:6379> lrange list 0 -1 
1) "three"
2) "one"
3) "three"
4) "four"
5) "five"
6) "five"
=====================================================
# 截取3~4之间的元素
127.0.0.1:6379> LTRIM list 2 3
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "four"
=====================================================
# 新建两个列表,source和destination,往列表右边插入一些元素
127.0.0.1:6379> RPUSH source a b c
(integer) 3
127.0.0.1:6379> RPUSH destination x y z
(integer) 3
# 使用RPOPLPUSH 将source列表最后一个元素转移到destination的第一个
127.0.0.1:6379> RPOPLPUSH source destination
"c"
127.0.0.1:6379> LRANGE source 0 -1
1) "a"
2) "b"
127.0.0.1:6379> LRANGE destination 0 -1
1) "c"
2) "x"
3) "y"
4) "z"
# 当源列表和目标列表是同一个时,会将此列表的最后一个转移到第一个
127.0.0.1:6379> RPOPLPUSH source source
"b"
127.0.0.1:6379> LRANGE source 0 -1
1) "b"
2) "a"
# 当源列表不存在,将返回nil值
127.0.0.1:6379> RPOPLPUSH yx source
(nil)
=====================================================
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "four"
# 修改list中的第二个元素
127.0.0.1:6379> LSET list 1 six
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "six"
# 索引大于列表范围,发生错误
127.0.0.1:6379> LSET list 3 abc
(error) ERR index out of range
======================================================
# 分别向元素"six"的前后插入一个元素
127.0.0.1:6379> LINSERT list before six five
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "five"
3) "six"
127.0.0.1:6379> LINSERT list after six seven
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "five"
3) "six"
4) "seven"

Lists总结:

  • 实际上是一个链表,before Node after 的结构,left、right都可以插入元素
  • 如果key不存在,将创建新的链表
  • 如果key存在,根据命令往左或者往右插入元素
  • 如果移除了所有值,空链表,那也就代表不存在了
  • 因为是链表,所有在两边插入和修改,效率高,获取中间的元素,效率会低一些

使用场景:消息排队、消息队列(LPUSH RPOP)、栈(LPUSH LPOP)

4.Sets(集合)数据类型常用命令

set中的值不能有重复的,sets的所有命令都是以S开头的

命令描述
SADD将一个或者多个元素添加到指定集合中,如果key不存在,则先创建再添加
SMEMBERS返回一个指定集合中的所有元素
SISMEMBER判断一个集合中有没有指定的元素
SCARD返回集合中元素的数量,如果key不存在,则返回0
SRANDMEMBER随机从集合中抽取一个元素返回,可以设置count决定返回个数
SREM指定一个元素,将它从集合中移除
SPOP从集合移除并返回一个或多随机个元素
SMOVE将指定元素从集合A移动到集合B中
# 向myset集合中添加多个元素
127.0.0.1:6379> sadd myset a b c d
(integer) 4
# 返回myset集合中的所有元素
127.0.0.1:6379> smembers myset
1) "c"
2) "b"
3) "d"
4) "a"
# 返回myset中元素的个数
127.0.0.1:6379> scard myset
(integer) 4
# 判断myset集合里有没有a元素
127.0.0.1:6379> SISMEMBER myset a
(integer) 1

=====================================================
# 下面测试一下SRANDMEMBER命令的用法
# 先创建一个myset集合
127.0.0.1:6379> sadd myset a b c d
(integer) 4
127.0.0.1:6379> smembers myset
1) "c"
2) "b"
3) "d"
4) "a"

# 随机从myset集合中返回两个元素,count大于0并且小于元素的个数,返回count个随机元素
127.0.0.1:6379> SRANDMEMBER myset 2
1) "a"
2) "d"
# 返回myset中所有元素。count大于元素的个数,将集合所有元素返回
127.0.0.1:6379> SRANDMEMBER myset 6
1) "c"
2) "b"
3) "d"
4) "a"
# count小于0,返回的随机元素数量是count的绝对值的个数
127.0.0.1:6379> SRANDMEMBER myset -2
1) "d"
2) "c"
# count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.
127.0.0.1:6379> SRANDMEMBER myset -5
1) "b"
2) "c"
3) "d"
4) "c"
5) "a"
===================================================
# 从myset集合中随机移除一个元素
127.0.0.1:6379> spop myset
"d"
127.0.0.1:6379> smembers myset
1) "c"
2) "b"
3) "a"
# 从myset集合中移除指定元素,没有这个元素则不删除
127.0.0.1:6379> srem myset a bc
(integer) 1
127.0.0.1:6379> SMEMBERS myset 
1) "c"
2) "b"
==================================================
# 清除一下数据库
127.0.0.1:6379> flushdb
OK
# 创建集合myset1和myset2
127.0.0.1:6379> sadd myset1 a b c d
(integer) 4
127.0.0.1:6379> sadd myset2 x y z
(integer) 3
# 将集合myset1中的b元素移动到myset2中
127.0.0.1:6379> smove myset1 myset2 b
(integer) 1
127.0.0.1:6379> smembers myset2
1) "y"
2) "b"
3) "z"
4) "x"

Sets还能操作交集、差集、并集

# 首先还是要创建两个集合用来测试
127.0.0.1:6379> sadd set1 a b c d
(integer) 4
127.0.0.1:6379> sadd set2 d c f x
(integer) 4
127.0.0.1:6379> sdiff set1 set2  #差集
1) "b"
2) "a"
127.0.0.1:6379> sinter set1 set2  # 交集
1) "c"
2) "d"
127.0.0.1:6379> sunion set1 set2  #并集
1) "c"
2) "a"
3) "b"
4) "f"
5) "x"
6) "d"

可以使用数学思想来使用Sets集合,QQ中的共同好友可以通过交集实现。

5.Hashs(哈希)数据类型常用命令

Redis是用key-value存储的,所以Hashs存储值的方式是key-map,进而演变成key-field-value。本质上与Strings类型没有太大区别,都是key-value
Hashs指令都是以H开头的。

命令描述
HSET设置 key 指定的哈希集中指定field 的value
HGET获取key 指定的哈希集中指定field所关联的value
HMSET设置 key 指定的哈希集中指定field的value ,可以同时设置多个field来获取多个value
HMGET获取key 指定的哈希集中指定field所关联的value ,可以同时设置多个field来获取多个value
HGETALL返回哈希集中所有的field和value
HLEN获取哈希表中包含的field的数量
HEXISTS检查在哈希表中是否存在指定的field
HVALS返回 哈希表中所有的field
HKEYS返回 哈希表中所有的value
HINCRBY增加哈希表中field对应的value的数值
HDEL将哈希表中的一个字段删除
# 创建一个hash,里面有字段field1、field2,有值abc、xyz
127.0.0.1:6379> hset hash field1 abc field2 xyz
(integer) 2
# 从hash中获取field1的值
127.0.0.1:6379> hget hash field1
"abc"
# 同时给user哈希表设置name、age字段,值为zhangsan、18
127.0.0.1:6379> hmset user name zhangsan age 18
OK
# 获取哈希表中name、age字段的值
127.0.0.1:6379> hmget user name age
1) "zhangsan"
2) "18"
# 获取user哈希表中的所有的字段和值
127.0.0.1:6379> HGETALL user
1) "name"
2) "zhangsan"
3) "age"
4) "18"
====================================================
# hash中有两个字段
127.0.0.1:6379> HLEN hash
(integer) 2
# hash中存在一个field1的字段
127.0.0.1:6379> hexists hash field1
(integer) 1
# 返回hash所有的字段
127.0.0.1:6379> HKEYS hash
1) "field1"
2) "field2"
# 返回hash所有的值
127.0.0.1:6379> HVALS hash
1) "abc"
2) "xyz"
==================================================
127.0.0.1:6379> hmset user name zhangsan age 18 sex man
OK
# 给name的自增1,因为name的值不是整型,将会报错
127.0.0.1:6379> HINCRBY user name 1
(error) ERR hash value is not an integer
# age的值是整型,自增1,返回自增后的值
127.0.0.1:6379> HINCRBY user age 1
(integer) 19
# 将sex字段删除
127.0.0.1:6379> hdel user sex
(integer) 1
127.0.0.1:6379> HGETALL user
1) "name"
2) "zhangsan"
3) "age"
4) "19"

相比较于Strings类型,Hashs更适合对象的存储,Strings适合字符存储

6.ZSets(有序集合)

在Sets的基础上增加了一个值,set k1 v1 -> zset k1 score v1 。
并且在有序集合里不允许存在重复的成员。
跟前面几种类型相似,所有的命令都是以Z开头

① ZADD key score member [score member …]

1.将指定成员添加到有序集合中去,添加时可以指定多个分数/成员(score/member)。
2.有序集合按照分数以递增的方式进行排序,并且不能存在重复的成员

② ZRANGE key start stop

从有序集合中返回指定范围内的元素,返回的元素按照从score从小到大排序

ZREVRANGE key start stop

从有序集合中返回指定范围内的元素,返回的元素按照从score从大到小排序

# 添加三个元素到myset中去
127.0.0.1:6379> zadd myset 1 one 2 two 3 three
(integer) 3
# 返回myset中所有的元素,withscores选项会将元素与score一起返回
127.0.0.1:6379> zrange myset 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"

③ ZRANGEBYSCORE key min max

1.设置一个区间,把在这个区间内的所有score的所有元素从有序集合中返回,返回的元素按从小到大排序
2.min和max可以设置为-inf和+inf ,表示负无穷大与正无穷大
3.区间默认是闭区间(小于等于或大于等于),可以通过在min或max前面设置一个 ( 符号来表示这是开区间(小于或大于)

ZREVRANGEBYSCORE key max min

1.与ZRANGEBYSCORE 类似,不过它是将元素从大到小排序
1.ZREVRANGEBYSCORE集合中按得分从高到底排序,所以"max"在前面,"min"在后面, ZRANGEBYSCORE集合中按得分从底到高排序,所以"min"在前面,"max"在后面。

# 设置一个工资表
127.0.0.1:6379> zadd salary 5000 zhangsan 2000 lisi 3000 wangwu
(integer) 3
# 返回工资在4000以内的名字(从小到大)
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 4000
1) "lisi"
2) "wangwu"
# 返回20004000之间的名字,不包括2000(从小到大)
127.0.0.1:6379> ZRANGEBYSCORE salary (2000 4000
1) "wangwu"
# 将salary集合中所有元素从大到小排序返回
127.0.0.1:6379> ZREVRANGEBYSCORE salary +inf -inf withscores
1) "zhangsan"
2) "5000"
3) "wangwu"
4) "3000"
5) "lisi"
6) "2000" 

④ ZREM key member

指定一个元素,将他从有序集合中移除

⑤ ZCARD key

返回有序集合中元素的个数

⑥ ZCOUNT key min max

设置一个区间,将在哪个区间内的元素个数返回

# 从salary中移除元素zhangsan
127.0.0.1:6379> ZREM salary lisi
(integer) 1
# 查看salary中所有元素个数
127.0.0.1:6379> ZCARD salary
(integer) 2
# 查看在salary中,score在19995000之间的元素个数
127.0.0.1:6379> ZCOUNT salary 1999 5000
(integer) 2

ZSets可以用于排行榜,普通消息、重要消息等场景。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值