黑马程序员Redis--基础篇

目录

[1 NoSQL](#1 NoSQL)

[2 Redis](#2 Redis)

[2.1 Redis 特征](#2.1 Redis 特征)

[2.2 Redis安装](#2.2 Redis安装)

[2.3 Redis客户端](#2.3 Redis客户端)

[2.3.1 Redis命令行客户端](#2.3.1 Redis命令行客户端)

[2.3.2 图形化桌面客户端](#2.3.2 图形化桌面客户端)

[3 Redis数据结构及通用命令](#3 Redis数据结构及通用命令)

[3.1 通用命令](#3.1 通用命令)

[3.2 String](#3.2 String)

[3.3 Hash(键值对)](#3.3 Hash(键值对))

[3.4 List(有序、可重复)](#3.4 List(有序、可重复))

[3.5 Set(无序、不可重复)](#3.5 Set(无序、不可重复))

[3.6 SortedSet(有序、不重复)](#3.6 SortedSet(有序、不重复))

[4 Redis的Java客户端](#4 Redis的Java客户端)

[4.1 Jedis](#4.1 Jedis)

[4.2 Spring Data Redis](#4.2 Spring Data Redis)

[4.3 RedisTemplate 的两种序列化实践方案](#4.3 RedisTemplate 的两种序列化实践方案)


1 NoSQL

比较维度 SQL(关系型数据库) NoSQL(非关系型数据库)
全称 Structured Query Language 结构化查询语言 Not Only SQL
数据结构 结构化:表结构数据库,像 Excel 表格。有行、列、字段类型严格固定。 非结构化 / 半结构化(如 Redis 键值类型)
数据关系 表与表有关系,强关联 无关联
操作语言 用统一的 SQL 语句操作 非 SQL
事务 ACID(强事务 / 无事务) BASE(弱事务 / 无事务)
存储位置 硬盘(磁盘)为主,持久化存储 内存(快) + 硬盘(如 Redis 常用内存,MongoDB 用硬盘)
核心优势 安全、准确、支持复杂查询 快、高并发、结构灵活
适合场景 银行、订单、用户账户、必须保证数据 100% 准确 高并发、大数据量、缓存、日志、用户行为、聊天记录
选择口诀 要安全、要准确、要关联 → 选 SQL 要快、要高并发、要灵活 → 选 NoSQL

2 Redis

Redis = REmote DIctionary Server

远程字典服务器

基于内存 的 NoSQL 键值(Key-Value)数据库

Redis官网

2.1 Redis 特征

  1. 纯内存操作 → 速度极快
  2. Key-Value 型数据库(value支持多种数据结构)
  3. 单线程 + IO 多路复用 → 高并发、无锁竞争
  4. 支持数据持久化(定期写入磁盘、安全)
  5. 非关系型、无表结构、无关联

2.2 Redis安装

Redis安装在Linux虚拟机上,此处用的CentOS7,流程如下:

  • 打开 VMware(虚拟机软件) → 启动虚拟电脑

  • 虚拟电脑里跑着 CentOS (Linux操作系统)

  • 打开 FinalShell(SSH 工具,用于远程连接、管理Linux) → 连接 CentOS → 开始操作 Linux

    //Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖
    yum install -y gcc tcl

    //Redis安装包上传到虚拟机的/usr/local/src 目录,解压缩
    cd /usr/local/src
    tar -xzf redis-6.2.6.tar.gz

    //进入redis目录
    cd redis-6.2.6

    //运行编译、安装命令
    make && make install

    //默认的安装路径是在 /usr/local/bin目录下,可以进入目录查看一下
    cd /usr/local/bin
    ll

安装完成后,在任意目录输入redis-server命令即可启动Redis(第一种启动方式),但前台启动会阻塞整个会话窗口:

复制代码
redis-server

指定配置启动(第二种启动方式):修改Redis配置文件,就在我们之前解压的redis安装包下,名字叫redis.conf,可修改为后台启动,同时可以配置更多信息,比如log等等。

开机自启(第三种启动方式):

复制代码
vi /etc/systemd/system/redis.service

[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target

systemctl daemon-reload

# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis

执行下面的命令,可以让redis开机自启:

复制代码
systemctl enable redis

2.3 Redis客户端

2.3.1 Redis命令行客户端

复制代码
redis-cli [options] [commonds]
  • h 127.0.0.1:指定要连接的redis节点的IP地址,默认是127.0.0.1
  • p 6379:指定要连接的redis节点的端口,默认是6379
  • a 123321:指定redis的访问密码

ping:与redis服务端做心跳测试,服务端正常会返回pong.

2.3.2 图形化桌面客户端

Redis的图形化桌面客户端,地址:https://github.com/uglide/RedisDesktopManager

在下面这个仓库可以找到安装包:https://github.com/lework/RedisDesktopManager-Windows/releases

若连接不成功,注意开放6379端口。

复制代码
# 开放 6379 端口
firewall-cmd --permanent --add-port=6379/tcp
# 重新加载防火墙规则
firewall-cmd --reload

# 验证端口是否开放
firewall-cmd --list-ports


3 Redis数据结构及通用命令

数据结构 示例数据 典型应用场景
String hello world 缓存、计数器、分布式锁、Session 存储
Hash {name: "Jack", age: 21} 用户信息、商品详情、配置项
List A -\> B -\> C -\> C 消息队列、评论列表、栈 / 队列
Set {A, B, C} 去重、点赞 / 收藏、共同好友、抽奖
SortedSet(ZSet) {A: 1, B: 2, C: 3} 排行榜、热搜榜、优先级队列
GEO {A: (120.3, 30.5)} 附近的人、地址检索、路线规划
BitMap 0110110101110101011 签到统计、用户活跃状态、布隆过滤器
HyperLogLog 0110110101110101011 UV 统计、独立访客数、海量数据去重计数

String、Hash、List、Set、SortedSet 是 Redis 最核心、最常用的 5 种数据结构,后三种只适合特殊场景。

3.1 通用命令

命令写法查看:https://redis.io/docs/latest/commands/

命令行查看:help command,比如:help keys

命令 功能描述 重要说明 / 示例
KEYS 查看所有符合给定模式的 key ⚠️不建议在生产环境使用,会阻塞 Redis 主线程(因为单线程)遍历所有键,性能极差。 示例:KEYS user*
DEL 删除一个或多个指定的 key 成功删除返回删除数量,key 不存在返回 0。 示例:DEL name age
EXISTS 判断一个或多个 key 是否存在 存在返回 1,不存在返回 0;多个 key 时返回存在的数量。 示例:EXISTS name
EXPIRE 为指定 key 设置过期时间(秒),到期后自动删除 成功设置返回 1,key 不存在或设置失败返回 0。 示例:EXPIRE name 60(60 秒后过期)
TTL 查看指定 key 的剩余存活时间(秒) 返回值:正数 = 剩余秒数;-1= 永不过期;-2=key 不存在 / 已过期。 示例:TTL name

3.2 String

string、int、float

命令 功能描述 示例
SET 添加或修改一个 String 类型的键值对 SET name "Jack"
GET 根据 key 获取对应的 String 类型 value GET name → 返回 "Jack"
MSET 批量添加多个 String 类型的键值对 MSET age 21 city "Beijing" gender "male"
MGET 根据多个 key 批量获取对应的 value MGET name age city → 返回 "Jack", "21", "Beijing"
INCR 让一个整型 key 的值自增 1 INCR count → 若 count 为 5,执行后变为 6
INCRBY 让一个整型 key 的值按指定步长自增 INCRBY num 2 → 若 num 为 3,执行后变为 5
INCRBYFLOAT 让一个浮点类型 key 的值按指定步长自增,浮点型自增必须设置步长 INCRBYFLOAT price 0.5 → 若 price 为 10.0,执行后变为 10.5
SETNX SET Not Exist 仅当 key 不存在时,添加一个 String 类型键值对(不存在才设置) SETNX lock "true" → 若 lock 不存在则设置成功,返回 1;若已存在则返回 0
SETEX SET EXpire 添加一个 String 类型键值对,并指定过期时间(秒) SETEX token 300 "abc123" → token 会在 300 秒后自动过期删除

KEY的层级结构 :用户模块用 id:1,商品模块也用 id:1,此时会产生冲突。因此用 冒号 : 分隔,模拟目录层级,让 Key 分类清晰、易管理、不冲突。

复制代码
192.168.100.128:6379> SET heima:user:1 '{"id":1, "name":"Jack", "age": 21}'
OK
192.168.100.128:6379> SET heima:user:2 '{"id":2, "name":"Rose", "age": 18}'
OK
192.168.100.128:6379> SET heima:product:1 '{"id":1, "name":"小米11", "price": 4999}'
OK
192.168.100.128:6379> SET heima:product:2 '{"id":2, "name":"荣耀6", "price": 2999}'
OK

192.168.100.128:6379> KEYS heima:*
1) "heima:product:2"
2) "heima:user:1"
3) "heima:user:2"
4) "heima:product:1"

3.3 Hash(键值对)

String 存储对象的痛点

将对象序列化为 JSON 字符串存入 String 类型时:heima:user:1 → {name:"Jack", age:21}

修改单个字段极不方便!!!需要先取出整个 JSON、反序列化、修改、再序列化存回。

Hash 结构将对象的每个字段独立存储为 field-value:

优势:可以针对单个字段做 CRUD,无需操作整个对象,更高效、更灵活。

命令 功能描述 示例
HSET 添加或者修改 hash 类型 key 的 field 的值 HSET heima:user:1 name Jack
HGET 获取一个 hash 类型 key 的 field 的值 HGET heima:user:1 name
HMSET 批量添加多个 hash 类型 key 的 field 的值 HMSET heima:user:1 name Jack age 21
HMGET 批量获取多个 hash 类型 key 的 field 的值 HMGET heima:user:1 name age
HGETALL 获取一个 hash 类型的 key 中的所有的 field 和 value HGETALL heima:user:1
HKEYS 获取一个 hash 类型的 key 中的所有的 field HKEYS heima:user:1
HVALS 获取一个 hash 类型的 key 中的所有的 value HVALS heima:user:1
HINCRBY 让一个 hash 类型 key 的字段值自增并指定步长 HINCRBY heima:user:1 age 1
HSETNX 添加一个 hash 类型的 key 的 field 值,前提是这个 field 不存在,否则不执行 HSETNX heima:user:1 gender male
复制代码
192.168.100.128:6379> HMSET heima:user:3 name Lilei age 21
OK
192.168.100.128:6379> HMGET heima:user:3 name age
1) "Lilei"
2) "21"
192.168.100.128:6379> HGETALL heima:user:3
1) "name"
2) "Lilei"
3) "age"
4) "21"
192.168.100.128:6379> HKEYS heima:user:3
1) "name"
2) "age"
192.168.100.128:6379> HVALS heima:user:3
1) "Lilei"
2) "21"

192.168.100.128:6379> HSET heima:user:3 age 24
(integer) 0
192.168.100.128:6379> HVALS heima:user:3
1) "Lilei"
2) "24"

3.4 List(有序、可重复)

List 双向链表,支持正向 / 反向检索。

核心特征:有序、可重复、插入 / 删除极快、查询速度一般(遍历链表)。

命令 功能描述 示例
LPUSH key element 向列表左侧插入一个或多个元素 LPUSH users 1 2 3
LPOP key 移除并返回列表左侧的第一个元素,没有则返回 nil LPOP users
RPUSH key element 向列表右侧插入一个或多个元素 RPUSH users 4 5 6
RPOP key 移除并返回列表右侧的第一个元素 RPOP users
LRANGE key start stop 返回一段角标范围内的所有元素 LRANGE users 0 5
BLPOP key timeout 与 LPOP 类似,在没有元素时等待指定时间,而非直接返回 nil BLPOP users 5
BRPOP key timeout 与 RPOP 类似,在没有元素时等待指定时间,而非直接返回 nil BRPOP users 5
复制代码
192.168.100.128:6379> LPUSH users 1 2 3
(integer) 3
192.168.100.128:6379> RPUSH users 4 5 6
(integer) 6
192.168.100.128:6379> LRANGE users 0 5
1) "3"
2) "2"
3) "1"
4) "4"
5) "5"
6) "6"

3.5 Set(无序、不可重复)

特征: 无序、不可重复、查找速度快、支持集合运算。

命令 功能描述 示例
SADD key member1 member2 ... 向 set 中添加一个或多个元素 SADD s1 a b c
SMEMBERS key 获取 set 中的所有元素 SMEMBERS s1
SISMEMBER key member 判断一个元素是否存在于 set 中 SISMEMBER s1 a
SCARD key 返回 set 中元素的个数 SCARD s1
SREM key member1 member2 ... 移除 set 中的指定元素 SREM s1 a
SINTER key1 key2 求多个 set 的交集 SINTER s1 s2
SUNIONkey1 key2 求多个 set 的并集 SUNION s1 s2
SDIFF key1 key2 求多个 set 的差集,在第一个不在第二个 SDIFF s1 s2
复制代码
192.168.100.128:6379> SADD s1 a b c
(integer) 3
192.168.100.128:6379> SMEMBERS s1
1) "a"
2) "c"
3) "b"

192.168.100.128:6379> SADD zhangsan lisi wangwu zhaoliu
(integer) 3
192.168.100.128:6379> SADD lisi wangwu mazi ergou
(integer) 3
192.168.100.128:6379> SCARD zhangsan
(integer) 3

192.168.100.128:6379> SINTER zhangsan lisi
1) "wangwu"
192.168.100.128:6379> SDIFF zhangsan lisi
1) "zhaoliu"
2) "lisi"
192.168.100.128:6379> SUNION zhangsan lisi
1) "ergou"
2) "lisi"
3) "wangwu"
4) "zhaoliu"
5) "mazi"

3.6 SortedSet(有序、不重复)

特征:可排序、不重复、查询速度快、常使用在排行榜、优先级队列等需要排序的业务场景。

命令 功能描述 示例
ZADD key score member 添加一个或多个元素到 sorted set,若元素已存在则更新其 score 值 ZADD stus 85 Jack 89 Lucy
ZREM key member 删除 sorted set 中的一个指定元素 ZREM stus Tom
ZSCORE key member 获取 sorted set 中指定元素的 score 值 ZSCORE stus Amy
ZRANK key member 获取 sorted set 中指定元素的排名(从小到大,从 0 开始) ZREVRANK stus Rose 获取分数排名时要从大到小,加上REV
ZCARD key 获取 sorted set 中的元素个数 ZCARD stus
ZCOUNT key min max 统计 score 值在给定范围内的所有元素的个数 ZCOUNT stus 80 100
ZINCRBY key increasement member 让 sorted set 中的指定元素自增,步长为指定的 increment 值 ZINCRBY stus 5 Jack
ZRANGE key min max 按照 score 排序后,获取指定排名范围内的元素(默认升序) ZREVRANGE stus 0 2 获取前几名时要从大到小,加上REV
ZRANGEBYSCORE key min max 按照 score 排序后,获取指定 score 范围内的元素 ZRANGEBYSCORE stus 90 100
ZDIFF numkeys key1 key2 求多个 sorted set 的差集 ZDIFF 2 stus stus2
ZINTER numkeys key1 key2 求多个 sorted set 的交集 ZINTER 2 stus stus2
ZUNION numkeys key1 key2 求多个 sorted set 的并集 ZUNION 2 stus stus2

默认从小到大,Z 变成 ZREV 就是 倒序、从大到小 的意思。

复制代码
192.168.100.128:6379> ZADD stus 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles
(integer) 7
192.168.100.128:6379> ZREM stus Tom
(integer) 1
192.168.100.128:6379> ZSCORE stus Amy
"92"

4 Redis的Java客户端

工具 核心特点 线程安全 定位
Jedis 轻量、命令和 Redis 一致、学习简单 基础 Redis 客户端
Lettuce 基于 Netty、异步非阻塞、高并发稳定 高级 Redis 客户端
Spring Data Redis 封装 Jedis/Lettuce、提供统一 API、集成 Spring ❤ Spring 生态 Redis 操作模板
Redisson 基于 Redis 实现分布式 Java 数据结构、提供分布式锁 / 队列等高级功能 分布式场景专用工具 (侧重分布式服务)

Jedis 和 Lettuce 是底层客户端,Spring Data Redis 是上层封装,SpringBoot 默认用 Lettuce。

4.1 Jedis

官网快速入门:https://github.com/redis/jedis

Jedis 缺点:

(1)Jedis 实例本身是线程不安全的,多线程环境下直接使用会引发并发问题。

(2)频繁创建 / 销毁 Jedis 连接会产生性能损耗,影响系统效率。

==>推荐使用 Jedis 连接池 替代直连方式。

Jedis 使用基本步骤:

  1. 引入依赖:在项目中引入 Jedis 的 Maven 依赖。
XML 复制代码
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>7.1.0</version>
</dependency>
  1. 创建 Jedis 对象,建立连接:通过 new Jedis(host, port) 实例化对象并连接 Redis,可补充认证、选择数据库等操作。
java 复制代码
@BeforeEach
void setUP() {
    jedis = new Jedis("192.168.100.128", 6379);
    jedis.auth("123321");
    jedis.select(0);
}
  1. 使用 Jedis:调用与 Redis 命令同名的方法(如 set()/get() 对应 SET/GET 命令)操作数据。
java 复制代码
@Test
void testString() {
    String result = jedis.set("name", "虎哥");
    System.out.println("result = " + result);
    String name = jedis.get("name");
    System.out.println("name = " + name);
}
  1. 释放资源:调用 close() 方法关闭连接,释放底层资源,避免连接泄漏。
java 复制代码
@AfterEach
void tearDown() {
    //必须先判断不为空再关闭,防止jedis创建失败是null,直接close()会空指针崩溃
    if (jedis != null) {
        jedis.close();
    }
}

测试通过!

Jedis连接池

  • 不直接 new Jedis() ,而是使用 JedisPool 连接池 统一管理连接。
  • 连接池在类加载时初始化一次,全局复用,避免频繁创建 / 销毁连接。
  • 用完连接不真正关闭 ,而是归还到连接池,供其他线程使用。

连接池工具类:提供统一获取 Jedis 连接的方法,内部维护一个静态、不可变的连接池对象:private static final JedisPool jedisPool。

java 复制代码
package com.heima.jedis.util;

public class JedisConnectionFactory {

    private static final JedisPool jedisPool;

    //static { } 就是:类一加载就自动运行,且只运行一次的代码块。
    static {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(8);
        jedisPoolConfig.setMaxIdle(8);
        jedisPoolConfig.setMinIdle(0);
        jedisPoolConfig.setMaxWait(Duration.ofMillis(1000));
        jedisPool = new JedisPool(jedisPoolConfig, "192.168.100.128", 6379, 1000, "123321");
    }

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

使用连接池获取一个 Jedis

java 复制代码
package com.heima.test;

public class JedisTest {

    private Jedis jedis;

    @BeforeEach
    void setUP() {
        jedis = JedisConnectionFactory.getJedis(); //不再new一个jedis,而是从池子里拿一个
        jedis.auth("123321");
        jedis.select(0);
    }

    @Test
    void testString() {
        String result = jedis.set("name", "虎哥");
        System.out.println("result = " + result);
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }

    @AfterEach
    void tearDown() {
        if (jedis != null) {
            jedis.close(); //归还给池子
        }
    }
}

4.2 Spring Data Redis

Spring Data 模块下的 Redis 集成组件,是 Spring 生态中操作 Redis 的统一方案。

官网:https://spring.io/projects/spring-data-redis

  1. 整合 Lettuce、Jedis 等多种 Redis 客户端,底层切换灵活。
  2. 提供RedisTemplate统一 API,简化 Redis 操作。
  3. 支持 Redis 发布订阅、哨兵、集群等高级模式。
  4. 支持基于 Lettuce 的响应式编程。
  5. 提供多种数据序列化方案(JDK、JSON、字符串、Spring 对象等)。
  6. 实现了基于 Redis 的 JDK Collection 接口,可以像操作 Java 集合 (List/Map/Set 等)一样操作 Redis

RedisTemplate快速入门:

① 引入依赖

XML 复制代码
<!--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>

② 配置文件application.yml

XML 复制代码
spring:
  data:
    redis:
      host: 192.168.100.128
      port: 6379
      password: 123321
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0
          max-wait: 1000ms

③ 注入RedisTemplate并使用

java 复制代码
@SpringBootTest
class RedisDemoApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void testString() {
        redisTemplate.opsForValue().set("name", "虎哥");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
}

4.3 RedisTemplate 的两种序列化实践方案

RedisTemplate:默认 JDK 序列化(乱码、体积大,不推荐)

StringRedisTemplate:RedisTemplate 的子类,key/value 都默认 String 序列化(推荐)

(1)方案1:自定义 RedisTemplate + JSON 自动序列化

适用场景:快速开发,不想手动处理 JSON,让 RedisTemplate 自动序列化成可读 JSON。但是会存全类名,体积大。

  1. 自定义 RedisTemplate
  2. 修改 RedisTemplate 的序列化器为 GenericJackson2JsonRedisSerializer

(2)方案二:StringRedisTemplate + 手动 JSON 转换 ❤

适用场景:企业生产最常用,可控性强、无冗余数据、跨语言兼容。

  1. 使用 StringRedisTemplate
  2. 写入 Redis 时,手动把对象序列化为 JSON
  3. 读取 Redis 时,手动把读取到的 JSON 反序列化为对象
java 复制代码
@SpringBootTest
class RedisStringTests {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 普通字符串存、取 Redis
    @Test
    void testString() {
        stringRedisTemplate.opsForValue().set("name", "虎哥");
        Object name = stringRedisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }

    /**
     * 定义Jackson的ObjectMapper工具对象
     * 用于实现Java对象和JSON字符串的相互转换(序列化/反序列化)
     * 声明为static final,全局复用,提升性能
     */
    private static final ObjectMapper mapper = new ObjectMapper();

    // 对象 → JSON → 存 Redis,读 Redis → JSON → 对象
    @Test
    void testSaveUser() throws JsonProcessingException {
        //创建对象
        User user = new User("虎哥", 21);
        //手动序列化
        String json = mapper.writeValueAsString(user);
        //写入redis
        stringRedisTemplate.opsForValue().set("user:100", json);
        //读取数据
        String jsonUser = stringRedisTemplate.opsForValue().get("user:100");
        //手动反序列化
        User user1 = mapper.readValue(jsonUser, User.class);
        //输出结果
        System.out.println("user1:" + user1);
    }

}
相关推荐
运维行者_5 小时前
企业无线网络监控的挑战与智能化演进趋势
大数据·运维·服务器·网络·数据库
国强_dev5 小时前
技术探讨:使用 stunnel 加密转发数据库连接时,如何获取客户端真实 IP?
数据库·网络协议·tcp/ip
@insist1235 小时前
系统规划与管理师-信息系统规划核心工作要点解析
数据库·软考·系统规划与管理师·软件水平考试·系统规划与管理工程师
超级数据查看器5 小时前
超级数据查看器 v10.0 发布
java·大数据·数据库·sqlite·安卓
数安3000天6 小时前
增量数据如何自动分类分级,避免目录“过期“?
大数据·数据库
桌面运维家6 小时前
如何用半缓存云桌面将服务器硬盘容量扩展至本地终端?
运维·服务器·缓存
南墙上的石头7 小时前
麒麟 V10 重装人大金仓 V8R6 踩坑实录(含 MySQL 兼容模式)
数据库·mysql
画中有画8 小时前
论向量数据库在项目中的应用
数据库
spider_xcxc8 小时前
Redis 数据库高质量实践指南(一)
运维·数据库·redis·oracle·云计算
l1t9 小时前
在linux和windows中解决duckdb 1.6dev版本输出执行计划报错问题
linux·运维·数据库·windows·duckdb