Redis基础数据类型和命令

Redis笔记

概述

Redis:远程字典服务

用处

1、内存存储,持久化,内存中是断电即失的、所以持久化非常重要。

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

3、发布订阅系统

4、计数器

5、地图信息分析

特性

1、多样的 数据类型

2、持久化

3、集群

4、事务

基础知识/命令

redis端口号为6379,为女明星merz的九宫格输入法

redis是单线程的

为什么redis单线程还是那么快

  • 核心 redis将所有数据存储在内存中,所以使用单线程去操作是效率最高的。

redis有16个数据库。默认使用第一个

select index #切换数据库

#查看所有key 
keys *
#清空数据库
flushdb
#清楚所有数据库
flushall
#删除键值
del key

Redis五大数据类型

redis-key

String

List

Set

Hash

Zset

String

百分之90的程序员只会用string类型

set                      #设置值
get                      #获得值
append                   #追加值 #如果当key不存在,则=set
atrlen                   #获取长度
getrange key start end 	 #截断字符串,下标start开始到end结束
setrange key start value #替换(replace)从下表start开始替换value
setex key second value   #设置有效时间为second的值value
setnx key value          #不存在key时才能设置(常用于分布式锁中)	
incr             #自增1
decr             #自减1
incrby key num   #自增num
decrby key num   #自减num

mset k v k2 v2 k3 v3	            #同时设置多个值
mget k  k2 k3  			    #同时获取多个值
msetnx 			            #为原子性的操作,把一行命令看作一个事务,其中操作不成功则整体失败

#对象
mset user:1 {name:lucas,age:12}     #用json字符来保存一个对象

getset 			            #先get再set,如果不存在,返回null,如果存在,先get出来再set进去

String的应用场景:value除了时字符串,还可以是数字

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

List

所有的list命令都是以L开头的

127.0.0.1:6379> lpush list one two three        #LPUSH key value1 value2... 将一个或多个插入列表头部(左)
(integer) 3
127.0.0.1:6379> lpush list four
(integer) 4
127.0.0.1:6379> lrange list 0 -1		#lrange 获取list的值
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrange list 0 2			#LRANGE KEY SATRT STOP 获取指定区间的值 
1) "four"
2) "three"
3) "two"
127.0.0.1:6379>
127.0.0.1:6379> rpush list zero   		#RPUSH KEY VALUE 从右边插入list尾部(右)
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
5) "zero"
127.0.0.1:6379>
127.0.0.1:6379> lrange list 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
5) "zero"
127.0.0.1:6379> lpop list		#LPOP KEY 移除list第一个元素(左)
"four"
127.0.0.1:6379> rpop list		#RPOP KEY 移除list尾部的元素(右)
"zero"
127.0.0.1:6379>  
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lindex list 0         #LINDEX key index 获取指定下标值
"three"

127.0.0.1:6379> llen list 	      #LLEN KEY 获取当前key的长度
(integer) 3
127.0.0.1:6379>  lrem list 1 one      #LREM KEY COUNT VALUE移除指定个数的值(精确移除)
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"

127.0.0.1:6379> rpush list 1 2 3 4 5 6
(integer) 6
127.0.0.1:6379> ltrim list 1 3		#LTRIM KEY START STOP通过下标截取list中指定位置的值
OK
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "3"
3) "4"

RPOPLPUSH KEY NEWKEY 		        #将key中右边第一个值移除再push到一个新的newkey中

127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> lset list 0 1		#LSET 将list中指定下标的值更新为value
OK
127.0.0.1:6379> lset list 4 4    	#如果不存在下标,则报错
(error) ERR index out of range
127.0.0.1:6379>

127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> linsert list before world my	#LINSERT KEY BEFORE/AFTER VALUE,在list中指定value的前或后插入一个值 
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "my"
3) "world"
127.0.0.1:6379>

小结

list实际上是个链表 before node after left right都可以插入

在两边插入或改动值,效率最高,中间元素则效率会相对低一些

应用场景:消息队列 (LPUSH RPOP)先进先出

​ 栈(LPUSH LPOP)先进后出

Set

set内值不能重复(唯一)

127.0.0.1:6379> sadd test i love u "I Love You"	 #SADD 往key里存储一个或多个值
(integer) 4
127.0.0.1:6379> smembers test			 #查看key中的元素
1) "u"
2) "love"
3) "I Love You"
4) "i"
127.0.0.1:6379> sismember test u		 #查询value是否在key中
(integer) 1					 #在侧返回1,不存在则返回0
127.0.0.1:6379> sismember test a
(integer) 0
127.0.0.1:6379> scard test			 #获取set集合中元素个数
(integer) 4

127.0.0.1:6379> srem test love			 #移除set中指定值
(integer) 1
127.0.0.1:6379> smembers test
1) "i love you"
2) "you"
3) "i"

#因为set是无序不重复的
127.0.0.1:6379> SRANDMEMBER test 1		#srandmember,随机抽取key中的一个或多个值
1) "i"
127.0.0.1:6379> SRANDMEMBER test 2		#随机获取test中的两个值
1) "you"
2) "i"

127.0.0.1:6379> spop test 1			#随机删除set中指定key的其中一个或多个元素
1) "you"

127.0.0.1:6379> smove test test2 "i love you"   #将test中的i love you移动到test2
(integer) 1
127.0.0.1:6379> smembers test
1) "i"
127.0.0.1:6379> smembers test2
1) "i love you"
2) "not"

应用场景:在社交网站中,经常会有“共同关注”功能

Redis Sdiff 命令返回第一个集合与其他集合之间的差异,也可以认为说第一个集合中独有的元素。不存在的集合 key 将视为空集。
差集的结果来自前面的 FIRST_KEY ,而不是后面的 OTHER_KEY1,也不是整个 FIRST_KEY OTHER_KEY1..OTHER_KEYN 的差集。

127.0.0.1:6379> sadd test1 1 2 3
(integer) 3
127.0.0.1:6379> sadd test2 3 4 5

127.0.0.1:6379> sdiff test1 test2 	#test1与其他set的差集
1) "1"
2) "2"



Redis Sinter 命令返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
127.0.0.1:6379> sadd test1 1 2 3
(integer) 3
127.0.0.1:6379> sadd test2 3 4 5

127.0.0.1:6379> sinter test1 test2		#test1和test2的交集
1) "3"


Redis Sunion 命令返回给定集合的并集。不存在的集合 key 被视为空集。
127.0.0.1:6379> sunion test1 test2 		#test1 test2的并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"

Hash

存储的值为Map集合,key-map,值map中又有key-value

127.0.0.1:6379> hset test name1 lucas	        #hset key field value 同时往key设置多个feild-value值
(integer) 1
127.0.0.1:6379> hget test name1			#hget key field
lucas
127.0.0.1:6379> hmget test name1 name2	        #hmget 同时获取key中多个field的值
1) "lucas"
2) "kavin"

127.0.0.1:6379> hgetall test			#hgetall 获取key中所有的field-value值
1) "name1"
2) "lucas"
3) "name2"
4) "kavin"
5) "name3"
6) "bren"

127.0.0.1:6379>  hdel test name1		#hdel删除key中指定field的值
(integer) 1
127.0.0.1:6379> hgetall test
1) "name2"
2) "kavin"
3) "name3"
4) "bren"

127.0.0.1:6379> hlen test			#hlen 获取hash key的长度
(integer) 2

127.0.0.1:6379> hexists test name1		#判断hash中指定key的指定field是否存在
(integer) 0								#不存在返回0.存在返回1
127.0.0.1:6379> hexists test name2
(integer) 1

#只获取key中所有的field
127.0.0.1:6379> hkeys test 		#hkeys key
1) "name2"
2) "name3"
#只获取key中所有的value
127.0.0.1:6379> hvals test		#hvals key
1) "kavin"
2) "bren"

#自增value hincrby key field num,自减则-num
127.0.0.1:6379> hset test num1 1
(integer) 1
127.0.0.1:6379> hincrby test num1 5
(integer) 6
127.0.0.1:6379> hincrby test num1 -4
(integer) 2

#set 指定field存在则不添加,不存在则添加
127.0.0.1:6379> hsetnx test num1 2
(integer) 0
127.0.0.1:6379> hsetnx test num2 2
(integer) 1


hash更适合对象的存储,如user name:xx age:11 adress:zhongshan

Zset

有序集合,在set的基础上,增加一个值排序

#ZADD key 浮点数(用来排序) value 浮点数2(用来排序) value2。。。添加一个或多个值
127.0.0.1:6379> zadd myzet 1 one 2 two 3 three
(integer) 3
127.0.0.1:6379> zrange myzet 0 -1
1) "one"
2) "two"
3) "three"

#Zrangebyscore根据score从小到大排序  min max为最小值和最大值的范围
127.0.0.1:6379> zrangebyscore myzet min max [WITHSCORES] [LIMIT offset count]   
#依据score的值从0-999的范围排序并显示score的值
127.0.0.1:6379> zrangebyscore myzet 0 999 withscores
 1) "one"
 2) "1"
 3) "two"
 4) "2"
 5) "three"
 6) "3"
 7) "six"
 8) "6"
 9) "eleven"
10) "12"

#zrevrange依据score从大到小排序
127.0.0.1:6379> zrevrange myzet 0 999 withscores
 1) "eleven"
 2) "12"
 3) "six"
 4) "6"
 5) "three"
 6) "3"
 7) "two"
 8) "2"
 9) "one"
10) "1"

#ZREM value value,。。。移除key中指定的value或多个value
127.0.0.1:6379> zrem myzet three  eleven
(integer) 2
127.0.0.1:6379> zrange myzet 0 -1
1) "one"
2) "two"
3) "six"
	
#获取有序集合中的个数
127.0.0.1:6379> zcard myzet
(integer) 3
#获取key中指定区间的成员个数
127.0.0.1:6379> zrange myzet 0 -1	
1) "one"
2) "two"
3) "six"
127.0.0.1:6379> zcount myzet 1 3		#1 2 6获取了1-3之间的个数
(integer) 2

有序SET集合应用场景:成绩表排序,工资表排序,播放量榜单

三种特殊数据类型

geospatial地理位置

在redis3.2版本已经推出。

########待学#######

hyperloglog基数统计

什么是基数

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

简介

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

一个网站的UV,如果一个人访问网站多次,但是还是算作一个人。

传统的方式,set保存用户的id,然后就可以统计set中元素数量作为标准判断。

这方法是为了计数,而不是保存userId,如果保存了大量的userId,则比较麻烦。

优点:占用的内存为固定的,2^64不同元素的基数,只需要12kb内存。

缺点:0.81%错误率,如果做统计UV任务,是可以忽略不记的。

127.0.0.1:6379> pfadd test1 a b c d		#创建一组元素
(integer) 1
127.0.0.1:6379> pfadd test2 c d e f		#创建一组元素
(integer) 1
127.0.0.1:6379> pfmerge test3 test1 test2	#合并test1 test2成为test3,并集
OK
127.0.0.1:6379> pfcount test3			#查看key的数量
(integer) 6

如果可以容错,则可以使用hyperloglog。

如果不允许,就是用set或自己定义的数据类型。

Bitmap

位存储

应用场景:活跃/不活跃、登录/未登录、打卡/未打卡、凡是两个状态的设计,都可以使用bitmaps。

bitmaps位图,数据结构。都是操作二进制来进行记录的,只有0和1两种状态。

127.0.0.1:6379> setbit sign 0 1			#setbit key offset value(value只有1和0)。
(integer) 0
127.0.0.1:6379> setbit sign 1 1
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 2			#value设置2则报错。
(error) ERR bit is not an integer or out of r

127.0.0.1:6379> getbit sign 1			#getbit key offset获取key中指定offset的value
(integer) 1
127.0.0.1:6379> getbit sign 2
(integer) 0

127.0.0.1:6379> setbit s1 1 1
(integer) 0
127.0.0.1:6379> setbit s1 2 1
(integer) 0
127.0.0.1:6379> setbit s1 3 0
(integer) 0

127.0.0.1:6379> bitcount s1			#统计key中所有value为1的个数
(integer) 2

笔记学习自Bilibili BV1S54y1R7SB
Up主:狂神说java

posted @ 2020-09-07 20:07  树樁  阅读(174)  评论(0)    收藏  举报