前言: 学习redis之前,我们要首先了解一下什么是关系型数据库(mysql),什么是非关系型数据库(redis, MongoDB )
nosql,泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性
做完以上了解,那么开启redis的学习!
我们跳过安装过程,百度教程有很多
redis基础知识
redis默认16个数据库,默认使用第0个数据库
127.0.0.1:6379> ping #测试连接
PONG
127.0.0.1:6379> select 1 #切换数据库
OK
127.0.0.1:6379[1]> dbsize #查看数据库存储数
(integer) 0
127.0.0.1:6379[1]> set name xiaoming #设置一个key-value值
OK
127.0.0.1:6379[1]> keys * #查看所有key
1) "name"
127.0.0.1:6379[1]> get name #查看指定key的值
"xiaoming"
127.0.0.1:6379[1]> flushdb #清空当前数据库
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> flushall #清空所有数据库
OK
127.0.0.1:6379> clear #相当于linux的清理干净当前页面
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> exists name #是否存在key,存在返回1,不存在返回0
(integer) 1
127.0.0.1:6379> expire age 20 #设置key过期时间
(integer) 1
127.0.0.1:6379> ttl age
(integer) 16
127.0.0.1:6379> ttl age
(integer) 14
127.0.0.1:6379> ttl age
(integer) 11
127.0.0.1:6379> ttl age
(integer) 7
127.0.0.1:6379> ttl age #key过期
(integer) -2
127.0.0.1:6379> get age
(nil)
127.0.0.1:6379> set name xiaoming
OK
127.0.0.1:6379> type name #查看数据类型
string
redis五大基础类型和使用
String
应用场景:后台大多数据的字符串存储,也可以存储数字
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> append k1 hello #追加字符串
(integer) 7
127.0.0.1:6379> get k1
"v1hello"
127.0.0.1:6379> strlen k1 #获取字符串长度
(integer) 7
127.0.0.1:6379> append k2 hello #如果追加不存在此key,会新建一个key
(integer) 5
127.0.0.1:6379> keys *
1) "k2"
2) "k1"
应用场景:文章浏览量,点赞数,做计数器
127.0.0.1:6379> set k1 0
OK
127.0.0.1:6379> get k1
"0"
127.0.0.1:6379> incr k1 #数值+1,只能是数值可以,有字符会报错
(integer) 1
127.0.0.1:6379> incr k1
(integer) 2
127.0.0.1:6379> get k1
"2"
127.0.0.1:6379> decr k1 #数值-1,只能是数值可以,有字符会报错
(integer) 1
127.0.0.1:6379> get k1
"1"
127.0.0.1:6379> incrby k1 10 #设置增长步长
(integer) 11
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> decrby k1 5 #设置减少步长
(integer) 6
127.0.0.1:6379> get k1
"6"
127.0.0.1:6379> set k1 hello,xiaoming
OK
127.0.0.1:6379> get k1
"hello,xiaoming"
127.0.0.1:6379> getrange k1 0 5 #截取0到5字符
"hello,"
127.0.0.1:6379> getrange k1 0 -1 #获取全部
"hello,xiaoming"
127.0.0.1:6379> getrange k1 0 -1
"hello,xiaoming"
127.0.0.1:6379> setrange k1 1 good #替换指定字符串
(integer) 14
127.0.0.1:6379> get k1
"hgood,xiaoming"
127.0.0.1:6379> setex k1 20 hello #设置key过期时间
OK
127.0.0.1:6379> ttl k1
(integer) 14
127.0.0.1:6379> get k1
"hello"
127.0.0.1:6379> ttl k1
(integer) -2
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> setnx k2 redis #如果k2不存在设置成功,存在则失败,乐观锁中用
(integer) 1
127.0.0.1:6379> setnx k2 nginx #设置失败
(integer) 0
127.0.0.1:6379> get k2
"redis"
127.0.0.1:6379> mset k1 v1 k2 v2 #同时设置多个值
OK
127.0.0.1:6379> mget k1 k2 #同时获取多个值
1) "v1"
2) "v2"
127.0.0.1:6379> msetnx k1 v1 k3 v3 #保证原子性,一起成功一起失败
(integer) 0
#将对象存储在redis的string类型中
set user:1:{name:xiaoming,age:16}
#用法user:{id}:{filed}
127.0.0.1:6379> mset user:1:name xiaoming user:1:age 16
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "xiaoming"
2) "16"
127.0.0.1:6379> getset k1 v1 #先获取在设置值,没有返回空
(nil)
127.0.0.1:6379> getset k1 v2
"v1"
127.0.0.1:6379> get k1
"v2"
List
List可以做栈,队列,左右都可以进,都可以出,具体如下
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> 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> keys *
1) "list"
127.0.0.1:6379> lpop list #移除头部第一个
"three"
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 1 #通过索引获取一个值
"one"
127.0.0.1:6379> lindex list 0 #通过索引获取一个值
"two"
127.0.0.1:6379> rpush list one
(integer) 1
127.0.0.1:6379> rpush list two
(integer) 2
127.0.0.1:6379> rpush list three
(integer) 3
127.0.0.1:6379> rpush list three
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
3) "three"
4) "three"
127.0.0.1:6379> lrem list 2 three #移除指定个数的value
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
127.0.0.1:6379> ltrim list 1 1 #截取指定的长度
OK
127.0.0.1:6379> lrange list 0 -1
1) "two"
127.0.0.1:6379> lpush list v1
(integer) 1
127.0.0.1:6379> lpush list v2
(integer) 2
127.0.0.1:6379> lpush list v3
(integer) 3
127.0.0.1:6379> rpoplpush list newlist #移除原来列表最后一个元素到新列表
"v1"
127.0.0.1:6379> lrange newlist 0 -1
1) "v1"
127.0.0.1:6379> exists list
(integer) 0
127.0.0.1:6379> lset list 0 item #list不存在,不可以更新值
(error) ERR no such key
127.0.0.1:6379> lpush list v1
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "v1"
127.0.0.1:6379> lset list 0 item #list存在,可以更新新值
OK
127.0.0.1:6379> lrange list 0 -1
1) "item"
127.0.0.1:6379> linsert list before item world #往列表某个元素后插入一个值
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "world"
2) "item"
127.0.0.1:6379> linsert list after item hello #往列表某个元素前插入一个值
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "world"
2) "item"
3) "hello"
Set
set 的值是不可以重复,无序存储
127.0.0.1:6379> sadd myset hello #往set集合添加元素
(integer) 1
127.0.0.1:6379> sadd myset hello,world
(integer) 1
127.0.0.1:6379> sadd myset welcome,world
(integer) 1
127.0.0.1:6379> smembers myset #查看set集合全部元素
1) "hello,world"
2) "welcome,world"
3) "hello"
127.0.0.1:6379> sismember myset hello #查看元素是否存在,1存在,0不存在
(integer) 1
127.0.0.1:6379> sismember myset world
(integer) 0
127.0.0.1:6379> scard myset #统计元素个数
(integer) 3
127.0.0.1:6379> srem myset hello #移除一个指定元素
(integer) 1
127.0.0.1:6379> scard myset
(integer) 2
127.0.0.1:6379> smembers myset
1) "hello,world"
2) "welcome,world"
127.0.0.1:6379> smembers myset
1) "good1"
2) "good"
3) "welcome,world"
4) "good2"
5) "hello,world"
6) "good3"
1
127.0.0.1:6379> srandmember myset #随机抽取一个元素
"good1"
127.0.0.1:6379> srandmember myset
"good3"
127.0.0.1:6379> srandmember myset 2 #随机抽取2个元素
1) "good"
2) "welcome,world"
127.0.0.1:6379> spop myset #随机移除一个元素
"good2"
127.0.0.1:6379> spop myset
"hello,world"
127.0.0.1:6379> smembers myset
1) "welcome,world"
2) "good"
3) "good1"
4) "good3"
127.0.0.1:6379> smembers myset
1) "welcome,world"
2) "good"
3) "good1"
4) "good3"
127.0.0.1:6379> smove myset myset2 good #移动一个指定元素到新set集合
(integer) 1
127.0.0.1:6379> smembers myset2
1) "good"
127.0.0.1:6379> smembers k1
1) "c"
2) "b"
3) "e"
4) "a"
127.0.0.1:6379> smembers k2
1) "d"
2) "c"
3) "e"
4) "f"
127.0.0.1:6379> sdiff k1 h2 #差集
1) "b"
2) "c"
3) "e"
4) "a"
127.0.0.1:6379> sinter k1 k2 #交集 ,共同好友
1) "c"
2) "e"
127.0.0.1:6379> sunion k1 k2 #并集
1) "e"
2) "a"
3) "c"
4) "b"
5) "d"
6) "f"
Hash
相当于map集合,key-map 时候这个值是一个map集合!
应用场景:用户信息保存,经常变动的信息,hash更适合对象的存储
127.0.0.1:6379> hset myhash k1 v1 #set一个key-value
(integer) 1
127.0.0.1:6379> hget myhash k1 #获取一个key-value
"v1"
127.0.0.1:6379> hmset myhash k1 v1 k2 v2 #set多个key-value
OK
127.0.0.1:6379> hmget myhash k1 k2 #获取多个key-value
1) "v1"
2) "v2"
127.0.0.1:6379> hgetall myhash #获取全部
1) "k1"
2) "v1"
3) "k2"
4) "v2"
127.0.0.1:6379> hdel myhash k1 #移除一个key-value
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "k2"
2) "v2"
127.0.0.1:6379> hlen myhash #获取hash数量
(integer) 1
127.0.0.1:6379> hexists myhash k1 #判断hash指定字段是否存在
(integer) 1
127.0.0.1:6379> hexists myhash k1
(integer) 0
127.0.0.1:6379> hkeys myhash #只获取key
1) "k2"
127.0.0.1:6379> hvals myhash #只获取value
1) "v2"
127.0.0.1:6379> hset myhash field1 5
(integer) 1
127.0.0.1:6379> hincrby myhash field1 1 #增1
(integer) 6
127.0.0.1:6379> hincrby myhash field1 -1 #减1
(integer) 5
127.0.0.1:6379> hsetnx myhash field2 world #判断元素是否存在,1存在
(integer) 1
127.0.0.1:6379> hsetnx myhash field2 worlds #0不存在
(integer) 0
127.0.0.1:6379> hset user:1 name zhangsan #存储一个对象
(integer) 1
127.0.0.1:6379> hget user:1 name #获取一个对象值
"zhangsan"
Zset
Zset有序存储
应用场景:排行榜,阅读榜
127.0.0.1:6379> zadd myset 1 one #追加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 two 3 three #追加多个值
(integer) 2
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zadd salary 2500 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 5000 lisi
(integer) 1
127.0.0.1:6379> zadd salary 1000 zhaowu
(integer) 1
127.0.0.1:6379> zrem salary zhangsan #移除一个元素
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf #升序排序
1) "zhaowu"
2) "zhangsan"
3) "lisi"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores #升序排序,带成绩
1) "zhaowu"
2) "1000"
3) "zhangsan"
4) "2500"
5) "lisi"
6) "5000"
127.0.0.1:6379> zrangebyscore salary -inf 2500 withscores #升序排序,带成绩,有范围
1) "zhaowu"
2) "1000"
3) "zhangsan"
4) "2500"
127.0.0.1:6379> zrevrangebyscore salary +inf -inf withscores #降序排序,带成绩
1) "lisi"
2) "5000"
3) "zhangsan"
4) "2500"
5) "zhaowu"
6) "1000"
127.0.0.1:6379> zrange salary 0 -1 #从小到大排序
1) "zhaowu"
2) "zhangsan"
3) "lisi"
127.0.0.1:6379> zrevrange salary 0 -1 #从大到小排序
1) "lisi"
2) "zhangsan"
3) "zhaowu"
127.0.0.1:6379> zcard salary #获取集合个数
(integer) 3
127.0.0.1:6379> zcount myset 1 3 #获取指定区间成员个数
(integer) 3
三种特殊类型
geospatial
应用场景: 搜索附近人,计算两人距离
使用方式
1.先添加地理坐标和城市名(人名)
2.通过方法获取两地距离
3.以r为半径扫描获取附近的人
Hyperloglog
应用场景 :基数统计
只要12kb内存,有0.81%误差
127.0.0.1:6379> pfadd mykey a b c d e f d e f g h #添加元素
(integer) 1
127.0.0.1:6379> pfadd mykey2 e f g h i j k l
(integer) 1
127.0.0.1:6379> pfcount mykey2 #统计个数
(integer) 8
127.0.0.1:6379> pfmerge mykey3 mykey mykey2 #统计两者差值
OK
127.0.0.1:6379> pfcount mykey3
(integer) 12
Bitmap
二位数保存 0 1
应用场景:统计用0 ,1两种状态的情景 365打卡,1打卡,0没有打卡
127.0.0.1:6379> setbit sign 0 0 #设置有无打卡
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0
127.0.0.1:6379> getbit sign 4 #查看某天有无打卡
(integer) 0
127.0.0.1:6379> getbit sign 6
(integer) 1
127.0.0.1:6379> bitcount sign #统计总共打卡记录
(integer) 3