Redis(二)—— 五大基本数据类型和三大特殊数据类型

一、五大基本数据类型

1.1 String字符串类型

1、常用命令


#=================添加操作、删除操作、查询操作=============
cj:15>set key1 7/25  # 新增一个key-value
"OK"
cj:15>del key1  # 删除一个key-value
"1"
cj:15>set key2 Tuesday
"OK"
cj:15>get key2  # 获取value值
"Tuesday"

cj:15>append key2 ", OMG"  # 追加字符串,返回追加后的字符串长度
"12"               
cj:15>get key2
"Tuesday, OMG"

cj:15>append key3 "I'm a new key"  # 如果向一个不存在的key去追加,相当于set一个新的
"13"
cj:15>get key3
"I'm a new key"

cj:15>strlen key3  # 获取字符串长度
"13"
cj:15>set key4 Wednesday
"OK"
cj:15>expire key4 10  # 给key4设置过期时间,单位:秒
"1"
cj:15>ttl key4  # time to live ,还剩多少生命值,单位:秒
"3"
cj:15>ttl key4  # 当key过期时,ttl一直保持为-2
"-2"
cj:15>ttl key4   
"-2"
cj:15>type key4  # 查无此键
"none"
cj:15>type key3  # 返回value类型
"string"


cj:15>incr key3  # 自增操作必须用在int上
"ERR value is not an integer or out of range"
cj:15>set integerKey 5
"OK"
cj:15>incr integerKey  # 自增1
"6"
cj:15>incrby integerKey 3  # 自增规定步长
"9"
cj:15>decr integerKey   # 自减1
"8"
cj:15>decrby integerKey 2  # 自减规定步长
"6"


cj:15>set key4 "hello,morning!"
"OK"
cj:15>getrange key4 0 5  # 返回字符串[0,5]范围内的字符串
"hello,"
cj:15>getrange key4 0 -1  # 返回完整字符串,相当于get key4命令
"hello,morning!"

cj:15>setrange key4 0 good,  # 替换指定位置开始的字符串
"14"
cj:15>get key4
"good,,morning!"


cj:15>setex key5 30 "set with expire"  # setex=set with expire,新建键值对的同时设定过期时间
"OK"
cj:15>ttl key5
"27"

cj:15>setnx key5 "newKey5"  # setnx=set if not exits,新建键值对的时候会判断是否已经存在,如果存在则不会覆盖(多用于分布式锁/乐观锁)
"0"
cj:15>get key5   # 发现并没有被新的值覆盖
"set with expire"
cj:15>set key6 "original"   # 对比单纯的set命令
"OK"
cj:15>set key6 "new"
"OK"
cj:15>get key6  # 新的值覆盖旧的值
"new"
cj:15>

 批量操作:

cj:15>mset k1 v1 k2 v2 k3 v3  # 批量设置key-value
"OK"
cj:15>mget k1 k2 k3  # 批量获取
1) "v1" 
2) "v2"
3) "v3"
cj:15>msetnx k1 v2 k4 v4   #批量设置,是一个原子操作,和事务一样,要么都成功要么都失败。因为k1已经存在了,所以整个操作失败,即使k4不存在也不会set成功。
"0"    # 返回0,不成功

cj:15>getset k1 v1-1  # 先get再set,这样方便我们阅读
"v1"
cj:15>get k1
"v1-1"
cj:15>getset k5 v5   # 当get的值不存在时,返回null
null
cj:15>get k5
"v5"

redis可以定义对象 

方式(一):以JSON格式(其实就是key-value格式)保存一个对象

cj:15>set user:1 {name:dd,age:25}  # 1号用户
"OK"
cj:15>keys *
1) "k1"
2) "k2"
3) "user:1"
4) "k3"
5) "k5"

cj:15>get user:1
"{name:dd,age:25}"

方式(二): 把对象的两个属性定义成两个key

cj:15>get user:1
"{name:dd,age:25}"
cj:15>mset user:1:name dd user:1:age 4
"OK"
cj:15>mget user:1:name user:1:age
1) "dd"
2) "4"

# 此种方式实际上定义了两个key
cj:15>keys *
1) "user:1:age"
2) "user:1:name"

注意,如果采用第一种方式,那么无法单独取出字段哦~

cj:15>set user:1 {name:dd,age:25}
"OK"
cj:15>mget user:1:name user:1:age  # 此种方式不可获得如上定义的name和age字段
1) null   
2) null   
cj:15>keys *
1) "user:1"
cj:15>get user:1    # 只能通过全部get的方式
"{name:dd,age:25}"

2、使用场景

数字int类型的string作为计数器,比如统计文章的浏览量,用incr key命令实现浏览量+1。你想啊浏览量这个东西如果每次+1你都写一次磁盘太浪费资源了,所以就先写到缓存里,再定时刷进磁盘。

比如统计粉丝数量,用decr key实现粉试数量-1。可以进行如下定义“id为794329用户的粉丝量为2”

set user:794329 {fansNum:2}

1.2 List类型

  • list在redis里其实是一个链表,所以才有头插和尾插操作。当删掉了最后一个元素时,这个链表也就不存在了
  • 通过给list设置“先进先出”等规则,可以将list当做消息队列、堆、栈、阻塞队列使用。
  • 所有命令以“L”开头
  • list中的值是可以重复的,set不可以重复

1、常用命令

#####################增加操作、查看操作############################
cj:15>LPUSH mylist string1   #LPUSH是头插法(自己画图感受)
"1"
cj:15>LPUSH mylist string2
"2"
cj:15>LPUSH mylist string3
"3"
cj:15>LPUSH mylist string3    # string类型不能有重复的key,但是list可以有重复的值
"4"
cj:15>LRANGE mylist 0 -1    # 打印全部的list,注意无法用get去获取全部的list
1) "string3"
2) "string3"
3) "string2"
4) "string1"

cj:15>LRANGE mylist 1 2   # 从左到右打印[1,2]区间的list
1) "string3"
2) "string2"

######################删除操作#######################
cj:15>RPUSH mylist right  # 尾插法,插到最右边
"5"
cj:15>LPOP mylist   # 删除最左边的元素
"string3"
cj:15>RPOP mylist  # 删除最右边的元素

cj:15>LRANGE mylist 0 -1   # 先看一下有两个string3
1) "string3"
2) "string2"
3) "string1"
4) "string3"

cj:15>Lrem mylist 1 string3  # 指定下标删除元素“1”代表移除从左数1个string3
"1"
cj:15>LRANGE mylist 0 -1
1) "string2"
2) "string1"
3) "string3"

###################其他常见操作###############

cj:15>Lindex mylist 0  # 下标为0的元素
"string2"
cj:15>Lindex mylist 1
"string1"
cj:15>Lindex mylist 4   # 下标为4没有元素
null
cj:15>Llen mylist  # list长度
"3"


cj:15>Ltrim mylist 1 2   # 截取[1,2]部分,剩下的直接扔了
"OK"
cj:15>LRANGE mylist 0 -1
1) "string1"
2) "string3"

cj:15>rpoplpush mylist newlist  #弹出mylist最右边元素,放到newlist最左边。如果没有newlist那就自动创建
"string3"
cj:15>get newlist  # 不能用get哦
"WRONGTYPE Operation against a key holding the wrong kind of value"
cj:15>lrange newlist 0 -1
1) "string3"

cj:15>lpop newlist  # 删掉newlist所有元素
"string3"
cj:15>exists newlist  # 那么这个newlist也就不存在了(因为list底层是一个链表)
"0"
cj:15>exists mylist
"1"
###############指定下标更新操作################
cj:15>lset mylist 0 "heihei"   # 替换下标为0的元素
"OK"
cj:15>lrange mylist 0 -1
1) "heihei"
2) "string3"
3) "string2"
4) "string1"

cj:15>lset mylist 8 "OK?"   # 替换下标不存在的元素,报错
"ERR index out of range"

###################插入操作########################
cj:15>LINSERT mylist after "string3" "after3"    # after表示插入string3的后面(从左到右)
"5"
cj:15>LINSERT mylist before "string1" "before1"  # before表示插入string1的前面(从左到右)
"6"
cj:15>lrange mylist 0 -1
1) "heihei"
2) "string3"
3) "after3"
4) "string2"
5) "before1"
6) "string1"

2、使用场景

模拟消息队列。甚至可以用ltrim命令截取部分信息。

1.3 set类型

1、常用命令

######################添加操作################
cj:15>sadd myset 1   
"1"
cj:15>sadd myset 2
"1"
cj:15>sadd myset 4
"1"
cj:15>sadd myset 3
"1"
cj:15>sadd myset 8
"1"
cj:15>sadd myset 0110
"1"
####################查看操作####################
cj:15>smembers myset   # 并不是按照添加的顺序输出的,说明set的底层是用C++写的hashmap
1) "8"
2) "4"
3) "2"
4) "1"
5) "0110"
6) "3"
 
cj:15>scard myset      # set的元素个数
"6"
cj:15>SISMember myset 9   # 是否是set的元素,“1”表示是
"0"
cj:15>SISMember myset 8
"1"
#######################删除操作#################
cj:15>srem myset 3
"1"
cj:15>srandmember myset   # 随机抽取一个元素(抽奖)
"2"
cj:15>srandmember myset
"0110"
cj:15>srandmember myset
"1"
cj:15>spop myset  # 随机删除一个元素
"2"
cj:15>spop myset 3  # 随机删除3个元素
1) "4"
2) "1"
3) "0110"


cj:15>smove myset newset 8  # 把元素“8”从myset移动到newset中去,没有newset就新建一个
"1"
cj:15>smembers newset  
1) "8"

集合特有的一些操作:求并集,交集,差集

cj:15>sadd myset1 a
"1"
cj:15>sadd myset1 b
"1"
cj:15>sadd myset1 c
"1"
cj:15>sadd myset2 aa
"1"
cj:15>sadd myset2 bb
"1"
cj:15>sadd myset2 c
"1"
cj:15>smembers myset1
1) "b"
2) "c"
3) "a"

cj:15>smembers myset2
1) "bb"
2) "aa"
3) "c"

cj:15>SUNION myset1 myset2   # 求并集
1) "b"
2) "c"
3) "a"
4) "aa"
5) "bb"

cj:15>Sdiff myset1 myset2  # 求myset1相对于myset2的差集
1) "b"
2) "a"

cj:15>Sinter myset1 myset2  # 求交集
1) "c"

2、使用场景

  • 微博的共同关注
    • 关注的人是不重复且无序的,刚好用set去存储。然后求两个set的交集
  • 推荐好友
    • 求你的关注列表这个set和你关注的某个人他的关注列表这个set的交集

1.4 Hashmap哈希类型

  • 本质和string类型没有区别。也是key-value,只不过是一堆key-value存在一个hashmap里。直接理解成java里的new HashMap<String,Object>,同样key不能重复
  • 最佳应用:存储变更的数据,尤其是用户的信息
  • 对象存储用哈希!虽然string也可以存对象,但是不是最佳方法(太麻烦了!)

1、常用命令

##################增加、查看操作####################
cj:15>hset myhash k1 v1 k2 v2 k3 v3  #hset等同于hmset,可以同时存储多对key-value
"3"

cj:15>hget myhash k1
"v1"
cj:15>hmget myhash k1 k2 k3  # 批量查看
1) "v1"
2) "v2"
3) "v3"

cj:15>hgetall myhash  # 查看所有键值对
1) "k1"
2) "v1"
3) "k2"
4) "v2"
5) "k3"
6) "v3"

##################删除操作###############
cj:15>hdel myhash k2
"1"
cj:15>hgetall myhash
1) "k1"
2) "v1"
3) "k3"
4) "v3"


cj:15>hlen myhash  # 键值对个数
"2"
cj:15>hexists myhash k1  # 是否存在某个key
"1"
cj:15>hexists myhash k2
"0"

#############等同于java中hashmap的keyset()和values()方法#############
cj:15>hkeys myhash  # 所有key
1) "k1"
2) "k3"

cj:15>hvals myhash  # 所有value
1) "v1"
2) "v3"


##################测试自增自减############
cj:15>hset myhash k5 5
"1"
cj:15>hincrby myhash k5 1  # 自增特定步长
"6"
cj:15>hincrby myhash k5 -1 # 自减特定步长
"5"
cj:15>hdecrby myhash k5 1  # 没有hdecrby命令,自减的话用自增命令把值设为负数
"ERR unknown command `hdecrby`, with args beginning with: `myhash`, `k5`, `1`, "
cj:15>hdecr myhash k5     # 也没有自-1命令,只有特定步长命令
"ERR unknown command `hdecr`, with args beginning with: `myhash`, `k5`, "
cj:15>hincr myhash k5    # 也没有自+1命令,只有特定步长命令
"ERR unknown command `hincr`, with args beginning with: `myhash`, `k5`, "

###################修改操作#####
cj:15>hsetnx myhash k5 7  # hsetnx表示已经存在就不要添加了
"0"
cj:15>hset myhash k5 7  # 但是可以修改/覆盖
"0"
cj:15>hgetall myhash
1) "k1"
2) "v1"
3) "k3"
4) "v3"
5) "k5"
6) "7"   # 修改成功


###################存储java对象###################
cj:15>hset userMap name jj age 20 
"2"
cj:15>hgetall userMap
1) "name"
2) "jj"
3) "age"
4) "20"

2、使用场景

储变更的数据(java对象),尤其是用户的信息

1.5 Zset类型

  • 底层是linkedHashMap,把元素添加进去以后,哈希表给自动排好序了
  • 有序的set,可以通过score这个指标去排序。有一些set的命令不能直接拿来用哦,比如smembers不能直接变成zmembers去用
  • 要求我们向zset中添加元素时,带着score这个指标,用来作为排序的标准

1、常用命令

###################添加操作####################
cj:15>zadd salaryset 5000 qq 3000 dd 8000 mm 500 kk
"4"

####################(升序、降序)查看操作##################
cj:15>zrange salaryset 0 -1    # 自动按照工资的升序排序(kk最低,mm最高)
1) "kk"
2) "dd"
3) "qq"
4) "mm"


cj:15>zrevrange salaryset 0 -1  # 自动按照工资的降序排序
1) "mm"
2) "qq"
3) "dd"
4) "kk"



cj:15>zrevrangebyscore salaryset +inf -inf  #按照[正无穷,负无穷]区间降序排列,注意前面的参数一定要大于后面的参数
1) "mm"
2) "qq"
3) "dd"
4) "kk"

cj:15>zrevrangebyscore salaryset +inf -inf withscores  # 并输出对应的score
1) "mm"
2) "8000"
3) "qq"
4) "5000"
5) "dd"
6) "3000"
7) "kk"
8) "500"


cj:15>zrangebyscore salaryset -inf 7000 withscores  # 升序,只看7000以下的
1) "kk"
2) "500"
3) "dd"
4) "3000"
5) "qq"
6) "5000"

########################删除操作##################3
cj:15>zrem salaryset kk
"1"

######################统计元素个数操作####################
cj:15>zcard salaryset  # 统计所有元素个数
"3"
cj:15>zcount salaryset 300 600  # 统计score在[300,600]这个区间内所有元素个数。至于开区间和闭区间的设置自己去查哦!开区间可能参数要(300 600)这样写
"0"
cj:15>zcount salaryset 300 7000
"2"

2、使用场景

班级成绩表排序,消息权重排序(重要消息权重大)、工资表排序

二、3大特殊数据类型

2.1 Geospatial类型——周围的人

1、只有6个命令

# 语法: geoadd key的名称  经度  纬度  给坐标起个名字
#  注意一定要先经度再纬度,不然范围错了会报错  
cj:11>geoadd china:city 116.40 39.90 beijing
"1"
cj:11>geoadd china:city 121.47 31.23 shanghai
"1"

# 查看
cj:11>geopos china:city beijing shanghai
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"

2) 1) "121.47000163793563843"
   2) "31.22999903975783553"


# 计算两个城市间距离  单位:m米  km千米 mi英里  ft英尺
cj:11>geodist china:city beijing shanghai km
"1067.3788"

GEORAIUDS命令和GEORADIUSBYMEMBER命令的区别

  • 这两个命令都是以指定位置为中心,画个圆。
  • GEORADIUS的参数是指定经纬度,通常用于“寻找周围的人”。
  • GEORADIUSBYMEMBER的参数是位置集合里的某个成员
# 语法 GEORADIUS 要查找的集合的key值  经度  纬度  半径 半径的单位
cj:11>GEORADIUS china:city 110 30 500 km 
1) "chongqing"
2) "xian"

# withdist参数打印距离,withcoord 参数打印经纬度,count 1参数指定要查找几个。比如附近1000km的人有200个,但我们只想看离我们最近的100个
cj:11>GEORADIUS china:city 110 30 500 km withdist withcoord count 1
1) 1) "chongqing"
   2) "342.2210"
   3) 1) "106.49899989366531372"
      2) "29.52000010403299513"


# 语法  GEORADIUSBYMEMBER 要查找的集合的key值  集合里某个位置的名字  半径 半径的单位
cj:11>GEORADIUSBYMEMBER china:city beijing 1000 km withdist
1) 1) "beijing"
   2) "0.0000"

2) 1) "xian"
   2) "910.8533"

GEOHASH命令就是将位置转换成哈希值,基本上用不到这个命令。

2、使用场景

我的位置、周围的人、打车距离的计算

2.2 Hyperlog类型基数统计

2.3 BitMap位图类型

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值