redis的世界

Redis基本操作

redis --缓存数据库

​ 为什么要使用缓存?

​ 因为每次查询数据库(Mysql、oracle)都会比较费时间,如果建立一个缓存数据库那么查询就会很快(就比如操作系统中,把经常访问的东西放入缓存中,访问起来就非常快)

redis的世界

redis能做什么?

1、内存存储、持久化

2、效率高、用于高速缓存

3、发布订阅系统

4、地图信息分析

5、计时器、计数器(浏览量)

key 命令:

key *   表示查看所有的key

exists 名称   :查看这个名称是否存在

move 名称 1 :移除一个数据类型

expire name  10:设置过期时间,10表示十秒钟后就自动过期 . ttl name :查看剩余时间

type name :查看name的类型

FLUSHDB:删除所有key,也就是清空数据库中的key

一、String

应用场景:统计数量、计数器、粉丝数、关注数…

可以存储比如jpg图片或者序列化的对象。string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

	set name hui //设置值
	get name 	//获得值
	append name "hello" //追加一个"hello"到name后面,如果key不存在 就相当于set了一个key
	strlen name //返回name的长度
	set age 20
	incr age //对age实行+1操作  21
	decr age //对age实行-1操作 20
	incrby age 10 //对age实行+10的操作
	decrby age 10 //对age实行-10的操作
	
	========================================
	字符串范围截取或替换:range
	 set name "abcdefg" //设置key value
	 getrange name 0 2 //截取字符串name中的[0,2]的值 abc
	 setrange name 2 xxx //替换从下标为2开始的三个字符为xxx  值为:abxxxfg
	 ===========================================
	 # setex(set with expire) //设置过期时间
	 # setnx(set if not exist) //不存在设置(在分布式锁中比较常用)
	 setex mykey 30 "hello,world!"  //设置mykey的值且30秒后过期
	 setnx mykey "hello,student"    //如果mykey不存在,就创建mykey 或者 存在的话,就创建失败
	 ============================================
	 # 批量设置和获取   mset和mget
	 mset k1 v1 k2 v2 k3 v3 //设置多个key value
	 mget k1 k2 k3			//获取多个key
	 msetnx k1 v1 k4 v4    //因为k1存在所以设置不会成功,k4即使不存在也无法被创建(原子性操作:要么全成功,要么全失败)
	 
	 
	 #可以将set构建成对象方式:
	 	set user:{id}:{fields} //这种方式可以设置可以达到(对象:字段:值)
	 	mset user:1:name 张三 user:1:age 20
	 	mget user:1:name user:1:age 	//结果为:"张三" \n "20"
	 
	 ==============================================
	 getset #先进行get再set
	 列子:
	 	getset database "mysql" //如果没有database这个key,就会先返回一个空(nil,然后会set值到这个key
	 	getset database "oracle" //结果为"mysql",显示之后又会马上再设置database的值为"oracle"

二、List

应用场景:粉丝列表、点赞人员、关注列表、(可以做简单的消息队列处理)

# List类型的命令都是l开头去书写的(LPUSH、LINDEX、LLEN、LPOP....)
# 可以实现队列(LPUSH、RPUSH)、栈(只使用一种插入方式和弹出方式 -> 就能实现栈的操作)
==============================================
LPUSH KEY VALUE [VALUE....]  # 向List的key中插入value值(头部插入)
RPUSH key value [value....]  # 尾部插入

==============================================
LPOP KEY   #在List列表的key中弹出左边一个值
RPOP KEY   #在List列表中key弹出右边的值

==============================================
LRANGE key  0 1  # 获取key中0到1的值
LRANGE key 0 -1 # 获取key中所有的值

==============================================
LINDEX key 下标值   # 获取下标的值

==============================================
LLEN key  # 查看key的长度


==============================================
LREM key count value  # 移除指定的值

# example: 
127.0.0.1:6379> lpush k1 v1 v1 v1 # 插入三个数(List 中允许重复值)
127.0.0.1:6379> LRANGE k1 0 -1  # 获取key中所有的值
1) "v1"
2) "v1"
3) "v1"
127.0.0.1:6379> LPUSH k1 v2 v3  # 再次往k1 中插入两个数
(integer) 5
127.0.0.1:6379> LRANGE k1 0 -1 # 获取key中所有的值
1) "v3"
2) "v2"
3) "v1"
4) "v1"
5) "v1"

127.0.0.1:6379> LREM k1 3 v1  # 移除k1中三个一样的值v1
(integer) 3
127.0.0.1:6379> LRANGE k1 0 -1  # 查看
1) "v3"
2) "v2"
127.0.0.1:6379> LREM k1 1 v2 # 移除k1 中1个v2
(integer) 1
127.0.0.1:6379> LRANGE k1 0 -1 # 查看
1) "v3"
127.0.0.1:6379> lpush kk k1 k2 k3  # 将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么在进行 push 操作前会创建一个
(integer) 3						   # 空列表。 如果 key 对应的值不是一个 list 的话,那么会返回一个错误。

127.0.0.1:6379> lrange kk 0 -1 # 返回列表指定区间内的元素。
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> lpop kk  # 从左边弹出一个元素
"k3"
127.0.0.1:6379> rpop kk # 从右边弹出一个元素
"k1"
127.0.0.1:6379> lrange kk 0 -1 
1) "k2"
127.0.0.1:6379> lpush kk k3 k4
(integer) 3
127.0.0.1:6379> lrange kk 0 -1  
1) "k4"
2) "k3"
3) "k2"
127.0.0.1:6379> LINDEX kk 2 # 获取到对应下标2 的值
"k2"
127.0.0.1:6379> BLPOP kk 3  # 阻塞弹出,对kk中弹出一个元素进行设置时间自动弹出(左弹出)
1) "kk"
2) "k4"
127.0.0.1:6379> LRANGE kk 0 -1
1) "k3"
2) "k2"

三、set

应用场景: 实现点赞,签到,like、实现关注模型,可能认识的人 等功能

# set存储是无序存储~
127.0.0.1:6379> sadd hh h1 h2 h3 h4 # 添加元素到key中
(integer) 4
127.0.0.1:6379> SMEMBERS hh  # 查看key下的所有元素
1) "h3"
2) "h4"
3) "h2"
4) "h1"
127.0.0.1:6379> SPOP hh 4  # 弹出key下 四个元素
1) "h3"
2) "h1"
3) "h2"
4) "h4"
127.0.0.1:6379> SMEMBERS hh  # 再次查看(无数据,因为添加四个又弹出四个)
(empty list or set)
==================================================
127.0.0.1:6379> SCARD hh # 查看key的length长度
(integer) 3
127.0.0.1:6379> SRANDMEMBER hh 2 # 随机弹出两个元素
1) "h3"
2) "h1"

==================================================
127.0.0.1:6379> SMEMBERS hh # 查看元素
1) "h3"
2) "h2"
3) "h1"
127.0.0.1:6379> SPOP hh 2  # 弹出两个元素
1) "h3"
2) "h2"
127.0.0.1:6379> SMEMBERS hh
1) "h1"

四、zset

**应用场景:zset天生是用来做排行榜的、好友列表, 去重, 历史记录等业务需求 **

# zset相对于set,zset是一个有序集合,而set是无序集合

127.0.0.1:6379> zadd curry 1 stephen # 添加元素
(integer) 1
127.0.0.1:6379> zadd curry 1 curry
(integer) 1
127.0.0.1:6379> ZRANGE curry 0 -1 # 返回key 中所有元素
1) "curry"
2) "stephen"
127.0.0.1:6379> zadd curry 2 james # 增加元素
(integer) 1
127.0.0.1:6379> ZRANGE curry 0 -1  # 返回key 中所有元素(正序返回)
1) "curry"
2) "stephen"
3) "james"
127.0.0.1:6379> ZREVRANGE curry 0 -1 # 返回元素(倒序返回)
1) "james"
2) "stephen"
3) "curry"
==================================================
127.0.0.1:6379> ZCARD curry  # 返回key中元素个数
(integer) 3
==================================================
127.0.0.1:6379> zadd curry 1 stephen
(integer) 1
127.0.0.1:6379> ZADD curry 2 curry
(integer) 1
127.0.0.1:6379> ZADD curry 3 mengshen
(integer) 1
127.0.0.1:6379> ZRANGE curry 0 -1
1) "stephen"
2) "curry"
3) "mengshen"
127.0.0.1:6379> EXPIRE curry 30  # 为key设置过期时间
(integer) 1
127.0.0.1:6379> ttl curry   # 查看key的过期时间
(integer) 28
127.0.0.1:6379> ttl curry
(integer) 21
127.0.0.1:6379> PERSIST curry  # 取消curry的过期时间(即不会随着时间过期)
(integer) 1
127.0.0.1:6379> ttl curry
(integer) -1
127.0.0.1:6379> ZRANGE curry 0 -1  # 查看key中所有元素
1) "stephen"
2) "curry"
3) "mengshen"
==================================================


五、Hash

应用场景:缓存、登陆session等…

# Hash 存储是由 key : value  形式存储

127.0.0.1:6379> HMSET hash1 k1 v1 k2 v2 k3 v3  # 批量设置设置hash1键对应的字段:值
OK
127.0.0.1:6379> HGETALL hash1  # 获取hash1键下全部的的key value 形式的值
1) "k1"
2) "v1"
3) "k2"
4) "v2"
5) "k3"
6) "v3"
127.0.0.1:6379> HSET hash1 k4 v5 # 设置单独的hash元素
(integer) 1
127.0.0.1:6379> HGETALL hash1   # 获取全部元素值
1) "k1"
2) "v1"
3) "k2"
4) "v2"
5) "k3"
6) "v3"
7) "k4"
8) "v5"
127.0.0.1:6379> HMGET hash1 k1 k2 k3 k4 k5  # 获取对应所在key下的 field字段的value (k5键不存在就返回nil)
1) "v1"
2) "v2"
3) "v3"
4) "v5"
5) (nil)
==================================================
127.0.0.1:6379> hset htest k1 v1  # 设置一个值
(integer) 1
127.0.0.1:6379> HSETNX htest k1 v2 # 想要修改k1的value  可是使用了HSETNX无法修改(不会覆盖以前的值)
(integer) 0
127.0.0.1:6379> HGETALL htest # 获取键中所有的键值对值
1) "k1"
2) "v1"
127.0.0.1:6379> HVALS htest  # 获取所有的value
1) "v1"
127.0.0.1:6379> HKEYS htest # 获取所有的key
1) "k1"
127.0.0.1:6379> HEXISTS htest k1 # 判断fields 是否存在
(integer) 1
==================================================
127.0.0.1:6379> hset test plus 1
(integer) 1
127.0.0.1:6379> HGETALL test
1) "plus"
2) "1"
127.0.0.1:6379> HINCRBY test plus 2  # 对plus进行自增
(integer) 3
127.0.0.1:6379> hget test plus  # 获取自增后的值
"3"
127.0.0.1:6379> HINCRBY test plus 77 # 对plus的value进行自增77
(integer) 80
127.0.0.1:6379> HGETALL test  # 获取key(test)的value
1) "plus"
2) "80"
127.0.0.1:6379> HINCRBYFLOAT test plus 2  # 浮点数自增
"82"(浮点数float)
127.0.0.1:6379> hlen test # 返回test这个key的长度
(integer) 1
127.0.0.1:6379> hstrlen test plus  # 返回key对应value 的长度
(integer)

三种特殊类型

1、geospatial

geospatial => 应用场景:地理位置、附近的人、导航…

  • 有效的经度从-180度到180度。
  • 有效的纬度从-85.05112878度到85.05112878度。
  • 前提:所有的key都需要录入城市的经纬度
# example:
# GEOADD / GEOPOS 用法
# 格式: GEOADD key(键值) longitude(经度) latitude(纬度) member(名称) [longitude latitude member ...]
127.0.0.1:6379> GEOADD china:city 106.5 29.4 chongqing # 添加重庆位置详情
(integer) 1
127.0.0.1:6379> GEOPOS china:city chongqing  # 查看重庆地理位置
   1) "106.49999767541885"
   2) "29.399998800186417"
   
####################################################
# GEOADD / GEODIST 用法   计算两个人或城市的距离
127.0.0.1:6379> GEOADD instance 106.5 29.4 chongqing  104.1 30.6 chengdu # 添加两个城市
(integer) 2
127.0.0.1:6379> GEODIST instance chongqing chengdu  # 计算两个城市的距离(m)
"266931.9728"
127.0.0.1:6379> GEODIST instance chongqing chengdu km # 计算两个城市的距离(km)
"266.9320"
####################################################
GEORADIUS:
	GEORADIUS china:city longitude latitude radius m|km|ft|mi # (以经纬度为中心寻找radius为半径的所有距离在内的城市或人)
127.0.0.1:6379> GEORADIUS china:city 105 28 500 km  # 以(105, 28)为中心 寻找出半径500为中心的500km的城市
1) "chongqing"


2、BitMap

bitmap应用场景存储用户是否在线状态…

bit: 会让我们联想到的就是二进制,但是底层还是应用的是对字符串的操作!

参考博客redis三种特殊类型

# bitmap 主要命令
setbit   getbit   bitcount

##########################################################
setbit key offset value   # 设置一个key(可以是字段) offset如果长度超过字符串长度,会默认用0进行填充,  value表示状态默认为0(只能为1或0)
# example
setbit test 2 1 # 设置test默认长度为2且值为1
gitbit test 1 # 获取test状态值, 1表示value

##########################################################
127.0.0.1:6379> setbit ahui 2 1  # 设置值
(integer) 0
127.0.0.1:6379> setbit ahui 5 1
(integer) 0
127.0.0.1:6379> GETBIT ahui 2   # 获取offset为2的个数
(integer) 1
127.0.0.1:6379> BITCOUNT ahui   # 统计key中元素个数
(integer) 2

3、HyperLogLog

应用场景:统计不重复的元素计数(省内存)

统计数据很快,但是无法查看统计元素内容!!!!

# 主要命令  
pfadd key value [value....]  # 存入元素
pfcount key # 返回key中所有元素
pfadd key1  value [value ...] # 再次存入
pfmerge key2 key1 key  # 创建key2   把key1 key的值进行合并
pfcount key2   # 统计key2集合中的个数

##########################################################
127.0.0.1:6379> PFADD key a b c d e  # 添加元素
(integer) 1
127.0.0.1:6379> pfcount key   # 统计元素
(integer) 5
127.0.0.1:6379> pfadd key1 1 2 3 4 5    
(integer) 1
127.0.0.1:6379> pfcount key1  
(integer) 5
127.0.0.1:6379> PFMERGE key2 key key1   # 合并两个key的数值
OK
127.0.0.1:6379> pfcount key2     # 查看合并后的数量
(integer) 10

y1 key的值进行合并
pfcount key2 # 统计key2集合中的个数

##########################################################
127.0.0.1:6379> PFADD key a b c d e # 添加元素
(integer) 1
127.0.0.1:6379> pfcount key # 统计元素
(integer) 5
127.0.0.1:6379> pfadd key1 1 2 3 4 5
(integer) 1
127.0.0.1:6379> pfcount key1
(integer) 5
127.0.0.1:6379> PFMERGE key2 key key1 # 合并两个key的数值
OK
127.0.0.1:6379> pfcount key2 # 查看合并后的数量
(integer) 10

上一篇:cf1251 F. Red-White Fence NTT + 组合数学


下一篇:redis