Redis基本数据类型String详解

    科技2024-07-06  74

    4.3 String数据类型详解

    4.3.1 自增减及长度

    String命令拓展

    append 增加key的值,类似于Java中的String里面的拼接字符串

    strlen 查询当前key的长度,类似于Java中String里面的length方法

    ##增加一个Key 127.0.0.1:6379> set key1 v1 OK ##判断key 127.0.0.1:6379> exists key1 (integer) 1 ##获取key 127.0.0.1:6379> get key1 "v1" ##获取key的类型 127.0.0.1:6379> type key1 string ##拼接key的值,如果当前key不存在,就相当于set一个key 127.0.0.1:6379> append key1 append (integer) 8 ##获取key 127.0.0.1:6379> get key1 "v1append" ##查看key的长度 127.0.0.1:6379> strlen key1 (integer) 8

    接下来基于一个实际场景,来解释一个类似于 Java中的i++ 命令,incr命令!

    我们平常看到的微信文章浏览量,视频播放量 …只要每一个用户点击这篇文章或者进入这个视频,那么相对应的浏览量就会增加,这个数据是每时每刻都在变化的!能不能直接从数据库里面读取呢?,答案是不能的!这样对于整个系统来说,数据库层面的访问压力太大了!

    我们可以使用Redis作为缓存中间件,让这个浏览量…数据都是从redis里面读取,然后设置合适的时间在把这个数据进行持久化操作! 这样对于整个系统来说,每当用户访问时,首先从redis缓存中读取,或没有才去访问数据库层,系统的数据库层面的压力将会大大减小

    比如这边我设置一个key,来存放浏览量…,在使用redis的incr方法实现自增,每当一个用户访问时,后面我们就会学到Jedis,在Redis中使用的的命令方式,在Java中就调用相应的方法即可!

    ##新增一个key 127.0.0.1:6379> set num 1 OK ##设置这个key自增,类似于java中的i++ 127.0.0.1:6379> incr num (integer) 2 ##获取这个key的值 127.0.0.1:6379> get num "2" ##设置这个key自增,类似于java中的i++ 127.0.0.1:6379> incr num (integer) 3 ##获取这个key的值 127.0.0.1:6379> get num "3"

    浏览量如果减一呢?

    ##设置这个Key自减 127.0.0.1:6379> decr num (integer) 2 ##设置这个Key自减 127.0.0.1:6379> get num "2" ##设置这个Key自减 127.0.0.1:6379> decr num (integer) 1 ##设置这个Key自减 127.0.0.1:6379> get num "1"

    如果一下子想要增加10,或者更多呢?

    ##设置key增加到步长 127.0.0.1:6379> incrby num 10 (integer) 11 ##获取key 127.0.0.1:6379> get num "11" ##设置key减少的步长 127.0.0.1:6379> decrby num 10 (integer) 1 ##获取key 127.0.0.1:6379> get num "1"

    4.3.2 范围获取值

    Java中String工具包下有一个获取字符串的范围,range,思想都是相通的! Redis中也是有的!

    Redis中: getrange

    ##新增一个key 127.0.0.1:6379> set key1 "This a Value" OK ##获取一个key 127.0.0.1:6379> get key1 "This a Value" ##获取这个key [0,-1]范围的值 127.0.0.1:6379> getrange key1 0 -1 "This a Value" ##获取这个key [0,9]范围的值 127.0.0.1:6379> getrange key1 0 9 "This a Val" ##获取这个key [0,11]范围的值 127.0.0.1:6379> getrange key1 0 11 "This a Value" ##获取这个key [0,3]范围的值 127.0.0.1:6379> getrange key1 0 3 "This"

    Java中还有一个方法,可以替换某一个范围的值!Redis中有没有呢?也是有的

    Redis中: setrange

    ##清空 127.0.0.1:6379> clear ##获取get的值 127.0.0.1:6379> get key1 "This a Value" ##替换指定index的值 127.0.0.1:6379> setrange key1 6 xxx (integer) 12 ##获取key的值 127.0.0.1:6379> get key1 "This axxxlue"

    4.3.3 设置key的过期时间

    能不能再新增key的时候设置过期时间呢?

    之前是利用exprie来设置的!

    setex 设置过期时间

    setnx 设置过期时间,如果不存在怎么怎么样

    ##新增key1的时候设置过期时间为30秒 127.0.0.1:6379> setex key1 30 v1 OK ##查看key的过期时间 127.0.0.1:6379> ttl key1 (integer) 25 ##获取Key 127.0.0.1:6379> get key1 "v1" ##查看key的过期时间 127.0.0.1:6379> ttl key1 (integer) 16 ##设置key,如果这个key不存在,则新增成功, ##若存在则新增失败,并不会覆盖当前key的值 127.0.0.1:6379> setnx key2 v2 (integer) 1 ##获取Key 127.0.0.1:6379> get key2 "v2" ##设置key,如果这个key不存在,则新增成功, ##若存在则新增失败,并不会覆盖当前key的值 127.0.0.1:6379> setnx key2 v22 (integer) 0 ##查看key的过期时间,-2代表已经过期 127.0.0.1:6379> ttl key1 (integer) -2

    4.3.4 批量添加与获取

    那这样一个一个的设置Key有点麻烦,能不能批量设置呢?

    mset 批量设置key

    mget 批量获取key

    msetnx 批量设置key 这个key不存在则设置成功,如果存在则设置失败

    为一个原子性的操作

    ##批量设置Key 127.0.0.1:6379> mset k1 v1 k2 v1 OK ##批量获取key 127.0.0.1:6379> mget k1 k2 1) "v1" 2) "v1" ##查看当前数据库中的所有key 127.0.0.1:6379> keys * 1) "k2" 2) "k1" ##批量设置key 这个key不存在则设置成功,如果存在则设置失败 127.0.0.1:6379> msetnx k1 v1 k4 v4 (integer) 0 ##批量设置key 这个key不存在则设置成功,如果存在则设置失败 127.0.0.1:6379> msetnx k4 v1 k1 v1 (integer) 0 ##批量设置key 这个key不存在则设置成功,如果存在则设置失败 127.0.0.1:6379> msetnx k4 v1 (integer) 1

    4.3.5 基于实际场景使用

    考虑一下项目,如果我们要往redis中存一个对象,一般情况下,怎么存?

    通常做法:

    set user:1 {name: zhangsan,age: 3} 设置一个User对象的值为一个JSON字符串,来保存一个对象 127.0.0.1:6379> set user:1 "{name: zhangsan,age: 6}" OK 127.0.0.1:6379> get user:1 "{name: zhangsan,age: 6}" 127.0.0.1:6379>

    其实还有一种方法:

    这种写法就类似于YML中的层级关系

    ##这种写法 key是为一个特殊的key ##user:{id}:{field} ##user:{id} 就可以实现复用 127.0.0.1:6379> mset user:1:name zhnagsan user:1:age 6 OK 127.0.0.1:6379> mget user:1 1) "age:6" 127.0.0.1:6379> mget user:1:name user:1:age 1) "zhnagsan" 2) "6" 127.0.0.1:6379> keys * 1) "k2" 2) "user:1" 3) "k4" 4) "k1" 5) "user:1:name" 6) "user:1:age" 127.0.0.1:6379>

    举个例子

    我们一篇微信公众号的文章,不仅仅是有浏览量吧?还有再看,转发等等属性,这个微信文章是有一个固定的Id的,这些再看,点赞数,转发数,都是实时的更新的,那么我们可以把这些封装为一个对象,存放再redis中,如何设计呢?

    mset wenzhang:{id}:{field} mset wenzhang:10:dainzan 1 wenzhang:10:zaikan 1 wenzhang:10:zhuanfa 1 mget wenzhang:10:zaikan wenzhang:10:zaikan wenzhang:10:zhuanfa 127.0.0.1:6379> mset wenzhang:10:dainzan 1 wenzhang:10:zaikan 1 wenzhang:10:zhuanfa 1 OK 127.0.0.1:6379> keys * 1) "wenzhang:10:zhuanfa" 2) "wenzhang:10:zaikan" 3) "wenzhang:10:dainzan" 127.0.0.1:6379> mget wenzhang:10:zaikan wenzhang:10:zaikan wenzhang:10:zhuanfa 1) "1" 2) "1" 3) "1" 127.0.0.1:6379>

    4.3.6 getset方法介绍

    还有一个方法为getset

    先get,再set

    ##当前查询是没有的! 127.0.0.1:6379> keys * (empty array) ##如果这个key不存在,则返回null,接着再去新增这个key 127.0.0.1:6379> getset k1 v1 (nil) ##现在已经可以获取到这个key 127.0.0.1:6379> getset k1 v1 "v1" ##现在给这个key一个新的值,先get出现在的Key的值, ##再去set新的值给这个key 127.0.0.1:6379> getset k1 v2 "v1" ##现在获取到的已经是新的key 127.0.0.1:6379> getset k1 v2 "v2" 127.0.0.1:6379>

    4.3.7 使用场景

    String的使用场景:

    Value可以是字符串,也可以是数字

    可以在项目中当作

    计数器统计多单位的数量粉丝数对象缓存时间
    Processed: 0.021, SQL: 8