redis 详解-第二课

五大基本数据类型

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)

redis 执行方法

 1、exists name    	# key是否存在
 2、move name		# 移除key
 3、expire name 10	# key设置过期时间10s
 4、ttl name 		# 剩余过期时间
 5、type name 		# 查询key的类型

类型一:String(字符串)
string相关命令:

1、append key “hello”					# 追加字符串,如果当key不存在,相当于set key
2、strlen key 							# 获取key的长度
3、incr views 1							# 实现i++的操作,增涨量为1,比如微信浏览量
4、decr views 1							# 实现i--操作,减少量为1
5、getrange key 0 3						# 获取字符串范围:0-3,闭区间,如果获取全部的字符串是 0 -1
6、setrange key 1 tihuan				# 替换字符串,从1位置开始替换成tihuan
7、setex key 30 "hello"					# (set with expire) 设置过期时间30秒
8、setnx key "hello"					# 不存在再设置 (分布式锁中常用),如果存在设置失败
9、mset key1 value1 key2 value2			# 同时设置多个key和value
10、mget key1 key2						# 同时获取多个key
11、msetnx key1 value1 key2 value2		# 同时设置,不存在再设置,如果有一个存在就全部设置失败,原子操作
12、set user:1:{name:zhang,age:3} 		# 设置一个user:1 对象 值为json字符来保存一个对象
还可以设置为:
13、mset user:1:name zhangsan user:1:age 2  # 这里的key是一个巧妙的设计: user:{id}:{filed},如此设计在redis中是可以的,并且可以用 mget user:1:name user:1:age
14、getset db redis 					# 如果不存在值,则获取的值为null,然后再设置,之后用同样的命令即可获取相应的值,如果存在,获取原来的值,并设置新的值

类型二:list(集合)
list可以用作堆、栈、阻塞队列,所有的list命令是以l开头的
redis不区分大小写命令

########################################################################
1、往list中设置值和获取值 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 0 -1	# 获取list所有的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1 	# 获取list的一部分值
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"
########################################################################
2、移除命令 lpop rpop
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> 
########################################################################
3、通过下标获取list中的某一个值
lindex
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 1  		# 通过下标获取list的某一个值
"one"
127.0.0.1:6379> lindex list 0
"two"
########################################################################
4、获取list的长度
llen
127.0.0.1:6379> llen list 			# 获取list的长度
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
########################################################################
5、移除指定的值:
lrem
127.0.0.1:6379> lrange list 0 -1  	
1) "three"
2) "two"
3) "one"
4) "two"
127.0.0.1:6379> lrem list 1 one   # 移除指定的一个 one
(integer) 1
127.0.0.1:6379> lrange list 0 -1  
1) "three"
2) "two"
3) "two"
127.0.0.1:6379> lrem list 2 two		# 移除指定两个two
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "three"
127.0.0.1:6379> 

########################################################################
6、截取的操作 ltrim 修剪,list 截断!
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
127.0.0.1:6379> ltrim list 1 2   # 通过下标截取,从1到2截断
OK
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"

########################################################################
7、移除最后一个元素,并将它加到另一个list中
rpoplpush
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> rpoplpush list list2  # 将list中的最有一个值取出后加到list2中
"one"
127.0.0.1:6379> lrange list 0 -1
1) "two"
127.0.0.1:6379> lrange list2 0 -1
1) "one"

########################################################################
 8、lset 将列表中指定下标的值替换为另一个值,更新操作
 127.0.0.1:6379> exists list3		# 判断list是否存在
(integer) 0
127.0.0.1:6379> exists list
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "two"
127.0.0.1:6379> lset list 0 redis	 # 如果存在,替换为新的值
OK
127.0.0.1:6379> lrange list 0 -1
1) "redis"
127.0.0.1:6379> lset list 1 redis	  # 如果不存在,报错
(error) ERR index out of range
########################################################################
9、某个位置插入值
linsert
127.0.0.1:6379> lrange list 0 -1
1) "redis"
127.0.0.1:6379> lpush list learning
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "learning"
2) "redis"
127.0.0.1:6379> linsert list before redis good  # 在redis前插入一个 good字符串
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "learning"
2) "good"
3) "redis"
127.0.0.1:6379> linsert list after redis project # 在redis后插入一个project的字符串
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "learning"
2) "good"
3) "redis"
4) "project"
########################################################################

小结:

  • 实际上是一个链表,before node after,left,right 都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果删除了所有的值,空链表,也代表不存在
  • 在两边插入猴子改动值,效率最高,中间元素,相对来说效率比较低

类型三:set(集合)
set的redis命令是以s开头,不能重复

########################################################################
1、set集合中添加值,查询值
127.0.0.1:6379> sadd set one  	# set中添加值
(integer) 1
127.0.0.1:6379> sadd set two
(integer) 1
127.0.0.1:6379> sadd set three
(integer) 1
127.0.0.1:6379> sadd set three
(integer) 0
127.0.0.1:6379> smembers set	# 获取set中所有的值
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> sismember set one  # 查询set中是否有one,有返回1
(integer) 1
127.0.0.1:6379> sismember set four # 查询set中是否有one,有返回0
(integer) 0
127.0.0.1:6379> scard set			# 获取set中的元素个数
(integer) 3
########################################################################
2、移除某一个值
srem

127.0.0.1:6379> smembers set
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> srem set one 		# 从set总移除one这个元素
(integer) 1
127.0.0.1:6379> smembers set
1) "two"
2) "three"

########################################################################
3、随机抽选指定个数的元素
srandmember 

127.0.0.1:6379> smembers set
1) "one"
2) "two"
3) "four"
4) "three"
127.0.0.1:6379> srandmember set  	# 随机获取其中的一个值
"two"
127.0.0.1:6379> srandmember set
"four"
########################################################################
4、随机删除元素
spop

127.0.0.1:6379> smembers set
1) "one"
2) "two"
3) "four"
4) "three"
127.0.0.1:6379> spop set	# 随机删除指定集合中的元素
"one"
127.0.0.1:6379> spop set
"three"
127.0.0.1:6379> smembers set
1) "two"
2) "four"
########################################################################
5、移动指定的元素到另一个set集合中
127.0.0.1:6379> smembers set
1) "two"
2) "four"
127.0.0.1:6379> smove set set2 two		# 将two这个元素从set中移到set2中
(integer) 1
127.0.0.1:6379> smembers set
1) "four"
127.0.0.1:6379> smembers set2
1) "two"

########################################################################
6、数字集合列:
 - 差集 sdiff
 - 交集 sinter   通过关注
 - 并集 sunion
127.0.0.1:6379> smembers set1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> smembers set2
1) "d"
2) "c"
3) "e"
127.0.0.1:6379> sdiff set1 set2		# 差集
1) "b"
2) "a"
127.0.0.1:6379> sinter set1 set2	# 交集
1) "c"
127.0.0.1:6379> sunion set1 set2	# 并集
1) "a"
2) "c"
3) "b"
4) "d"
5) "e"
########################################################################

类型四:hash(哈希)
相当于map集合,key-map,本质和string区别不大
所有的命令是以h开头

########################################################################
1、给hash设置值,获取值
hset  hmset  hget  hmget  hgetall

127.0.0.1:6379> hset hash key1 one				# 给hash设置值key-value
(integer) 1
127.0.0.1:6379> hmset hash key2 two key3 three	# 给hash设置多个值
OK
127.0.0.1:6379> hget hash key1					# 获取hash单个值
"one"
127.0.0.1:6379> hgetall hash					# 获取hash所有值
1) "key1"
2) "one"
3) "key2"
4) "two"
5) "key3"
6) "three"
127.0.0.1:6379> hmget hash key1 key2 key3		# 获取hash多个值
1) "one"
2) "two"
3) "three"

########################################################################
2、删除
hdell

127.0.0.1:6379> hgetall hash
1) "key1"
2) "one"
3) "key2"
4) "two"
5) "key3"
6) "three"
127.0.0.1:6379> hdel hash key1		# 删除指定的key
(integer) 1
127.0.0.1:6379> hgetall hash
1) "key2"
2) "two"
3) "key3"
4) "three"
########################################################################
3、获取hash的长度
127.0.0.1:6379> hgetall hash  		
1) "key2"
2) "two"
3) "key3"
4) "three"
127.0.0.1:6379> hlen hash  #  获取hash长度
(integer) 2
########################################################################
4、判断hash中的key是否存在
127.0.0.1:6379> hgetall hash		# 获取所有hash的值
1) "key2"
2) "two"
3) "key3"
4) "three"
127.0.0.1:6379> HEXISTS hash key2	# hash中的key2是否存在,存在返回1
(integer) 1
127.0.0.1:6379> HEXISTS hash key1	# hash中的key1是否存在,不存在返回0
(integer) 0
#######################################################################
5、获取hash中所有的field
获取所有的value
127.0.0.1:6379> hkeys hash    # 获取所有的key
1) "key2"
2) "key3"
127.0.0.1:6379> hvals hash		# 获取所有的value
1) "two"
2) "three"
########################################################################
6、指定增量,指定减量 hset  hincrby  hdecr
不存在则设置,存在则设置失败 hsetnx
127.0.0.1:6379> hset hash key1 0
(integer) 1
127.0.0.1:6379> hincrby hash key1 2  # 对指定量加2
(integer) 2
127.0.0.1:6379> hincrby hash key1 -1 # 对指定量减1
(integer) 1
127.0.0.1:6379> hsetnx hash key4 four # 如果不存在key4则增加
(integer) 1
127.0.0.1:6379> hsetnx hash key4 five # 如果存在则增加失败
(integer) 0
########################################################################

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

类型五:Zset(有序集合)
在set的基础上,增加了一个值,set k1 v1 zset k1 score1 v1

########################################################################
1、添加值,获取值
127.0.0.1:6379> zadd myzset 1 one   # 添加一个值
(integer) 1
127.0.0.1:6379> zadd myzset 2 two 3 three  # 添加多个值
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1  # 获取所有的值
1) "one"
2) "two"
3) "three"
########################################################################
2、排序
 127.0.0.1:6379> zadd salary  50 name
(integer) 1
127.0.0.1:6379> zadd salary  20 name2
(integer) 1
127.0.0.1:6379> zadd salary  100 name3
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf   #  负无穷到正无穷排序
1) "name2"
2) "name"
3) "name3"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores  # 负无穷到正无穷按照scores排序
1) "name2"
2) "20"
3) "name"
4) "50"
5) "name3"
6) "100"
127.0.0.1:6379> zrangebyscore salary -inf 50 withscores # 负无穷到50排序
1) "name2"
2) "20"
3) "name"
4) "50"
127.0.0.1:6379> zrevrange salary 0 -1  # 从大到小排列
1) "name3"
2) "name2"

########################################################################
3、移除操作
127.0.0.1:6379> zrem salary name  # 移除key name
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "name2"
2) "name3"
########################################################################
4、获取集合中的个数 zcard
127.0.0.1:6379> zcard salary
(integer) 2
########################################################################
5、获取指定区间的成员变量
127.0.0.1:6379> zadd myset 1 hello 
(integer) 1
127.0.0.1:6379> zadd myset 2 world 3 zhang 
(integer) 2
127.0.0.1:6379> zcount myset 1 3    # 获取指定区间的成员变量
(integer) 3
127.0.0.1:6379> zcount myset 1 2	# 获取指定区间的成员变量
(integer) 2
127.0.0.1:6379> zcount myset 1 3	# 获取指定区间的成员变量
(integer) 3
########################################################################

三种特殊数据类型

类型六:geospatial(地理位置)
可以推算地理位置的信息,两地之间的距离,方圆几里的人。

相关命令
GEOADD
GEODIST
GEOHASH
GEOPOS
GEORADIUS
GEORADIUSBYMEMBER


########################################################################
1、
geoadd 添加地理位置
geopos 获取指定的城市的经度和纬度 获取当前定位:一定是一个坐标值
# 规则:两级无法直接添加,一般操作是下载城市数据,直接通过java程序一次性导入
# 有效的经度从-180 到180度
# 有效的纬度从-85.05112878度到84.05112878度。
# 当坐标位置超出上述指定的范围时,该命令将会返回一个错误。
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> geopos china:city beijing chongqin
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2) 1) "106.49999767541885376"
   2) "29.52999957900659211"
########################################################################
2、geodist
两人之间的距离!
单位:
 - m表示单位为米。
 - km表示单位为千米。
 - mi表示单位为英里。
 - ft表示单位为英尺。
127.0.0.1:6379> geodist china:city beijing shanghai   #  北京到上海的距离
"1067378.7564"
127.0.0.1:6379> geodist china:city beijing shanghai km
"1067.3788"
########################################################################
3、georadius 以给定的经纬度为中心,找出某一半径内的元素
附近的人,获取所有附近的人的地址,定位,通过半径来查询
获取指定参数数量的人
所有的数据应该都录入
127.0.0.1:6379> georadius china:city 110 30 1000 km    # 以110 30 为中心获取1000km内的城市
1) "chongqin"
2) "xian"
3) "shengzhen"
4) "hangzhou"
127.0.0.1:6379> georadius china:city 110 30 1000 km withdist # 以110 30 为中心获取1000km内的城市 并显示经度
1) 1) "chongqin"
   2) "341.9374"
2) 1) "xian"
   2) "483.8340"
3) 1) "shengzhen"
   2) "924.6408"
4) 1) "hangzhou"
   2) "977.5143"
127.0.0.1:6379> georadius china:city 110 30 1000 km withcoord # 以110 30 为中心获取1000km内的城市 并显示纬度
1) 1) "chongqin"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.96000176668167114"
      2) "34.25999964418929977"
3) 1) "shengzhen"
   2) 1) "114.04999762773513794"
      2) "22.5200000879503861"
4) 1) "hangzhou"
   2) 1) "120.1600000262260437"
      2) "30.2400003229490224"
127.0.0.1:6379> georadius china:city 110 30 1000 km withdist withcoord count 1 # 以110 30 为中心获取1000km内的城市 并显示经度 并且只查询1个
1) 1) "chongqin"
   2) "341.9374"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"
########################################################################
4、georadiusbymember 找出位于指定位置的城市
127.0.0.1:6379> georadiusbymember china:city beijing 1000 km
1) "beijing"
2) "xian"

########################################################################
5、geohash 命令-返回一个或者多个位置元素的geohash表示
该命令将返回11个字符串的geohash字符串
将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近!
127.0.0.1:6379> geohash china:city beijing chongqin
1) "wx4fbxxfke0"
2) "wm5xzrybty0"

########################################################################

geo底层的实现原理其实就是zset ,可以使用zset命令来操作geo

127.0.0.1:6379> zrange china:city 0 -1  # 查看地图中全部的元素
1) "chongqin"
2) "xian"
3) "shengzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"
127.0.0.1:6379> zrem china:city beijing # 移除地图中的某一个元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqin"
2) "xian"
3) "shengzhen"
4) "hangzhou"
5) "shanghai"

类型七:hyperloglog(基数统计)
基数:不重复的元素 如:
A{1,3,5,7,8,7}
B{1,3,5,7,8}
基数: = 5,可以接受误差
hyperloglog 用于基数统计的算法
优点:占用的内存是固定,2^64不同元素的基数,只需要12KB内存,如果要从内存角度来比较的话,hyperloglog是首选。
网页的UV(一个人访问一个网站多次,但是还是算作一个人)
传统的方式,set保存用户的id,然后就可以统计set中的元素数量作为标准判断
这个方式如果保存大量的用户id,就会比较麻烦,比较占内存。我们的目的是为了技术,而不是保存用户id;
0.81%错误率,可以被接受

127.0.0.1:6379> pfadd mykey a b c d e f g h i j   # 创建第一组元素
(integer) 1
127.0.0.1:6379> pfcount mykey						# 统计元素的基数数量
(integer) 10
127.0.0.1:6379> pfadd mykey2 i j z x c v b n m
(integer) 1
127.0.0.1:6379> pfcount mykey2
(integer) 9
127.0.0.1:6379> pfmerge mykey3 mykey mykey2  	# 将mykey 和mykey2合并到mykey3,是个并集
OK
127.0.0.1:6379> prcount mykey3					# 查询并集数量
(error) ERR unknown command `prcount`, with args beginning with: `mykey3`, 
127.0.0.1:6379> pfcount mykey3
(integer) 15

类型八:bitmap(位存储)
统计用户信息,活跃,不活跃!登录,未登录,打卡,两个状态的,都可以使用bitmaps!
bitmap 位图,数据结构!都是操作二进制位来进行记录,就只有0和1两个状态
365天= 365bit 1字节 = 8bit 46个字节左右

使用bitmap来记录周一到周日的打卡
周一:1 周二:0;周三:0.。。。

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
# 查看某一天 是否有打卡
127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 6
(integer) 0
# 统计操作,统计这周的打卡天数
127.0.0.1:6379> bitcount sign
(integer) 3

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值