NOSQL,Redis的常用数据类型

Redis的数据类型

Redis 是一种基于内存的数据库,并且提供一定的持久化功能,它是一种键值数据库,使用 key 作为索引找到当前缓存的数据,并且返回给程序调用者。

当前的 Redis 支持 5 种基础数据类型和 3 种特殊数据类型,它们分别是字符串(String)、哈希结构(hash)、列表(List)、集合(set)、有序集合(zset)和基数(HyperLogLog)、GEO(geospatial)、位图(bitmap)。

Redis 定义的这数据类型是十分有用的,它除了提供简单的存储功能,还能对存储的数据进行一些计算。

比如字符串可以支持浮点数的自增、自减、字符求子串,集合求交集、并集,有序集合进行排序等,所以使用它们有利于对一些不太大的数据集合进行快速计算,简化编程,同时它也比数据库要快得多,所以它们对系统性能的提升十分有意义。

  • STRING(字符串):可以是保存字符串、整数和浮点数 ,可以对字符串进行操作
    • 比如增加字符或者求子串:
    • 如果是整数或者浮点数,可以实现计算,比如自增等
  • LIST(列表):它是一个链表,它的每一个节点都包含一个字符串
    • Redis 支持从链表的两端插入或者弹出节点,或者通过偏移对它进行裁剪;
    • 还可以读取一个或者多个节点,根据条件删除或者查找节点等
  • SET(集合):它是一个收集器,但是是无序的,在它里而每一个元素都是一个字符串,而且是独一无二,各不相同的
    • 可以新增、读取、删除单个元素:检测一个元素是否在集合中;
    • 计算它和其他集合的交集、并集和差集等;
    • 随机从集合中读取元素
  • HASH(哈希散列表):它类似于 Java 语言中的 Map,是一个键值对应的无序列表
    • 可以増、删、査、改单个键值对,也可以获取所有的键值对
  • ZSET(有序集合):它是一个有序的集合,可以包含字符 串、整数、浮点数、分值(score),元素 的排序是依据分值的大小来决定的
    • 可以增、删、査、改元素,根据分值的范围或者成员 來获取对应的元索
  • geospatial(Geo):Redis 在 3.2 推出 Geo 类型,该功能可以推算出地理位置信息,两地之间的距离。
    • 规则:两极无法直接添加,一般会下载城市数据,直接通过 Java 程序一次性导入。
    • 有效的经度从 -180 度到 180 度。有效的纬度从 -85.05112878 度到 85.05112878 度。当坐标位置超出指定范围时,该命令将会返回一个错误。
  • HyperLogLog(基数):它的作用是计算重复的值,以确定存储的数量
    • 只提供基数的运算,不提供返回的功能
  • bitmap (位图):是通过最小的单位bit来进行0或者1的设置,表示某个元素对应的值或者状态。一个bit的值,或者是0,或者是1;也就是说一个bit能存储的最多信息是2。
    • bitmap 常用于统计用户信息比如活跃粉丝和不活跃粉丝、登录和未登录、是否打卡等。

String 数据结构和常用命令

字符串(String)是 Redis 最基本的数据结构,它将以一个键和一个值存储于 Redis 内部,它犹如 Java 的 Map 结构,让 Redis 通过键去找到值。Redis 字符串的数据结构如图 1 所示。

Redis字符串数据结构

​ 图 1 Redis 字符串数据结构

Redis 会通过 key 去找到对应的字符串,比如通过 key1 找到 value1,又如在 Java 互联网中,假设产品的编号为 0001,只要设置 key 为 product_0001,就可以通过 product_0001 去保存该产品到 Redis 中,也可以通过 product_0001 从 redis 中找到产品信息。

常用命令如下:

命 令 说 明 备 注
set key value 设置键值对 最常用的写入命令
get key 通过键获取值 最常用的读取命令
del key 通过 key,删除键值对 删除命令,返冋删除数,注意,它是个通用的命令,换句话说在其他数据结构中,也可以使用它
strlen key 求 key 指向字符串的长度 返回长度
getset key value 修改原来 key 的对应值,并将旧值返回 如果原来值为空,则返回为空,并设置新值
getrange key start end 获取子串 记字符串的长度为 len,把字符串看作一个数组,而 Redis 是以 0 开始计数的,所以 start 和 end 的取值范围 为 0 到 len-1
append key value 将新的字符串 value,加入到原来 key 指向的字符串末 返回 key 指向新字符串的长度

为了让大家更为明确,在 Redis 提供的客户端进行测试如图 2 所示。

Redis操作字符串重用命令

​ 图 2 Redis 操作字符串重用命令

这里我们看到了字符串的常用操作,为了在 Spring 中测试这些命令,首先配置 Spring 关于 Redis 字符串的运行环境,配置 Spring 关于 Redis 字符串的运行环境代码如下所示。

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxIdle" value="50" />
    <property name="maxTotal" value="100" />
    <property name="maxWaitMillis" value="20000" />
</bean>

<bean id="connectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="hostName" value="localhost" />
    <property name="port" value="6379" />
    <property name="poolConfig" ref="poolConfig" />
</bean>
<bean id="jdkSerializationRedisSerializer"
    class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
<bean id="stringRedisSerializer"
    class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="keySerializer" ref="stringRedisSerializer" />
    <property name="valueSerializer" ref="jdkSerializationRedisSerializer" />
</bean>

注意,这里给 Spring 的 RedisTemplate 的键值序列化器设置为了 String 类型,所以它就是一种字符串的操作。假设把这段 Spring 的配置代码保存为一个独立为文件 applicationContext.xml,使用 Spring 测试 Redis 字符串操作代码如下所示。

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;

import com.pojo.Role;

public class Test {
   
    public static void main(String[] args) {
   
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        RedisTemplate redisTemplate = applicationContext
                .getBean(RedisTemplate.class);
        // 设值
        redisTemplate.opsForValue().set("key1", "value1");
        redisTemplate.opsForValue().set("key2", "value2");
        // 通过key获取值
        String value1 = (String) redisTemplate.opsForValue().get("key1");
        System.out.println(value1);
        // 通过key删除值
        redisTemplate.delete("key1");
        // 求长度
        Long length = redisTemplate.opsForValue().size("key2");
        System.out.println(length);
        // 设值新值并返回旧值
        String oldValue2 = (String) redisTemplate.opsForValue().getAndSet(
                "key2", "new_value2");
        System.out.println(oldValue2);
        // 通过key获取值.
        String value2 = (String) redisTemplate.opsForValue().get("key2");
        System.out.println(value2);
        // 求子串
        String rangeValue2 = redisTemplate.opsForValue().get("key2", 0, 3);
        System.out.println(rangeValue2);
        // 追加字符串到末尾,返回新串长度
        int newLen = redisTemplate.opsForValue().append("key2", "_app");
        System.out.println(newLen);
        String appendValue2 = (String) redisTemplate.opsForValue().get("key2");
        System.out.println(appendValue2);
    }
}

这是主要的目的只是在 Spring 操作 Redis 键值对,其操作就等同于图 2 所示的命令一样。

在 Spring 中,redisTemplate.opsForValue() 所返回的对象可以操作简单的键值对,可以是字符串,也可以是对象,具体依据你所配置的序列化方案。

由于配置 Spring 关于 Redis 字符串的运行环境代码所配置的是字符串,所以以字符串来操作 Redis,其测试结果如下:

运行结果

​ 图 3 运行结果

结果和我们看到的命令行的结果一样的,作为开发者要熟悉这些方法。

上面介绍了字符串最常用的命令,但是 Redis 除了这些之外还提供了对整数和浮点型数字的功能。如果字符串是数字(整数或者浮点数),那么 Redis 还能支持简单的运算。不过它的运算能力比较弱,目前版本只能支持简单的加减法运算,如下 。

  • incr key :在原字段上加 1 ,只能对整数操作
  • incrby key increment : 在原字段上加上整数(increment) , 只能对整数操作
  • decr key :在原字段上减 1 ,只能对整数操作
  • decrby key decrement : 在原字段上减去整数(decrement), 只能对整数操作
  • incrbyfloat keyincrement : 在原字段上加上浮点数(increment), 可以操作浮点数或者整数

对操作浮点数和整数进行了测试,如图 4 所示。

操作浮点数和整数

​ 图 4 操作浮点数和整数

在测试过程中,如果开始把 val 设置为浮点数,那么 incr、decr、incrby、decrby 的命令都会失败。Redis 并不支持减法、乘法、除法操作,功能十分有限,这点需要我们注意。

由于 Redis 的功能比较弱,所以经常会在 Java 程序中读取它们,然后通过 Java 进行计算并设置它们的值。

注意,所有关于减法的方法,原有值都必须是整数,否则就会引发异常,

hash 数据结构和常用命令

Redis 中哈希(hash)结构就如同 Java 的 map 一样,一个对象里面有许多键值对,它是特别适合存储对象的,如果内存足够大,那么一个 Redis 的 hash 结构可以存储 2 的 32 次方减 1 个键值对(40 多亿)。

一般而言,不会使用到那么大的一个键值对,所以我们认为 Redis 可以存储很多的键值对。在 Redis 中,hash 是一个 String 类型的 field 和 value 的映射表,因此我们存储的数据实际在 Redis 内存中都是一个个字符串而已。

Redis hash 结构命令,如下。

命 令 说 明 备 注
hdel key field1[field2…] 删除 hash 结构中的某个(些)字段 可以进行多个字段的删除
hexists key field 判断 hash 结构中是否存在 field 字段 存在返回 1,否则返回 0
hgetall key 获取所有 hash 结构中的键值 返回键和值
hincrby key field increment 指定给 hash 结构中的某一字段加上一个整数 要求该字段也是整数字符串
hincrbyfloat key field increment 指定给 hash 结构中的某一字段加上一个浮点数 要求该字段是数字型字符串
hkeys key 返回 hash 中所有的键 ——
hlen key 返回 hash 中键值对的数量 ——
hmget key field1[field2…] 返回 hash 中指定的键的值,可以是多个 依次返回值
hmset key field1 value1 [field2 field2…] hash 结构设置多个键值对 ——
hset key filed value 在 hash 结构中设置键值对 单个设值
hsetnx key field value 当 hash 结构中不存在对应的键,才设置值 ——
hvals key 获取 hash 结构中所有的值 ——

可以看出,在 Redis 中的哈希结构和字符串有着比较明显的不同。

首先,命令都是以 h 开头,代表操作的是 hash 结构。其次,大多数命令多了一个层级 field,这是 hash 结构的一个内部键,也就是说 Redis 需要通过 key 索引到对应的 hash 结构,再通过 field 来确定使用 hash 结构的哪个键值对。

下面通过 Redis 的这些操作命令来展示如何使用它们,如图 2 所示。

Redis的hash结构命令展示

​ 图 2 Redis 的 hash 结构命令展示

从图 2 中可以看到,Redis 关于哈希结构的相关命令。这里需要注意的是:

哈希结构的大小,如果哈希结构是个很大的键值对,那么使用它要十分注意,尤其是关于 hkeys、hgetall、hvals 等返回所有哈希结构数据的命令,会造成大量数据的读取。这需要考虑性能和读取数据大小对 JVM 内存的影响。

对于数字的操作命令 hincrby 而言,要求存储的也是整数型的字符串,对于 hincrbyfloat 而言,则要求使用浮点数或者整数,否则命令会失败。

我们用 Spring 来完成图 2 的功能,代码如下所示。

public static void testRedisHash()  {
   
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    RedisTemplate redisTemplate =  applicationcontext.getBean(RedisTemplate.class);
    String key = "hash";
    Map<String, String> map = new HashMap<String,String>();
    map.put("f1", "val1");
    map.put("f2", "val2");
    // 相当于hmset命令
    redisTemplate.opsForHash(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值