Redis基础教程

news2024/11/23 17:46:28

Redis基础教程

Redis介绍

官方网站:https://redis.io/
Redis是一种键值型的NoSql数据库,这里有两个关键字:

  • 键值型:Redis中存储的数据都是以key、value对的形式存储
  • NoSql:相对于传统关系型数据库而言,有很大差异的一种数据库。(not only sql,非关系型数据库)

NoSql则对数据库格式没有严格约束,往往形式松散,自由。
对比传统数据库:
kZP40dQ.png
关系型数据库(RDBMS)和非关系型数据库(NoSQL数据库)是两种不同类型的数据库管理系统,它们在数据存储、数据模型和适用场景等方面存在显著的区别。

  1. 数据模型:
    • 关系型数据库:使用表格(表)来组织数据,数据之间的关系通过外键建立。数据存储在结构化表格中,每行代表一个记录,每列代表一个属性。
    • 非关系型数据库:使用不同的数据模型,如文档、键值对、列族、图形等。这些数据库通常更自由灵活,不需要固定的模式,允许存储不同结构的数据。
  2. 查询语言:
    • 关系型数据库:通常使用SQL(Structured Query Language)来查询和操作数据,支持复杂的查询和事务。
    • 非关系型数据库:使用不同的查询语言或API,通常是根据数据库类型而变化的。有些NoSQL数据库支持查询,但通常不如SQL数据库灵活。
  3. 扩展性:
    • 关系型数据库:通常采用垂直扩展(增加服务器性能)或水平分区来提高性能,但有一定限制。
    • 非关系型数据库:通常更容易水平扩展,可以更好地处理大规模数据。
  4. 一致性:
    • 关系型数据库:强调ACID(原子性、一致性、隔离性和持久性)事务特性,确保数据的一致性和完整性。
    • 非关系型数据库:一些NoSQL数据库可能牺牲ACID属性以获得更高的性能和可用性,而强调CAP(一致性、可用性和分区容忍性)理论。
  5. 适用场景:
    • 关系型数据库:适用于需要强一致性和复杂事务处理的应用,如金融系统、ERP系统等。
    • 非关系型数据库:适用于需要高度可扩展性和灵活性的应用,如大数据、社交媒体、物联网、日志存储等。

Macos安装Redis

https://redis.io/docs/getting-started/installation/install-redis-on-mac-os/
安装redis

brew install redis

查看安装信息:

brew info redis

前台启动redis:

redis-server

后台启动redis:

brew services start redis

查看信息:

brew services info redis

停止:

brew services stop redis

配置

打开/opt/homebrew/etc/redis.conf配置文件
修改密码

requirepass 123456

前台启动的时候可以加 配置文件

cd /opt/homebrew/etc/
redis-server redis.conf

在后台启动redis,这个时候不需要加配置文件

brew services start redis

登录redis

redis-cli -h localhost -p 6379 -a 123456

启动问题

后台启动的时候报错:
image.png
解决办法:

cd /opt/homebrew/Library/Taps/homebrew
rm -rf homebrew-services
brew tap homebrew/services

客户端工具

可以选择 another redis desktop
https://goanother.com/cn/#download

Redis中的数据结构

Redis是键值对结构,即key-value,我们需要保证key不冲突,
常见的方式为:

	项目名:业务名:类型:id

例如:

  • user相关的key:heima:user:1
  • product相关的key:heima:product:1
    如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:

字符串

String类型,也就是字符串类型,是Redis中最简单的存储类型。
String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便

KEYVALUE
heima:user:1{“id”:1, “name”: “Jack”, “age”: 21}
heima:product:1{“id”:1, “name”: “小米11”, “price”: 4999}
常用命令

SET key value :设置
GET key :获取
SETEX key seconds value :设置指定key过期时间,单位s
SETNX key vvalue :只有在key不存在时才设置
x2zDBjf.png

哈希

Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:

常用命令

HSET key fiele value 将key设置为value
HGET key field 获取
HDEL key field 删除
HKEYS key 获取所有字段
HVALS key 获取所有值
VF2EPt0.png

列表

Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

常用命令

LPUSH key value1[value2] 插入到头部 左侧
LRANGE key start stop 获取指定范围达到元素
RPOP key 移除并获取列表最后一个元素 右侧
LLEN key 获取列表长度

集合

Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的

常用命令

SADD key number1 [number2] 插入一个成员
SMEMBERS key 返回集合中所有成员
SCARD key 获取成员数
SINTER key1[key2] 返回定义所哟集合的交集
SUNION key1 [key2] 返回所有集合的并集
SREM key number1[numer2] 删除集合中成员

有序集合

Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。

因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。

常用命令

ZADD key score1 member1 [score2 member2] 向有序集合添加一个成员
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合指定区间内的成员
ZINCRBY key increment member 对指定成员分数加上增量increment
ZREM key member [member..] 删除成员

通用命令

KEYS pattern: 查找所有符合给定模式的key
EXISTS key: 检查给定key是否存在
TYPE key: 返回key 所存储的值的类型
DEL key :在key存在时删除key
EXPIRE:给一个key设置有效期,到期会被自动删除

Redis的Java客户端Jedis

入门

引入依赖:

<!--jedis-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.0</version>
</dependency>
<!--单元测试-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
</dependency>

建立连接,存数据,以及取数据,最后释放连接测试:

public class TestJedis {

    private Jedis jedis;

    @BeforeEach
    void setup() {
        // 1.建立连接
        jedis = new Jedis("localhost", 6379);
        // 2.设置密码
        jedis.auth("123456");
        // 3.选择库
        jedis.select(0);
    }

    @Test
    void testString() {
        // 存入数据
        String result = jedis.set("name", "cxk");
        System.out.println("result=" + result);
        // 获取数据
        String name = jedis.get("name");
        System.out.println("name=" + name);
    }

    @Test
    void testHash() {
        jedis.hset("user:1", "name", "cxk");
        jedis.hset("user:1", "age", "18");

        Map<String, String> map = jedis.hgetAll("user:1");
        System.out.println(map);

    }

    @AfterEach
    void tearDown() {
        // 关闭连接
        jedis.close();
    }
}

连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐使用Jedis连接池代替Jedis的直连方式。
创建factory

public class JedisConnectionFactory {

    private static JedisPool jedisPool;

    static {
        // 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);
        poolConfig.setMaxIdle(8);
        poolConfig.setMinIdle(0);
        poolConfig.setMaxWaitMillis(1000);
        jedisPool = new JedisPool(poolConfig, "localhost",
                6379, 1000, "123321");
    }

    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

创建对象:

    @BeforeEach
    void setup() {
        // 1.建立连接
//        jedis = new Jedis("localhost", 6379);
        jedis= JedisConnectionFactory.getJedis();
        // 2.设置密码
        jedis.auth("123456");
        // 3.选择库
        jedis.select(0);
    }

SpringBoot中使用Redis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

入门

导入依赖
pool是连接池

        <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--common-pool-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--Jackson依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

配置Redis
配置redis,以及连接池设置

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
    lettuce: # 连接池
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 1000ms

编写配置类
RedisTemplate可以接收任意Object作为值写入Redis,写入前会把Object序列化为字节形式,默认是采用JDK序列化,
缺点:

  • 可读性差
  • 内存占用较大
    可以自定义序列化方式

自定义序列化方式

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //创建RedisTemplate<String, Object>对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置RedisTemplate的连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        //创建json格式序列化对象
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置key和hashKey的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        template.setValueSerializer(genericJackson2JsonRedisSerializer);
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        return template;
    }
}

测试:

@SpringBootTest
class RedisDemoApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void testString() {
        // 写入一条String数据
        redisTemplate.opsForValue().set("name", "蔡徐坤");
        // 获取string数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
}

测试写入一个Pojo类

    @Test
    void testPojo(){
        User user = new User("蔡徐坤", 18);
        redisTemplate.opsForValue().set("user", user);
        Object user1 = redisTemplate.opsForValue().get("user");
        System.out.println("user1 = " + user1);
    }

结果如下:
image.png

整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。

使用StringRedisTemplate

为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //json格式化工具
    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    void testSaveUser() throws Exception{
        User user = new User("蔡徐坤", 18);
        //手动序列化
        String userJson = mapper.writeValueAsString(user);
        stringRedisTemplate.opsForValue().set("user:1",userJson);
        String jsonUser = stringRedisTemplate.opsForValue().get("user:1");
        //手动反序列化
        User user1 = mapper.readValue(jsonUser, User.class);
        System.out.println("user1 = " + user1);
    }

其他的类型一些测试:

@SpringBootTest
class RedisConfigurationTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testString() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("name", "cxk");
        String name = (String) valueOperations.get("name");
        System.out.println(name);
        valueOperations.set("code", "1234", 3, TimeUnit.HOURS); //3小时后过期
        valueOperations.setIfAbsent("code1", "1234"); //如果不存在则设置
    }

    @Test
    public void testHash() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put("user", "name", "cxk");
        hashOperations.put("user", "age", "18");
        String name = (String) hashOperations.get("user", "name");
        System.out.println(name);

        Set user = hashOperations.keys("user");
        System.out.println(user);

        List user1 = hashOperations.values("user");
        System.out.println(user1);

        hashOperations.delete("user", "name");
    }

    @Test
    public void testList() {
        ListOperations listOperations = redisTemplate.opsForList();
        listOperations.leftPushAll("list", "a", "b", "c");
        listOperations.leftPush("list", "d");

        List list = listOperations.range("list", 0, -1);
        System.out.println(list);

        listOperations.rightPop("list");

        Long size = listOperations.size("list");
        System.out.println(size);
    }

    @Test
    public void testSet() {
        SetOperations setOperations = redisTemplate.opsForSet();
        setOperations.add("set", "a", "b", "c", "d", "e");
        Set set = setOperations.members("set");
        System.out.println(set);

        setOperations.remove("set", "a", "b");
        set = setOperations.members("set");
        System.out.println(set);


        setOperations.add("set2", "a", "b", "c", "d", "e");
        Set union = setOperations.union("set", "set2");
        Set intersect = setOperations.intersect("set", "set2");
        Set difference = setOperations.difference("set", "set2");
        System.out.println(union);
        System.out.println(intersect);
        System.out.println(difference);
    }
    
    @Test
    public void testZset(){
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("zset", "a", 1);
        zSetOperations.add("zset", "b", 2);
        zSetOperations.add("zset", "c", 3);

        Set zset = zSetOperations.range("zset", 0, -1);
        System.out.println(zset);
        
        zSetOperations.incrementScore("zset", "a", 1);
        zSetOperations.remove("zset", "a");
    }
    @Test
    public void testCommon(){
        Set keys = redisTemplate.keys("*");
        System.out.println(keys);

        Boolean name = redisTemplate.hasKey("name");

        for (Object key : keys) {
            DataType type = redisTemplate.type(key);
            System.out.println(type.name());
        }
        redisTemplate.delete("name");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1163272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关键词搜索亚马逊商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

亚马逊提供了API接口来获取商品数据。其中&#xff0c;关键词搜索亚马逊商品接口&#xff08;item_search-按关键字搜索亚马逊商品接口&#xff09;可以用于获取按关键字搜索到的商品数据。 通过该接口&#xff0c;您可以使用API Key和API Secret来认证身份&#xff0c;并使用…

Seata 四种事务模式

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。 全文参考文献&#xff1a;中文文档 TC (Transaction Coordinator) - 事务…

Redis入门指南学习笔记(2):常用数据类型解析

一.前言 本文主要介绍Redis中包含几种主要数据类型&#xff1a;字符串类型、哈希类型、列表类型、集合类型和有序集合类型。 二.字符串类型 字符串类型是Redis中最基本的数据类型&#xff0c;它是其他4种数据类型的基础&#xff0c;其他数据类型与字符串类型的差别从某种角度…

HALCON的综合应用案例【01】: 3D 算法处理在 Visual Studio 2019 C# 环境中的集成实例

前言: HALCON 为一款比较流行的商业视觉处理软件,他提供了多种开发的模式,可以在HALCON中开发,也可以将HALCON的设计通过导出库的形式集成到其他开发环境里面,以方便系统集成。本文为笔者自己的一个3D 视觉检测项目,利用HALCON的3D 库开发算法,然后,将算法集成到 MS-V…

指挥通信车360度3d虚拟互动展示系统的优势及特点

通信车是装有通信装备&#xff0c;用于保障通信联络的专用车辆&#xff0c;用于偏僻/特殊环境下的机动通信。并且机动通信局装备通常分为应急综合通信车、网络管理车、程控电话车、自适应跳频电台车、数字扩频接力车、散射通信车、卫星通信车、光缆引接车、线缆收放车和通信电源…

医疗数据可视化大屏:重构医疗决策的未来

医疗行业一直是信息密集型领域之一&#xff0c;它的复杂性不仅在于患者病历和医疗数据的海量积累&#xff0c;还包括了病情诊断、医疗资源分配、病患治疗等多层次的挑战。随着信息技术的不断发展&#xff0c;医疗数据可视化大屏成为了一种创新性的工具&#xff0c;它为医疗管理…

Linux学习笔记之一(计算机网络基础)

Linux learning note 1、计算机网络1.1、IP地址和MAC地址1.2、NAT、端口1.3、动态IP、静态IP、DHCP1.4、子网掩码、网关地址、DNS服务器1.5、TCP、UDP、ftp、http 2、虚拟机的网络管理2.1、桥接模式2.2、NAT模式2.3、仅主机模式2.4、总结 1、计算机网络 1.1、IP地址和MAC地址 …

python:将多个9波段影像tif文件转成numpy格式保存

作者:CSDN @ _养乐多_ 最近有粉丝问,如何将多个9波段的Aster影像tif文件转成numpy格式保存,然后输入网络进去训练。本文提供了两种思路和代码。 结果如下图所示, 文章目录 一、简单方法(分两步)二、端到端方法(一步到位)一、简单方法(分两步) 先将所有的多波段影像…

葡萄酒中的“多酚”有机化合物

“多酚”是在植物中发现的有机化合物&#xff0c;包括树皮、种子、坚果、茶叶和木材。单宁是一种多酚&#xff0c;它们完全是天然的&#xff0c;但是尝起来很苦。如果你是一个茶迷&#xff0c;你应该知道喝一口高单宁的红茶会使你的口腔内侧起皱。 葡萄也含有大量的单宁&#…

文心一言画图体验1.0

文心一言画图体验1 版本&#xff1a;文心大模型3.5 文心一言官方链接&#xff1a;https://yiyan.baidu.com/ 1、画一幅画&#xff1a;在大树下喝啤酒的熊猫&#xff0c;水墨风格&#xff0c;中国风&#xff0c;印象主义&#xff0c;写意&#xff0c;薄涂 2、画一幅画&#x…

一、VPN基础

VPN基础 1、定义及特征2、VPN优势3、VPN分类4、VPN体系结构5、VPN实现的模式 —————————————————————————————————————————————————— 1、定义及特征 虚拟专用网VPN是依靠Internet服务提供商ISP和网络服务提供商NSP在公共网…

如何保证跨国传输的安全性,了解这篇文章就够了

在当今的全球化时代&#xff0c;跨国传输是许多企业不可或缺的业务需求&#xff0c;无论是进行远程协作、数据分析、项目交付、市场拓展等&#xff0c;都需要在不同国家或地区之间进行数据、信息、货物或服务的传输。然而&#xff0c;跨国传输也面临着很多挑战和风险&#xff0…

中兴路由器、小米路由器无线信号强度对比

最近小米新推出的路由器小米AX3000T非常火&#xff0c;在网上看到有好多人都在安利&#xff0c;引起了我的兴趣&#xff0c;刚好老家的路由器用了这么久也是时候要换一个了&#xff0c;毕竟我妈老说上网卡??所以我立马就在PDD搞了一台回来&#xff0c;打算和我现在家里用的中…

【进程控制⑥】:进程替换/exec*()系列接口

【进程控制⑥】&#xff1a;进程替换/ exec*(&#xff09;系列接口 一.进程替换原理二.替换特点1.独立性2.唯一性3.不变性4.不返回 三.程序替换应用【exec*系列系统调用】①execl&#xff1a;②execlp&#xff1a;③execv&#xff1a;④execle&#xff1a; 一.进程替换原理 我…

【自动控制原理】数学模型:控制系统的运动微分方程、拉氏变换和反变换、传递函数

文章目录 第2章 数学模型基本概念2.1 控制系统的运动微分方程a. 常微分方程的一般标准形式b. 线性定常系统微分方程的一般标准形式 2.1.1 建立数学模型的一般步骤2.1.2 控制系统微分方程的列写 2.2 拉氏变换和反变换2.2.1 拉氏变换的定义2.2.2 典型函数的拉氏变换2.2.3 拉氏变换…

2023年鸿雁全国经销商大会暨秋季新品发布会圆满落幕

聚力同行&#xff0c;再起征程。11月2日&#xff0c;一场以“数字双翼&#xff0c;鸿雁奋飞”为主题的鸿雁全国经销商大会暨秋季新品布会在杭州盛大召开。鸿雁电器总裁王米成、副总裁吴明、副总裁夏晓衍、市场部总经理梁彩雷、灯饰与智能家居渠道部总经理王育炳、五金水暖渠道部…

照亮室外生活:户外灯具的创新趋势

日落之后&#xff0c;庭院变成了一个独特的世界&#xff0c;等待我们探索和享受。然而&#xff0c;要让庭院成为温馨、迷人的地方&#xff0c;户外照明起着关键作用。在这里&#xff0c;我们将讨论如何通过巧妙的户外照明&#xff0c;为庭院带来夜晚的魅力。 户外照明不仅是为了…

石油开采vr模拟生产安全体验平台提高员工上岗技能

近年以来我国矿山曾发生多起罐笼坠落事故&#xff0c;造成多人死伤&#xff0c;给企业和社会造成不良影响&#xff0c;事故的发生的主要原因多是人员违章、安全设施附件检修维护不到位。 钻井平台安全生产重于泰山&#xff0c;关乎经济社会发展大局&#xff0c;更关乎人们群众生…

StoneDB-8.0-V2.1.0 企业版正式发布!免费公测中!

很高兴告诉大家&#xff0c;我们StoneDB-8.0-V2.1.0企业版正式发布了&#xff01;经过一个月的开发&#xff0c;我们的研发团队用极高的效率对2.0新架构版本查漏补缺&#xff0c;完善了最新架构的代码&#xff0c;并对性能、稳定性做出了优化&#xff0c;同时也修复了一些用户们…

OmniGraffle Pro 7.22.2(思维导图工具)

OmniGraffle Pro是一款图表绘制和设计软件&#xff0c;它的主要特点包括&#xff1a; 功能强大&#xff1a;OmniGraffle Pro提供了丰富的图形设计工具&#xff0c;包括各种形状库、图层支持、自定义模板等&#xff0c;可以满足用户在图表绘制和设计方面的各种需求。智能连接和…