Redis基础入门(MAC)

Redis入门

Redis有16个数据库,默认使用的是第0个

127.0.0.1:6379> select 3  #切换数据库
OK
127.0.0.1:6379[3]> dbsize  #查看db大小!
(integer) 0

Redis-Key

  • flushall 清除全部数据库
  • flushdb 清除当前数据库
  • keys * 查看所有的 key
  • set key
  • get key
  • exits key 判断当前 key 是否存在
  • move key 1 移动key 到数据库 1
  • expire key 10 设置过期时间,单位是秒
  • ttl key 查看key 的剩余时间
  • type key 查看 key 的类型

五大数据类型

String

append key abc   #给 key 追加一个字符串 当 key 不存在就set
strlen key #获取字符串长度

127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views  #自增 1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views #自减 1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379> INCRBY views 10 #设置步长 指定增量
(integer) 9
127.0.0.1:6379> INCRBY views 10
(integer) 19
127.0.0.1:6379> DECRBY views 5
(integer) 14
127.0.0.1:6379> 

#字符串范围
127.0.0.1:6379> KEYS *
1) "views"
2) "name"
127.0.0.1:6379> GETRANGE name 0 2  #截取字符串 [0,2]
"yet"
127.0.0.1:6379> GETRANGE name 0 -1 #获取全部字符串
"yetong"
127.0.0.1:6379> 

#替换
127.0.0.1:6379> SETRANGE name 1 ee #从指定位置开始字符替换
(integer) 6
127.0.0.1:6379> get name
"yeeong"
127.0.0.1:6379> 

#setex(set with expire) 设置过期时间

127.0.0.1:6379> setex name2 30 yetong
OK
127.0.0.1:6379> ttl name2
(integer) 23
127.0.0.1:6379> get name2
"yetong"
127.0.0.1:6379> 

#setnx(set if not exist)不存在=set ,存在的时候不执行任何操作(在分布式锁中常使用)
127.0.0.1:6379> setnx mykey yetong
(integer) 1
127.0.0.1:6379> KEYS *
1) "views"
2) "mykey"
3) "name"
127.0.0.1:6379> setnx mykey tomyee
(integer) 0
127.0.0.1:6379> get mykey
"yetong"
127.0.0.1:6379> 

#批量操作
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> KEYS *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4 #msetnx 是一个原子性操作 要么都成功要么都失败
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379> 

#对象
#key   巧用冒号  对象:{id}:{属性}   
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 3
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "3"
127.0.0.1:6379> 


#getset
#先 get 再 set
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mysql
"redis"
127.0.0.1:6379> get db
"mysql"
127.0.0.1:6379> 

List

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
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1
1) "three"
2) "two"
127.0.0.1:6379> LPUSH list four five
(integer) 5
127.0.0.1:6379> LRANGE list 0  -1
1) "five"
2) "four"
3) "three"
4) "two"
5) "one"
127.0.0.1:6379> RPUSH list zero  #从右边插入一个值
(integer) 6
127.0.0.1:6379> 
127.0.0.1:6379> LRANGE list 0 -1 #从左到右全部遍历
1) "five"
2) "four"
3) "three"
4) "two"
5) "one"
6) "zero"


#移除
127.0.0.1:6379> LRANGE list 0 -1
1) "five"
2) "four"
3) "three"
4) "two"
5) "one"
6) "zero"
127.0.0.1:6379> Lpop list  #移除左边第一个
"five"
127.0.0.1:6379> LRANGE list 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
5) "zero"
127.0.0.1:6379> RPOP list #移除右边第一个
"zero"
127.0.0.1:6379> LRANGE list 0 -1  
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> 


#通过下标获取值
127.0.0.1:6379> LRANGE list 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> LINDEX list 1
"three"

#获取数组长度
127.0.0.1:6379> Llen list  
(integer) 4


#移除指定的值,精确匹配
lrem list 1 one 移除 list 里面的一个 one
lrem list 2 three 移除 list 里面的两个 three

#ltrim 裁剪
ltrim list 1 2 #截取指定长度,list已经改变了,只剩下截取的长度了

rpoolpush
#移除列表最左边元素并添加到新的列表
rpoplpush mylist myotherlist


lset list 0 item #第 0 位存在就更新为 item

linsert list before world hello #在 list 数组的 world 里面添加 hello

Set(集合)

set 中的值不能重复,无序

127.0.0.1:6379> sadd myset hello  #添加元素
(integer) 1
127.0.0.1:6379> sadd myset world tomye 
(integer) 2
127.0.0.1:6379> SMEMBERS myset #查看所有元素
1) "tomye"
2) "world"
3) "hello"
127.0.0.1:6379> SISMEMBER myset hello #查看是否存在元素
(integer) 1
127.0.0.1:6379> SISMEMBER myset yetong
(integer) 0
127.0.0.1:6379> SCARD myset #获取集合元素个数
(integer) 3
127.0.0.1:6379> SREM myset hello #移除元素
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "tomye"
2) "world"
127.0.0.1:6379> SRANDMEMBER myset #随机抽元素
"world"
127.0.0.1:6379> SRANDMEMBER myset
"world"
127.0.0.1:6379> SRANDMEMBER myset
"world"
127.0.0.1:6379> SRANDMEMBER myset
"tomye"
127.0.0.1:6379> SRANDMEMBER myset
"tomye"
127.0.0.1:6379> SRANDMEMBER myset 2#随机抽两个元素
1) "tomye"
2) "world"
127.0.0.1:6379> SPOP myset #随机移除一个
"world"
127.0.0.1:6379> SPOP myset 2 #随机移除两个

smove myset myset2 hello #移动元素到另外一个集合

sdiff myset1 myset2 #差集
sinter myset1 myset2 #交集
sunion myset1 myset2 #并集

Hash(哈希)

本质上和 String 类型一样,Key-Value 只不过这边的 value 也变成了 Key-Value 的形式

Key - value(key-value)

127.0.0.1:6379> hset myhash field1 tong #set 一个具体的 key-value
(integer) 1
127.0.0.1:6379> hget myhash field1
"tong"
127.0.0.1:6379> hmset myhash field1 hello field2 world #set 多个 key-value
OK
127.0.0.1:6379> hmget myhash field1 field2 #获取多个value
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash #获取全部
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> HDEL myhash field1 #删除 field1
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field2"
2) "world"
127.0.0.1:6379> HLEN myhash #hash 长度
(integer) 1
127.0.0.1:6379> HEXISTS myhash field2 #判断某个字段是否存在
(integer) 1
127.0.0.1:6379> hkeys myhash #所有的 key
1) "field2"
2) "field1"
127.0.0.1:6379> HVALS myhash #所有的 value
1) "world"
2) "hello"
127.0.0.1:6379> hset myhash field3 5 
(integer) 1
127.0.0.1:6379> HINCRBY myhash field3 1 #指定增量
(integer) 6
127.0.0.1:6379> HINCRBY myhash field3 -1
(integer) 5
127.0.0.1:6379> hsetnx myhash field4 hell #不存在就设置
(integer) 1
127.0.0.1:6379> hsetnx myhash field4 hell #存在不设置
(integer) 0
127.0.0.1:6379> 


Zset(有序集合)

127.0.0.1:6379> ZADD myset 1 one  #添加一个值
(integer) 1
127.0.0.1:6379> ZADD myset 2 two 3 three #添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1 # 查看全部
1) "one" 
2) "two"
3) "three"
127.0.0.1:6379> ZADD salary 500 zhangsan
(integer) 1
127.0.0.1:6379> ZADD salary 1000 lisi 2000 wangwu
(integer) 2
127.0.0.1:6379> zrangebyScore salary -inf +inf #升序排序
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> zrangebyScore salary -inf +inf withscores #升序排序并显示值
1) "zhangsan"
2) "500"
3) "lisi"
4) "1000"
5) "wangwu"
6) "2000"
127.0.0.1:6379> zrangebyScore salary -inf 1000 withscores #小于等于 1000带值显示
1) "zhangsan"
2) "500"
3) "lisi"
4) "1000"
127.0.0.1:6379> ZREM salary lisi  #移除lisi
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "zhangsan"
2) "wangwu"
127.0.0.1:6379> ZRANGE salary 0 -1 withscores
1) "zhangsan"
2) "500"
3) "wangwu"
4) "2000"
127.0.0.1:6379> ZCARD salary #获取集合中的元素个数
(integer) 2
127.0.0.1:6379> ZCOUNT salary 1 2000 #获取【1,200】中的个数
(integer) 2


三种特殊数据类型

Geospatial地理位置

Redis 的 GEO 特性在 3.2 版本中推出, 这个功能可以将用户给定的地理位置信息储存起来。

通常用以实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。

geo 的数据类型为 zset。

GEO 的数据结构总共有六个常用命令:geoaddgeoposgeodistgeoradiusgeoradiusbymembergethash

geoadd

  • geoadd 命令以标准的x,y格式接受参数,所以用户必须先输入经度,然后再输入纬度。

    扫描二维码关注公众号,回复: 15977260 查看本文章
  • geoadd 能够记录的坐标是有限的:非常接近两极的区域无法被索引。

  • 有效的经度介于 -180 ~ 180 度之间,有效的纬度介于 -85.05112878 ~ 85.05112878 度之间。当输入超出范围的经度或者纬度,geoadd 将返回一个错误。

geopos

  • 从 key 里返回所有给定位置元素的位置(经度和纬度)

geodist

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

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

    • m 表示单位为米
    • km 表示单位为千米
    • mi 表示单位为英里
    • ft 表示单位为英尺
  • 如果用户没有显式地指定单位参数,那么 geodist 默认使用作为单位。

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

georadius

  • 以给定的经纬度为中心,找出某一半径内的元素。

georadiusbymember

  • 找出位于指定范围内的元素,中心点是由给定的位置元素决定

geohash

  • 将二维经纬度转换为一维字符串,字符串越长表示位置更精确,两个字符串越相似表示距离越近。

zrem

  • GEO 没有提供删除成员的命令,但是因为 GEO 的底层实现是 zset,所以可以借用 zrem 命令实现对地理位置信息的删除。

原文链接:https://www.kuangstudy.com/bbs/1526414199528763393

HyperLogLog基数统计

其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的,并且是很小的。

每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2 ^ 64 个不同元素的基数。

HyperLogLog 是一种算法,它提供了不精确的去重计数方案。

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8},基数(不重复元素)为 5。

基数估计就是在误差可接受的范围内,快速计算基数。

pfadd

添加

pfcount

统计获取基数

pfmerge

A,B合并成 C后统计基数

原文链接:https://www.kuangstudy.com/bbs/1529017995744391170

BitMap位图

当需要统计用户一年的某些信息,如活跃或不活跃,登录或不登录,打卡或没打卡。

如果使用普通的 key / value存储,则要记录 365 条记录,如果用户量很大,需要的空间也会很大。

Redis 提供了 Bitmap 位图这种数据结构,Bitmap 就是通过操作二进制位来进行记录,即为 0 和 1。

如果要记录 365 天的打卡情况,使用 Bitmap 表示的形式大概如下:0101000111000111……

这样 365 天相当于 365 bit,又 1 字节 = 8 bit , 所以相当于使用 46 个字节即可。

BitMap 就是通过一个 bit 位来表示某个元素对应的值或者状态,其中的 key 就是对应元素本身。

实际上底层也是通过对字符串的操作来实现的。

setbit

添加

getbit

单项取值

bitcount

统计 key 上,位为 1 的个数

原文链接:https://www.kuangstudy.com/bbs/1529023625540546562

事务

Redis 单条命令具有原子性,事务不保证原子性!

一次性顺序性排他性, 执行一系列命令

Redis事务:

  • 开启事务(multi)
  • 命令入队
  • 执行事务(exec)
  • 放弃事务(discard)

编译型异常(例如入队的时候就报语法错误),那么整个事务都会被回滚,都不执行

运行时异常(代码语法没有问题,比如(1/0)),那么其他语句会正常执行,错误语句抛出异常不执行

乐观锁

watch

事务开始之前先 watch 该 key(简单理解成事务开始前先获取 version),然后执行事务(比较 version,一致就成功)。

如果事务执行失败了,就 unwatch,重新watch最新的(version)。

Jedis

基本使用

  1. 导入 Jedis 依赖

  2. Jedis jedis = new Jedis(ip,端口)
    jedis.apiAPI 和上面 Redis 所有命令都保持一致!
    jedis.close()
    

事务

注意 try catch 包裹

猜你喜欢

转载自blog.csdn.net/Xiao_tongtong/article/details/131835056