Redis_01_redis五大基础类型和三大特殊类型

1.Redis

Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。

Redis 与其他 key - value 缓存产品有以下三个特点:

Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份。
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

2.redis安装
1.下载redis.tar.gz
2.make
3.make install PREFIX=/usr/local/redis
4.赋值配置文件 并且修改redi.config 将daemonize no 改成daemonize yes 使用redis.config后台启动redis.server
3. redis基础命令

redis有16个数据库默认使用第0个可以使用select 进行切换数据库

127.0.0.1:6379> select 3  #切换数据库
OK
127.0.0.1:6379[3]> dbsize #查看db大小
(integer) 0
127.0.0.1:6379[3]> set name  hdh #在三号数据库设置一个值
OK
127.0.0.1:6379[3]> dbsize #查看db大小
(integer) 1
127.0.0.1:6379[3]> set name  hdh #在三号数据库设置一个值
OK
127.0.0.1:6379[3]> flushdb #清除当前数据库
OK
127.0.0.1:6379[3]> flushall #清除所有数据库
OK

redis 是单线程的

Redis是非常快的,Redis是基于内存操作,CPU不是Redis的性能瓶颈,Redis的瓶颈是根据内存和网络带宽来决定的。

为什么Redis是单线程还是很快?

Redis是基于内存操作,Redis所有的数据都是存放在内存中的,多线程直接的切换都是每必要的耗时行为,对于内存来说单线程是最快的

4.Redis五大数据类型

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持[字符串、[哈希表]、[列表]、[集合]、[有序集合],[位图],[hyperloglogs]等数据类型。内置复制、[Lua脚本]、LRU收回、[事务]以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动[分区]。

1.redisKey的基本操作
127.0.0.1:6379[3]> set name hdh
OK
127.0.0.1:6379[3]> set age 18
OK
127.0.0.1:6379[3]> exists name  #判断一个key是否存在
(integer) 1
127.0.0.1:6379[3]> exists name1
(integer) 0
127.0.0.1:6379[3]> move name 1 #移除第一个key为name的
(integer) 1
127.0.0.1:6379> set name hdh
OK
127.0.0.1:6379> get name 
"hdh"
127.0.0.1:6379> expire name 10 #设置key的过期时间 单位秒
(integer) 1
127.0.0.1:6379> ttl name #查询Key剩余过期时间 -2已过期
(integer) 7
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> set name hdh
OK
127.0.0.1:6379> type name 判断key的类型
string
2.String类型

以下的所有的方法都会被转化为java操作的中的方法


127.0.0.1:6379> set key1 v1
OK
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> exists key1 #判断key是否存在
(integer) 1
127.0.0.1:6379> append key1 hello #向key追加一个值 key不存在创建
(integer) 7 #返回key的长度
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> strlen key1 #查询key的长度
(integer) 7
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views #value值自增1
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> decr views #value值减1
(integer) 0
127.0.0.1:6379> incrby views 10 #设置步长value值自增10
(integer) 10
127.0.0.1:6379> get views
"10"
127.0.0.1:6379> set key abcdefg
OK
127.0.0.1:6379> get key
"abcdefg"
127.0.0.1:6379> getrange key 0 3 #截取字符串 开始和结尾的下标
"abcd"
127.0.0.1:6379> getrange key 0 -1
"abcdefg"
127.0.0.1:6379> set key1 abcdefg
OK
127.0.0.1:6379> get key1
"abcdefg"
127.0.0.1:6379> setrange key1 1 x #替换下标为1的值
(integer) 7
127.0.0.1:6379> get key1
"axcdefg"
#setex (set with expire)#设置过期时间
#setnx (set if not exist) #不存在设置(在分布式锁中常常会用到)
127.0.0.1:6379> setex key3 30 abcd #设置key3的为abcd  30秒后过期
OK
127.0.0.1:6379> ttl key3  #查选key3 的过期时间 -1没有过期时间 -2 已经过期
(integer) 24
127.0.0.1:6379> get key3
"abcd"
127.0.0.1:6379> setnx mykey redis #判断mykey是不是存在 不存在创建返回 1  存在返回0 
(integer) 1
127.0.0.1:6379> get mykey  
"redis"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> setnx mykey java
(integer) 0
127.0.0.1:6379> mset k1 a k2 b k3 c
OK
127.0.0.1:6379> mget k1 k2 k3
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> msetnx k1 a k4 d #msetnx是原子操作 
(integer) 0 #失败
#redis 对象用作key json用来存值
#巧妙地设计 user:{id}:{filed}
127.0.0.1:6379> mset user:1:name zhansan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhansan"
2) "2"

127.0.0.1:6379> getset #先get再set 如果存在值先get 不存在返回nul 。

3.List类型

redis中 list可以实现栈、堆、队列

list可以左边进值右边出值,可以完成消息队列(lpush,rpop), 先进先出

栈操作:(lpush,lpop)先进后出

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 whree
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #获取list中的值(全部)
1) "whree"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1 #获取list中的值(下标为0和1的)
1) "whree"
2) "two"
127.0.0.1:6379> rpush list right #向尾部追加一个或者多个值
(integer) 4
127.0.0.1:6379> lrange list 0 -1  #获取list中的值(全部)
1) "whree"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> lrange list 0 -1
1) "whree"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> lpop list #移除头部的一个值
"whree"
127.0.0.1:6379> rpop list #移除尾部的一个值
"right"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one" 
127.0.0.1:6379> lindex list 0 #获取指定下标的值
"two"
127.0.0.1:6379> 
############################################################
llen
127.0.0.1:6379> llen list #返回列表的长度
(integer) 3
127.0.0.1:6379> lrem list 1 a  #移除list中指定个数的value  移除1个value是a的值
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "d"
2) "c"
3) "b"
127.0.0.1:6379> RPUSH list key1 key2 key3 key4 #向list尾部插入值
(integer) 4
127.0.0.1:6379> ltrim list 1 2 #截取list 从下标1到2
OK
127.0.0.1:6379> lrange list 0 -1
1) "key2"
2) "key3"
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> lset list 1 a #通过下标修改list中的值  修改list下标为1的值 如果不存在会报错
OK
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "a"
3) "3"
4) "4"
#linsert 将一个值插入到list中 一个值的后面
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "a"
3) "3"
4) "4"
127.0.0.1:6379> linsert list before 4 5 #向list值为4 的后面(前面)插入一个值为5数
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "a"
3) "3"
4) "5"
5) "4"
4.set
set中的值是不能重复的
127.0.0.1:6379> sadd name hdh #向set中存入一个或者多个元素
(integer) 1
127.0.0.1:6379> sadd name xj
(integer) 1
127.0.0.1:6379> sadd name dd
(integer) 1
127.0.0.1:6379> smembers name #查选set中所有的元素
1) "xj"
2) "dd"
3) "hdh"
127.0.0.1:6379> sismember name hdh #判断set中是否有某个元素
(integer) 1
127.0.0.1:6379> sadd set a 
(integer) 1
127.0.0.1:6379> sadd set b
(integer) 1
127.0.0.1:6379> sadd set c
(integer) 1
127.0.0.1:6379> scard set #查询set中元素个数
(integer) 3
127.0.0.1:6379> srem set a #移除set中一个指定的元素
(integer) 1
127.0.0.1:6379> smembers set 
1) "c"
2) "b"
127.0.0.1:6379> srandmember set #随机抽出一个元素
"c"
127.0.0.1:6379> srandmember set
"b"
127.0.0.1:6379> spop set  #随机删除一个元素
"c"
127.0.0.1:6379> spop set 
"b"
127.0.0.1:6379> sadd set a b c d e
(integer) 5
127.0.0.1:6379> smembers set
1) "d"
2) "c"
3) "a"
4) "b"
5) "e"
127.0.0.1:6379> smove set set1 f #将set集合中的f元素移动到set1集合中
(integer) 1
127.0.0.1:6379> smember set
1) "b"
2) "c"
3) "d"
4) "e"
127.0.0.1:6379> smembers set1
1) "a"
2) "f"
127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
127.0.0.1:6379> sdiff key1 key2 #差集
1) "a"
2) "b"
127.0.0.1:6379> sinter key1 key2 #交集
1) "c"
127.0.0.1:6379> sunion key1 key2 #并集
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
5.Hash(哈希)

Map集合,key-map–>key-!这时候vle就是一个Map1

hash变更数据:可以存放一个user

hset user:1 name hdh

hset user:1 age 24


127.0.0.1:6379> hset myhash filed hdh  #set一个key-value
(integer) 1
127.0.0.1:6379> hget myhash filed
"hdh"
127.0.0.1:6379> hmset myhash filed xj filed1 hello #set多个key-value
OK
127.0.0.1:6379> hmget myhash filed filed1  #get一个或者多个key-value
1) "xj"
2) "hello"
127.0.0.1:6379> hgetall myhash #get全部的key-value
1) "filed"
2) "xj"
3) "filed1"
4) "hello"
127.0.0.1:6379> hdel myhash filed  #删除指定的key
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "filed1"
2) "hello"
127.0.0.1:6379> hlen myhash #计算hash长度 有多少个key-map键值对 
(integer) 1
127.0.0.1:6379> 
127.0.0.1:6379> hexists myhash filed1 #判断hash中key是否存在
(integer) 1
127.0.0.1:6379> hexists myhash filed2
(integer) 0
127.0.0.1:6379> hkeys myhash #获取hash中的所有的key
1) "filed1"
127.0.0.1:6379> hvals myhash #获取hash中的所有的value
1) "hello"
127.0.0.1:6379> hset myhash age 10
(integer) 1
127.0.0.1:6379> hincrby myhash age 10 #hash自增10
(integer) 20
127.0.0.1:6379> hincrby myhash age -10 #hash自增-10
(integer) 10
127.0.0.1:6379> hsetnx myhash name hdh #如果不存在可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash name hdh#如果存在不可以设置
(integer) 0
6.Zset(有序集合)

在set的基础上,增加了一个值
set k1 v1
zset k1 score1 v1

127.0.0.1:6379> zadd myzset 1 one #向zset中添加一个值
(integer) 1
127.0.0.1:6379> zadd myzset 2 two 3 three #向zset中添加多个值
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1 #获取zet中所有的值
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zadd salary 1000 hdh 
(integer) 1
127.0.0.1:6379> zadd salary 2000 xj
(integer) 1
127.0.0.1:6379> zadd salary 3000 zs
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf #按照salary正序排序-inf +inf 所有的
1) "hdh"
2) "xj"
3) "zs"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores #按照salary升序排序带上value
1) "hdh"
2) "1000"
3) "xj"
4) "2000"
5) "zs"
6) "3000"
127.0.0.1:6379> zrange salary 0 -1 withscores #从大到小排序
1) "xj"
2) "2000"
3) "zs"
4) "3000"
127.0.0.1:6379> 
127.0.0.1:6379> zrange salary 0 -1
1) "hdh"
2) "xj"
3) "zs"
127.0.0.1:6379> zrem salary hdh #移除一个元素
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "xj"
2) "zs"
127.0.0.1:6379> zcard salary #集合中元素的个数
(integer) 2
127.0.0.1:6379> zadd myzset 1 a 2 b 3 c 
(integer) 3
127.0.0.1:6379> zcount myzset 1 3 #获取zset指定区间之间的元素数量
(integer) 3
127.0.0.1:6379>  zcard myzset #获取zset的元素数量
(integer) 3
5.三种特殊的数据类型
1.geospatial

朋友圈定位,附近的人,打车的距离

GEOADD:

该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。这些坐标的限制是可以被编入索引的,区域面积可以很接近极点但是不能索引。具体的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:

有效的经度从-180度到180度。

有效的纬度从-85.05112878度到85.05112878度。

当坐标位置超出上述指定范围时,该命令将会返回一个错误

(error) ERR invalid longitude,latitude pair 39.900000,116.400000#及维度超出范围

127.0.0.1:6379> geoadd china:city 116.40 39.90 beijin #添加一个或者多个地理位置
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqin 114.05 22.52 shengzhen
(integer) 2
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 beijin #获取指定的城市的经纬度
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2.geodist

返回两个给定位置之间的距离。

如果两个位置之间的其中一个不存在, 那么命令返回空值。

指定单位的参数 unit 必须是以下单位的其中一个:

m 表示单位为米。

km 表示单位为千米。

mi 表示单位为英里。

ft 表示单位为英尺。

如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。

GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。

127.0.0.1:6379> geodist china:city beijin shanghai km #北京到上海的距离
"1067.3788"
 ``

我附近的人?(获得我附近所有人的地址,定位)
```linux
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 100 30 1000 km withdist withcoord count 1
##查找指定坐标 110 30 附近1000km的人并且显示 withcoord详细坐标 count取一个
1) 1) "chongqin"
   2) "629.6756" 
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"

通过指定的元素查找附近的人

127.0.0.1:6379> georadiusbymember china:city beijin 1000 km withdist withcoord
#找出指定元素(beijin)1000km之内的所有元素的详情
1) 1) "beijin"
   2) "0.0000"
   3) 1) "116.39999896287918091"
      2) "39.90000009167092543"
2) 1) "xian"
   2) "910.0565"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"

geohash 返回一个或者多个位置元素的经纬度 GeoHash表示

#将二维码的经纬度转换为一维的字符串,如果两个字符串越接近,那么距离越接近
127.0.0.1:6379> geohash china:city beijin chongqin
1) "wx4fbxxfke0"
2) "wm5xzrybty0

geo底层的实现原理是Zste!意味着我们可以使用Zset命令操作

127.0.0.1:6379> zrange china:city  0 -1 #查看地图中所有的元素
1) "chongqin"
2) "xian"
3) "shengzhen"
4) "hangzhou"
5) "shanghai"
6) "beijin"
127.0.0.1:6379> zrem china:city beijin #移除地图中指定的元素
(integer) 1
2.Hyperloglog 数据结构

什么是基数?

一个集合中不存在重复的元素,Hyperloglog存储的就是基数

网页的的访问数量(多次访问只算一次)
Hyperloglog 存放:2^64次方个不同的用户id,只需要12kb内存,但是存在0.81%的误差

传统方式 set方式保存用户id。数量级过大时非常消耗资源。而且我们需要的不是用户id,需要的事访问数量。

127.0.0.1:6379> pfadd key1 1 2 3 4 #创建一组数据结构 
(integer) 1
127.0.0.1:6379> pfadd key2 3 4 5 6 #创建一组数据结构 
(integer) 1
127.0.0.1:6379> pfmerge key3 key 1 key2 #合并两个数据结构
OK
127.0.0.1:6379> pfcount key3 #查询一组组数据结构的个数
(integer) 6
3.Bitmaps

位存储

统计活跃和不活跃用户,登录,不登陆的用户。只有2种状态的都可以使用Bitmap表示。

127.0.0.1:6379> setbit id+y+y  1 0 #设置 用户id+y+y  用户 哪一年 哪一月 哪一天是否登录
(integer) 0
127.0.0.1:6379> setbit id+y+y 2 0
(integer) 0
127.0.0.1:6379> getbit id+y+y 1 #获得 用户id+y+y  用户 哪一年 哪一月 哪一天是否登录
(integer) 0
127.0.0.1:6379> bitcount id+y+y 获得 用户id+y+y  当月的打卡次数
(integer) 2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值