redis-2-string

/ Database / 没有评论 / 212浏览

字符串命令

以下指令仅对string类型的key有效

键指令作用例子返回值序号
SET设置指定 key 的值SET KEY_NAME VALUE在 Redis 2.6.12 以前版本, SET 命令总是返回 OK 。从 Redis 2.6.12 版本开始, SET 在设置操作成功完成时,才返回 OK0
GET获取指定 key 的值GET KEY_NAME返回 key 的值,如果 key 不存在时,返回 nil。 如果 key 不是字符串类型,那么返回一个错误1
GETRANGE返回 key 中字符串值的子字符GETRANGE KEY_NAME start end截取得到的子字符串2
GETSET将给定 key 的值设为 value ,并返回 key 的旧值(old value)GETSET KEY_NAME VALUE返回给定 key 的旧值。 当 key 没有旧值时,即 key 不存在时,返回 nil 。 当 key 存在但不是字符串类型时,返回一个错误3
GETBIT对 key 所储存的字符串值,获取指定偏移量上的位(bit)GETBIT KEY_NAME OFFSET字符串值指定偏移量上的位(bit)。 当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 04
MGET获取所有(一个或多个)给定 key 的值MGET KEY1 KEY2 .. KEYN一个包含所有给定 key 的值的列表5
SETBIT对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)Setbit KEY_NAME OFFSET指定偏移量原来储存的位6
SETEX将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)SETEX KEY_NAME TIMEOUT VALUE设置成功时返回 OK7
SETNX只有在 key 不存在时设置 key 的值SETNX KEY_NAME VALUE设置成功,返回 true 。 设置失败,返回 false8
SETRANGE用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始SETRANGE KEY_NAME OFFSET VALUE被修改后的字符串长度9
STRLEN返回 key 所储存的字符串值的长度STRLEN KEY_NAME字符串值的长度。 当 key 不存在时,返回 010
MSET同时设置一个或多个 key-value 对MSET key1 value1 key2 value2 .. keyN valueN总是返回 OK11
MSETNX同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在MSETNX key1 value1 key2 value2 .. keyN valueN当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(如果有一个 key 已经存在),那么返回 012
PSETEX这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位PSETEX key1 EXPIRY_IN_MILLISECONDS value1设置成功时返回 OK13
INCR将 key 中储存的数字值增一INCR KEY_NAME执行 INCR 命令之后 key 的值14
INCRBY将 key 所储存的值加上给定的增量值(increment)INCRBY KEY_NAME INCR_AMOUNT加上指定的增量值之后, key 的值15
INCRBYFLOAT将 key 所储存的值加上给定的浮点增量值(increment)INCRBYFLOAT KEY_NAME INCR_AMOUNT执行命令之后 key 的值16
DECR将 key 中储存的数字值减一DECR KEY_NAME执行命令之后 key 的值17
DECRBYkey 所储存的值减去给定的减量值(decrement)DECRBY KEY_NAME DECREMENT_AMOUNT减去指定减量值之后, key 的值18
APPEND如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾APPEND KEY_NAME NEW_VALUE追加指定值之后, key 中字符串的长度19
BITCOUNT用来获取 key 的值中二进制是 1 的个数BITCOUNT KEY_NAME [start] [end]key 的值中二进制是 1 的个数20
BITFIELD在一次调用中同时对多个位范围进行操作:它接受一系列待执行的操作作为参数,并返回一个数组,数组中的每个元素就是对应操作的执行结果BITFIELD KEY_NAME [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]命令的返回值是一个数组,数组中的每个元素对应一个被执行的子命令。需要注意的是,OVERFLOW 子命令本身并不产生任何回复21
BITPOS查找字符串中第一个设置为1或0的bit位BITPOS KEY_NAME bit [start] [end]

代码实践

SET

	// -1 永不过期
	//err := RedisClient.Set(ctx,"keyName","0000",-1).Err()
	err := RedisClient.Set(ctx,"keyName","0000",100*time.Second).Err() // 100秒有效期
	if err != nil{
		logrus.Error(err)
		return
	}

GET

	result, err := RedisClient.Get(ctx, "name101").Result()
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Info("结果为->",result)

如果get的key不是string类型,则报错如下

ERRO[0000] WRONGTYPE Operation against a key holding the wrong kind of value 

GETRANGE

	result, err := RedisClient.GetRange(ctx, "name101", 1, 2).Result() // value为hello,结果是 "el"
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Info(result)

GETSET

	result, err := RedisClient.GetSet(ctx, "name101", "value").Result()
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Info("原来的key为->", result) // 返回原来key的值

GETBIT

	result, err := RedisClient.GetBit(ctx, "SetBitKey", 123123).Result()
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Infof("Key: SetBitKey |offset: %d |value: %v",123123,result)
	result, err = RedisClient.GetBit(ctx, "SetBitKey", 12313).Result()
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Infof("Key: SetBitKey |offset: %d |value: %v",12313,result)

MGET

	keys :=  []string{"name267","name102","name795","name302"}
	result, err := RedisClient.MGet(ctx, keys...).Result()
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Info("value列表为->",result) // value的顺序和key的顺序保持一致

SETBIT

offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。对使用大的 offsetSETBIT 操作来说,内存分配可能造成 Redis 服务器被阻塞

	result, err := RedisClient.SetBit(ctx, "SetBitKey", 123123, 1).Result()
	err = RedisClient.SetBit(ctx, "SetBitKey", 12313, 0).Err()
	if err != nil {
		logrus.Error(err)
		return
	}
	logrus.Info(result)

使用场景

http://neosu.info/posts/redis-bitmap.html#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF

  1. 场景:统计每天有多少活跃用户,或者有多少用户连续几天活跃。

    使用日期作为key,用户id作为offset,如何活跃了就把bitmap二进制位设置成1。

    127.0.0.1:6379> setbit active_20220503 {userID} 1 // 使用日期作为key,用户id作为offset
    127.0.0.1:6379> bitcount active_20200509 // 某天的活跃用户
    
  2. 场景:用户在线状态

    场景:提供接口查询用户是否在线(有上线和下线)

    把用户id作为偏移量offset,在线就设置成1,不在线就设置成0。

    127.0.0.1:6379> setbit online {userID} 1	//设置用户上线
    127.0.0.1:6379> setbit online 9 0  		//设置用户ID为9下线
    127.0.0.1:6379> getbit online 9				// 查询用户ID为9在线状态
    127.0.0.1:6379> bitcount online 			// 查询当前所有在线用户数量
    
  3. 场景:记录每个用户的签到记录

    https://www.cnblogs.com/liang24/p/14449835.html

    考虑到每月要重置连续签到次数,最简单的方式是按用户每月存一条签到数据。Key的格式为 u:sign:{uid}:{yyyMM},而Value则采用长度为4个字节的(32位)的BitMap(最大月份只有31天)。BitMap的每一位代表一天的签到,1表示已签,0表示未签。

    例如 u:sign:1225:202101 表示ID=6667的用户在2021年1月的签到记录

    # 用户1月6号签到
    127.0.0.1:6379> setbit u:sign:6667:202101 5 1 # 偏移量是从0开始,所以要把6减1
    
    # 检查1月6号是否签到
    127.0.0.1:6379> getbit u:sign:6667:202101 5 # 偏移量是从0开始,所以要把6减1
    
    # 统计1月份的签到次数
    127.0.0.1:6379> bitcount u:sign:6667:202101
    
    # 获取1月份前31天的签到数据
    127.0.0.1:6379> BITFIELD u:sign:6667:202101 get u31 0
    
    # 获取1月份首次签到的日期
    127.0.0.1:6379> BITPOS u:sign:6667:202101 1 # 返回的首次签到的偏移量,加上1即为当月的某一天
    

SETEX

	res, err := RedisClient.SetEX(ctx, "setExKeyName", "setExKeyName-value", 100*time.Second).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Info(res) // ok

SETNX

	res, err := RedisClient.SetNX(ctx, "setExKeyName", "setExKeyName-value", 100*time.Second).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Info(res) // 设置成功则返回true,否则返回false

SETRANGE

	RedisClient.Set(ctx, "demo", "222267 yeah!", -1)

	res, err := RedisClient.SetRange(ctx, "demo", 8, "yep!").Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Info("修改后的字符串长度->", res) // 被修改后的字符串长度
	logrus.Info(RedisClient.Get(ctx, "demo"))

STRLEN

	res,err := RedisClient.StrLen(ctx,"deasdasmo").Result()
	if err != nil{
		logrus.Error(err)
	}
	logrus.Infof("字符串长度为->%d",res) // 返回字符串长度,如果key不存在,则结果为0

MSet

	res, err := RedisClient.MSet(ctx, "key1", "222", "key2", "333").Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%s", res) // 总是返回ok
	logrus.Info(RedisClient.MGet(ctx, "key1", "key2"))

MSETNX

	// 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在才能执行成功
	res,err := RedisClient.MSetNX(ctx,"key4","333","key5","333").Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res) // 当所有 key 都成功设置,返回 true 。 如果所有给定 key 都设置失败(如果有一个 key 已经存在),那么返回 false
	logrus.Info(RedisClient.MGet(ctx, "key1", "key2","key5"))

PSETEX

等同于 PExpire

	RedisClient.Set(ctx,"key1","sss",-1)
	res,err := RedisClient.PExpire(ctx,"key1",time.Millisecond*100000).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res)

INCR

	RedisClient.Set(ctx,"key1","66",-1)
	res,err := RedisClient.Incr(ctx,"key1").Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错

INCRBY

	RedisClient.Set(ctx,"key1","57",-1)
	res,err := RedisClient.IncrBy(ctx,"key1",10).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错

IncrByFloat

	RedisClient.Set(ctx,"key1","57",-1)
	res,err := RedisClient.IncrByFloat(ctx,"key1",10).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res) // value需要是一个浮点数类型,否则报错

DECR

	RedisClient.Set(ctx,"key1","68",-1)
	res,err := RedisClient.Decr(ctx,"key1").Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错

DECRBY

	RedisClient.Set(ctx,"key1","69",-1)
	res,err := RedisClient.DecrBy(ctx,"key1",2).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错

APPEND

	RedisClient.Set(ctx,"key1","69",-1)
	res,err := RedisClient.Append(ctx,"key1","23").Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("追加结果->%v", res) // 6923
	logrus.Info(RedisClient.Get(ctx,"key1"))

BITCOUNT

	RedisClient.SetBit(ctx,"SetBitKey",6,1)
	RedisClient.SetBit(ctx,"SetBitKey",7,1)
	count := redis.BitCount{Start: 0, End: -1}
	res,err := RedisClient.BitCount(ctx,"SetBitKey",&count).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("二进制是 1 的个数->%v", res) // 2

BITFIELD

todo

BITPOS

	RedisClient.SetBit(ctx, "SetBitKey", 6, 1)
	RedisClient.SetBit(ctx, "SetBitKey", 7, 1)
	logrus.Info(RedisClient.Get(ctx, "SetBitKey"))
	res, err := RedisClient.BitPos(ctx, "SetBitKey", 1).Result()
	if err != nil {
		logrus.Error(err)
	}
	logrus.Infof("查找字符串中第一个设置为1或0的bit位->%v", res) // 6
docker run -p 9090:9090 -v /Users/adou_mini/Downloads/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

xx

https://www.redis.com.cn/commands/bitfield.html