Redis五大基本类型(狂神视频笔记)

Redis

Redis有16个数据库

默认使用第0个

数据库切换select number

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7YeUjKqs-1611627084867)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210124173424570.png)]

127.0.0.1:6379> select 3  #切换数据库
OK
127.0.0.1:6379[3]> dbsize  #查看数据库中的数据数量
(integer) 0
127.0.0.1:6379[3]> set name fengfeng  #添加数据
OK
127.0.0.1:6379[3]> dbsize
(integer) 1
127.0.0.1:6379[3]> select 7
OK
127.0.0.1:6379[7]> dbsize
(integer) 0
127.0.0.1:6379[7]> 

127.0.0.1:6379[3]> flushdb #清空数据库
OK
127.0.0.1:6379[3]> keys *
(empty array)
127.0.0.1:6379[3]> 
127.0.0.1:6379> flushall #清空全部数据库
OK

flushdb #清空数据库
flushall#清空全部数据库

Redis 是单线程的

所以Redis的性能瓶颈不是CPU,而是机器内存和网络带宽。

那么为什么Redis的速度如此快呢,性能这么高呢?QPS达到10W+

  • 误区1:高性能的服务器一定是多线程的?
  • 误区2:多线程(CPU上下文会切换!)一定比单线程效率高!

核心:Redis是将所有的数据放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时的操作!),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上的,在内存存储数据情况下,单线程就是最佳的方案

string

移动
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name"

move

设置过期时间expire
127.0.0.1:6379[1]> get name
"fengfeng"
127.0.0.1:6379[1]> expire name 10
(integer) 1
127.0.0.1:6379[1]> ttl name
(integer) 6
127.0.0.1:6379[1]> ttl name #查看剩余时间
(integer) 4
127.0.0.1:6379[1]> ttl name
(integer) 3
127.0.0.1:6379[1]> ttl name
(integer) 2
127.0.0.1:6379[1]> ttl name
(integer) 0
127.0.0.1:6379[1]> ttl name
(integer) -2
127.0.0.1:6379[1]> get name
(nil)
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> type age  #查看当前key的类型
string
127.0.0.1:6379> type name
string

127.0.0.1:6379> set key1 key
OK
127.0.0.1:6379> set key1 v1
OK
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> append key1 hello 
#追加字符串,如果当前key不存在,就相当于 set key
(integer) 7
127.0.0.1:6379> get key1 
"v1hello"
127.0.0.1:6379> strlen key1  #获取字符串长度
(integer) 7
127.0.0.1:6379> append key1 ,fengfeng
(integer) 16
127.0.0.1:6379> get key1
"v1hello,fengfeng"
127.0.0.1:6379> strlen key1
(integer) 16
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views  #自增一
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views  #自减一
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379> incrby views 10  #按照步长增
(integer) 9
127.0.0.1:6379> incrby views 10
(integer) 19
127.0.0.1:6379> decrby views 5  #按照步长减
(integer) 14
127.0.0.1:6379> decrby views 5
(integer) 9

getrange 🎃截取字符串

setrange :替换字符串

127.0.0.1:6379> set key1 hello,fengfeng,i miass you
(error) ERR syntax error
127.0.0.1:6379> set key1 "hello,fengfeng,i miass you"
OK
127.0.0.1:6379> get key1
"hello,fengfeng,i miass you"
127.0.0.1:6379> strlen key1
(integer) 26
127.0.0.1:6379> getrange key1 0,5
(error) ERR wrong number of arguments for 'getrange' command
127.0.0.1:6379> getrange key1 0 5  #截取字符串[0,5]双闭区间
"hello,"
127.0.0.1:6379> getrange key1 0 -1  #全部
"hello,fengfeng,i miass you"

127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> strlen key2
(integer) 7
127.0.0.1:6379> setrange key2 1 xxx  #替换字符串
(integer) 7
127.0.0.1:6379> get key2
"axxxefg"

setex : (set with expire) 设置过期时间

setnx :(set if not exist) 如果过不存在再设置!(在分布式中经常使用!)

127.0.0.1:6379> setex key 30 hello
OK
127.0.0.1:6379> ttl key
(integer) 24
127.0.0.1:6379> setnx mykey redis
(integer) 1
127.0.0.1:6379> keys *
1) "key1"
2) "key2"
3) "mykey"
4) "key"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> ttl key
(integer) -2
127.0.0.1:6379> set mykey "mohoDB"
OK
127.0.0.1:6379> get mykey
"mohoDB"
127.0.0.1:6379> setnx mykey redis #存在mykey所以不能覆盖
(integer) 0
127.0.0.1:6379> get mykey
"mohoDB"

mset : 批量添加

mget : 批量获取

msetnx :🚛类似于setnx,只不过是原子性操作

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key2"
3) "k2"
4) "k3"
5) "mykey"
6) "k1"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4  #能够说明msetnx是原子性操作
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> 

存取对象

设计user:1 对象,👆值为json字符来保存一个对象
第二个就用的巧妙的key设计,user:{id}:{filed},如此设计zairedis中是完全可以的🥇
127.0.0.1:6379> set user:1 {name:zhangsan,age:3}
OK
127.0.0.1:6379> get user:1
"{name:zhangsan,age:3}"
127.0.0.1:6379> mset user:2:name lisi user:2:age 5
OK
127.0.0.1:6379> get user:2
(nil)
127.0.0.1:6379> mget user:2
1) (nil)
127.0.0.1:6379> mget user:2:name user:2:age
1) "lisi"
2) "5"
127.0.0.1:6379> 

getset :😗先get再set

127.0.0.1:6379> getset  db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb
"redis"
127.0.0.1:6379> get db
"mongodb"

String类似的使用场景:value除了是字符串还可以是数字,用途举例:

  • 计数器
  • 统计多单位的数量:uid:123666:follow 0
  • 粉丝数
  • 对象存储缓存

List

在redis中,我们可以把list玩成,栈、队列、阻塞队列

所有的list命令都是 l 开头的

lpush :将一个值或多个值,插入列表(左)

rpush :🗾将一个将一个值或多个值,插入列表(右)

lrange:查看列表数据(全部或指定范围)

127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list o -1
(error) ERR value is not an integer or out of range
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"

lpop :移除list的第一个元素

rpop :移除list的最后一个元素

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"

lindex :🚡通过下标获得list中的某一个值

llen: 返回列表长度

127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379> lindex list 0
"two"
#############################
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3

127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> llen list
(integer) 3

移除指定的值

lrem:💛移除指定个数的指定的value值,精确匹配

127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> clear
127.0.0.1:6379> lrem list 1 one
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"

ltrim:🚛 列表截断,闭区间;通过下标截取指定的长度,这个list已经改变了,截断

127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
3) "hello2"
4) "hello3"
127.0.0.1:6379> ltrim mylist 1 2    # 
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"

rpoplpush:💴移除列表最后一个元素,将他移动到新的列表中!

127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpush mylist hello1
(integer) 2
127.0.0.1:6379> rpush mylist hello2
(integer) 3
127.0.0.1:6379> rpoplpush mylist myotherlist 
"hello2"
127.0.0.1:6379> lrange mylist
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "hello2"

lset :👖将列表中指定下标的值替换为另一个值,更新操作

127.0.0.1:6379> lset list 0 item ##不存在这个list就没办法替换,报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "value1"
127.0.0.1:6379> lset list 0 item ##存在就替换,类似于更新
OK
127.0.0.1:6379> lrange list 0 -1
1) "item"

linsert:🕹将某个具体的value插入到列表中某个元素的前面后者后面

127.0.0.1:6379> rpush list hello
(integer) 1
127.0.0.1:6379> rpush list world
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> linsert list before world other
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> linsert list after world !!!
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "other"
3) "world"
4) "!!!"

小结✴️

  • list实际上是一个链表,before Node after , left, right 都可以插入值
  • 如果key不存在,则创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,也代表不存在
  • 在两边插入或者改动值,效率最高!修改中间元素,效率相对较低

应用:

消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)

set

set不能操作重复数

sadd:🛰set集合中添加元素

member:查看指定set集合中的元素

sismember:判断某一个值是不是在set中

scard: 获取元素个数

127.0.0.1:6379> sadd myset hello
(integer) 1
127.0.0.1:6379> sadd myset fengfeng
(integer) 1
127.0.0.1:6379> sadd myset lovejackson
(integer) 1
127.0.0.1:6379> smembers myset
1) "hello"
2) "lovejackson"
3) "fengfeng"
127.0.0.1:6379> ismember myset hello
(error) ERR unknown command `ismember`, with args beginning with: `myset`, `hello`, 
127.0.0.1:6379> sismember myset hello
(integer) 1
127.0.0.1:6379> sismember myset world
(integer) 0
127.0.0.1:6379> sadd myset hello  ##添加重复的就失败了
(integer) 0
127.0.0.1:6379> scard myset  ##获取set集合中的元素
(integer) 3



srem:移除元素

127.0.0.1:6379> srem myset hello
(integer) 1
127.0.0.1:6379> scard myset
(integer) 2
127.0.0.1:6379> smember myset
(error) ERR unknown command `smember`, with args beginning with: `myset`, 
127.0.0.1:6379> smembers myset
1) "lovejackson"
2) "fengfeng"

spop:⚖️随机移除一个元素

127.0.0.1:6379> smembers myset
1) "jacky"
2) "lovejackson"
3) "fengfeng"
127.0.0.1:6379> spop myset
"lovejackson"

srandmember🛰随机抽选指定个数的元素

127.0.0.1:6379> SRANDMEMBER myset
"fengfeng"
127.0.0.1:6379> SRANDMEMBER myset
"lovejackson"
127.0.0.1:6379> srandmember myset
"fengfeng"
127.0.0.1:6379> srandmember myset
"fengfeng"
127.0.0.1:6379> srandmember myset 2
1) "lovejackson"
2) "jacky"

rmove:😋将一个指定的值移动到另外一个set集合中

127.0.0.1:6379> sadd myset hello
(integer) 1
127.0.0.1:6379> sadd myset world
(integer) 1
127.0.0.1:6379> sadd myset fengfeng
(integer) 1
127.0.0.1:6379> smove myset otherset fengfeng
(integer) 1
127.0.0.1:6379> smembers myset
1) "hello"
2) "world"
127.0.0.1:6379> smembers otherset
1) "fengfeng"

微博,b站,共同关注~(并集)共同好友

  • 差集

  • 交集

  • 并集

127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
127.0.0.1:6379> sdiff key1 key2
1) "a"
2) "b"
127.0.0.1:6379> sdiff key2 key1 #差集
1) "e"
2) "d"
127.0.0.1:6379> sinter key1 key2  #交集
1) "c"
127.0.0.1:6379> sunion key1 key2	#并集
1) "e"
2) "b"
3) "c"
4) "a"
5) "d"

Hash(哈希)

Map集合,key-map ! 时候这个值是一个map集合

hset:添加

hmset:添加多个

hget:获取

hmget:获取多个

hgetall:获取全部以key value的形式呈现

127.0.0.1:6379> hset myhash file1 fengfeng
(integer) 1
127.0.0.1:6379> hget myhash file1
"fengfeng"
127.0.0.1:6379> hmset myhash file1 jacky file2 love file3 jackson
OK
127.0.0.1:6379> hmget myhash file1 file2 file3
1) "jacky"
2) "love"
3) "jackson"
127.0.0.1:6379> hgetall myhash
1) "file1"
2) "jacky"
3) "file2"
4) "love"
5) "file3"
6) "jackson"

hdel​:🍀删除hash指定的key字段,对应的value的删掉了

127.0.0.1:6379> hdel myhash file1
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "file2"
2) "love"
3) "file3"
4) "jackson"

hlen:🐤长度

hexists:是否存在这个字段

127.0.0.1:6379> hgetall myhash
1) "file2"
2) "love"
3) "file3"
4) "jackson"
5) "file1"
6) "jacky"
127.0.0.1:6379> hlen myhash
(integer) 3
#########################################################
127.0.0.1:6379> hexists myhash file1
(integer) 1
127.0.0.1:6379> hexists myhash file9
(integer) 0

hkeys:只获得所有的field

hvals:只获得所有的values

127.0.0.1:6379> hkeys myhash
1) "file2"
2) "file3"
3) "file1"
127.0.0.1:6379> hvals myhash
1) "love"
2) "jackson"
3) "jacky"

hincrby: 增加,加负数就是减少

hsetnx:🏮类似setnx

127.0.0.1:6379> hset myhash file5 5
(integer) 1
127.0.0.1:6379> hincrby myhash file5 2
(integer) 7
127.0.0.1:6379> hincrby myhash file5 -1
(integer) 6
127.0.0.1:6379> hsetnx myhash file6 123
(integer) 1
127.0.0.1:6379> hsetnx myhash file6 987
(integer) 0

Hash变更的数据user name age,尤其是用户信息之类的,经常变动的信息!Hash更适合于对象的存储,Sring更加适合字符串存储!

127.0.0.1:6379> hset user:1 name hanmeimei age 5
(integer) 2
127.0.0.1:6379> hmset user:1 sex female habbit swim
OK
127.0.0.1:6379> hgetall user:1
1) "name"
2) "hanmeimei"
3) "age"
4) "5"
5) "sex"
6) "female"
7) "habbit"
8) "swim"

Zset

zadd

zrangebyscore:(可以带参数withscores)只能从小值到大值

-inf:负无穷

+inf:正无穷

ZREVRANGE:从大到小

127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
127.0.0.1:6379> zadd myzset 3 three
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
############################################################
127.0.0.1:6379> zadd salary 2500 xiaobai
(integer) 1
127.0.0.1:6379> zadd salary 5000 xiaozie
(integer) 1
127.0.0.1:6379> zadd salary 1000 xiaosa
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf
1) "xiaosa"
2) "xiaobai"
3) "xiaozie"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores
1) "xiaosa"
2) "1000"
3) "xiaobai"
4) "2500"
5) "xiaozie"
6) "5000"
127.0.0.1:6379> zrangebyscore salary -inf 2500
1) "xiaosa"
2) "xiaobai"
#############################################################
127.0.0.1:6379> ZREVRANGE salary 0 -1 withscores
1) "xiaozie"
2) "5000"
3) "xiaosa"
4) "1000"

zrem:☯️移除元素

zcard:获取集合中的个数

127.0.0.1:6379> zrange salary 0 -1
1) "xiaosa"
2) "xiaobai"
3) "xiaozie"
127.0.0.1:6379> zrem salary xiaobai
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "xiaosa"
2) "xiaozie"
127.0.0.1:6379> zcard salary
(integer) 2

zcount:获取指定区间的成员数量

127.0.0.1:6379> zadd myset 1 hello 2 jackson 3 jacky
(integer) 3
127.0.0.1:6379> zcount myset 1 3
(integer) 3
127.0.0.1:6379> zcount myset 1 2
(integer) 2

应用案例:

  • set排序 存储班级成绩表 工资表排序!

  • 普通消息,1.重要消息 2.带权重进行判断

  • 排行榜应用实现,取Top N测试

Redis API文档。Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。redis的官网地址,非常好记,是redis.io。(域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)目前,Vmware在资助着redis项目的开发和维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值