「数据库」 redis入门到实战
mhr18 2024-11-18 14:32 19 浏览 0 评论
- 基本介绍
- 为什么会用redi, 为什么大小公司都在用redis
- 微信红包
- 微博
- 淘宝
- 讲到redis不得不将nosql
- nosql是不同于传统的关系型数据库管理系统的统称, 其两者最重要的区别是nosql不使用sql作为查询语句
- noql数据库可以不需要固定的表格模式, noql是基于键值对, 可以想象成表中的主键和值的对应关系
- nosql: redis, memcached, mongodb, guava(loadingCache)
- redis定义
- redishi一个开源(BSD许可)的, 内存中的数据结构存储系统, 他可以用作数据库, 缓存和消息中间件, 它支持多种类型的数据结构, 如字符串(strings), 数列(hashes), 列表(lists),集合(sets),有序集合(sorted sets) 等
- 从大家熟悉的mysql出发来认识redis
- 概念: 关系型数据库的一个长江用法是存储长期的报告数据, 并将这些报告数据用作固定时间范围内的聚合数据, 收集聚合数据的常见做法是: 先将各个行插入一个报告表里面, 之后再通过扫描这些行来收集聚合数据
- 图解剖析mysql的执行过程(网上自己找图看)
- 分析redis和mencached和mysql之间的区别
- 从数据库类型, 数据存储方式, 特殊功能讲解redis和mencached和mysql的区别
- 作为同款功能的内存缓存产品, redis和memcached各有什么优势
- 内存管理机制
- mencached默认使用Slab Allocation机制管理内存, 其主要思想按照预先规定的大小, 将分配的内存分割成特定长度的块, 以存储相应长度的key-value数据记录, 以完全解决内容碎片问题,
- redis使用现场申请内存的方式来存储数据, 并且很少使用free-list等方式来优化内存分配, 会在一定程度上存在内存碎片
- 数据持久化方案
- memcached不支持内存数据的持久化操作, 所有的数据都以in-memory的形式存储
- redis支持持久化操作, redi提供了两种不同的持久化方法来将数据存储到硬盘里面
- 第一种是rdb形式: 基于全量护具备份, 备份的是数据
- 第二种是aof形式: append only if, 增量持久化备份, 备份的是指令 [例如: set key, del key]
- 缓存数据过期机制
- mencached在删除失效主键时也是采用消极方法, 即memcached内部也不会见识主键是否失败, 而是在通过get访问主键时才会检查其是否已经失败
- 定时, 定期等多种缓存失效机制, 减少内存泄露
- redis作为数据库和作为内存缓存的两种使用方法
- redis作为数据库的使用有什么优缺点:
- 优点: 没有Schema约束, 数据结构的变更相对容易, 抗压能力强, 性能极高
- 缺点: 没有索引, 没有外键, 缺少int/date等基本数据类型, 多条件查询需要通过集合内联(sinter, zintertore)和链接间接开发效率低, 可维护性不佳
- redis作为缓存的左右, 搭配数据库使用的两种方法
- jedis整合使用方案
- 第一层在缓存进行查询, 如果得到数据则直接返回
- 第二层在数据库进行查询, 并且刷新缓存, 方便下次查询
- 作为mybatis/hibernate二级缓存使用方法
- 一级缓存: sqlSession级别, 进程缓存, 单次链接有效
- 图解分析加redis前后的架构区别
掌握redis五中数据结构(string,list,set,sortset,hash)
- String: 是最常用的一种数据类型, 普通的key/value存储都可以归为此类
- set/get
- 设置key对应的值为string类型的value
- 获取key对应的值
- mget
- 批量获取多个key的值, 如果可以不存在则返回null
- incr && incrby
- incr对key对应的值进行加加操作, 并返回新的值; incrby加指定值
- decr && decrby
- decr对key对应的值进行减减操作, 并返回新的值; decrby减指定值
- sentx
- 设置key对应的值为String类型的value, 如果key直径存在则返回0
- setex
- 设置key对应的值为string类型的value, 并设定有效时间
- 其他指令
- getrange: 获取key对应value的子字符串
- mset: 数量设置多个key的值, 如果成功表示所有值都被设置, 否则返回0表示没有任何值被设置
- msetnx, 同mset, 不存在就设置, 不会覆盖已有的key
- getset: 设置key的值, 并返回key旧的值
- append: 给指定key的value增加字符串, 并返回新字符串的长度
Hash类型
- Hash类似于HashMap
- key / value的形式
- 格式: Map<String, Map<String, String>>
- 第一个String 就是 Map<String, String> 的名称
- Hash 是一个String类型的field和value之间的映射类
- redis的Hash数据类型的key(hash表名称)对应的value实际的内部存储结构为一个HashHashMap
- Hash特别适合存储对象
- 相当于把一个对象的每个属性存储String类型, 将整个对象存储在Hash类型中会占用更少内存.
- 所存储的成员较少时数据存储为zipmap, 当成员数量大时会自动转成真正的HashMap, 此时encoding为ht
- 运用场景:
- 如用一个对象来存储对象信息, 商品信息, 订单信息等等
- Hash命令讲解:
- hset: 设置key对应的HashMap中的field的value
- hget: 获取key对应的HashMap中的field的value
- hgetall: 获取所有key-value信息
- hmset: 一次设置多个属性
- hdel: 删除一个属性
- hlen: 获取set的长度
LIst数据类型
- lpush: 在key对应的list的头部添加一个元素
- lrange: 获取key对应的list的指定下标范围的元素, -1表示获取所有元素
- lpop: 从key对应的list的头部删除一个元素, 并返回该元素
- rpush: 在key对应的list的尾部添加一个元素
- rpop: 从key对应的list的尾部删除一个元素, 并返回该元素
- lrem: 删除一定个数或者指定的元素
- lrem list 2 value2 删除两个值为value2的记录
- lindex: 获取指定索引下标的值
- llen: 获取list的长度
set集合
- sadd: 在key对应的set中添加一个元素
- smembers: 获取key对应的set的所有元素
- spop: 随机返回并删除key对应的set中的一个元素
- suion: 求给定key对应的set并集
- sinter: 求给定key对应的set交集
- sdiff: 求给定key对应的set的差集
SortSet讲解
- zadd: 在key对应的zset中添加一个元素
- zrange: 获取key对应的zset中指定范围的元素, -1表示获取所有元素
- zrem: 删除key对应的zset中的一个元素
- zrangebyscore: 返回有序集key中, 指定分户范围的元素列表
- zrank: 返回key对应的zet中指定member的排名, 其中member按score值递增(从小到大), 排名以0为底, 也就是说, score值是最小的成员排名为0
- zcard: 查询sortset有多少个元素(长度)
- set是通过hasmmap存储, key对应et的元素, value是空对象
- sortset是怎么存储并实现排序的呢, hashmap存储, 还加了一层跳跃表
- 跳跃表: 相当于双向链表, 在其基础上添加前往比当前元素大的跳跃链接
redis发布订阅
- 发布订阅作用: 类似于信息管道, 用来进行系统之间消息解耦, 类似于mq, rabbitmq, rocketmq, kafka, activemq, 主要有消息发布者和消息订阅者
- PUBLISH: 将消息message发送到指定的平道channel, 返回收到消息的客户端信息
- SUBSCRIBE: 订阅给指定频道的信息
- UNSUBSCRIBE: 取消订阅指定的频道, 如果不指定, 则取消订阅所有的频道
传统关系型数据库事务
- 一个数据库事务通常包含了一个序列的对数据库的读写操作, 他的存在包含有以下两个目的
- 为数据库操作序列提供了一个从失联中恢复到正常状态的方法, 同时提供了数据库即使在异常状态下仍然能保持一致性的方法
- 当多个应用程序在并发访问数据库时, 可以在这些应用程序之间提供一个隔离方法, 以防止彼此的操作互相干扰
- 事务ACID四大特性
- 原子性(Atomicity): 事务作为一个整体被执行, 包含在其中的对数据库的操作要么全部成功, 要么全部不成功
- 一致性(Consistency): 事务应该确保数据库的状态从一个状态转变为另一个状态一致
- 隔离性(Isolation): 多个事务并发执行时, 一个事务的执行不会影响另外一个事务
- 持久性(Durability): 已经被提交的事务对数据的修改应该是永久保存在数据库中
- 事务隔离机制:
- read uncommitted 读未提交
- read committed 读已提交
- repeatable read 可重复读
- serializable 串行化
redis事务机制
- MULTI 与 EXEX命令
- 以MULTI开始一个事务, 然后将多个命令如队列到事务中, 最后由EXEC命令触发事务, 一并执行十五中的所有命令
- DISCARD命令
- DISCARD命令用于取消一个事务, 他清空客户端整个事务队列, 然后将客户端从事务状态调整回非事务状态, 最后返回字符串OK给客户端, 说明事务已经被取消
- WATCH命令
- WATCH命令用于在事务开始之前见识任意数量的键. 当调用EXEC命令执行事务时, 如果任意一个被见识的键已经被其他客户端修改了, 那么整个事务不再执行, 直接返回失败.
- 图解redis执行事务过程原理
redis事务与传统关系型事务的比较
- 原子性(Automicity)
- 单个Redis命令的执行是原子性的, 但Redis没有在事务上增加任何维持原子性的机制, 所以Redis事务的执行并不是原子性的, 如果一个事务队列中的所有命令都被成功的执行, 那么称这个事务执行成功
- 一致性(Consistency)
- 入队错误
- 在命令入队的过程中, 如果客户端向服务器发送了错误的命令, 比如命令命令参数数量不对,等等, 那么服务器向客户端返回一个出错信息, 并且将客户端的事务状态设为 REDIS_DIRTY_EXEC
- 执行错误
- 如果命令在事务执行的过程中发生错误, 比如说, 对一个不同类型的key执行了错误的错误, 那么Redis只会将错误包含在事务的结果中, 这不会引起事务中断或这个失败, 不会影响已执行事务命令的结果, 也不会影响后续要执行的事务命令, 所以他对事务的一致性也没有影响
- 隔离性(Isolation)
- WATCH 命令用于在事务开始之前见识任意数量的键, 当调用EXEC命令执行事务时, 如果任意一个被监控的键被其他客户端修改了, 那么整个事务不再执行, 直接返回失败
- 持久性(Durability)
- 因为事务不过是用队列包裹起了一组Redis命令, 并没有提供任何额外的持久性功能, 所以事务的持久性由redis所使用的持久化模式决定
- redis持久化模式包括:
- rdb: 数据内存备份
- aof(append onlyif增量备份), 每个一秒做一个备份
springboot整合redis
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
- 引入bean
- redisTemplate的使用, 类似于: mongoTemplate, jdbcTemplate数据库链接工具, RedisTemplate是从redisConnectionFactory中获取的
- 引入jar包 spring-boot-starter-data-redis
- 实例代码
- RedisConfig.java
package cn.jishupeng.redis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
- textController.java
package cn.jishupeng.redis.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@RestController
public class test {
@Resource
private RedisTemplate redisTemplate;
@GetMapping("/setAndget")
public String index(String name) {
redisTemplate.opsForValue().set("name", name);
return (String)redisTemplate.opsForValue().get("name");
}
}
redisTemplate api
- opsForValue -> String
- opsForSet -> Set
- opsForHash -> Hash
- opsForZset -> SortSet
- opsForList -> List
springboot快速整合mybatis(极简 mysql版本8.X)
- 加入依赖
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
- 配置application.properties文件
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/redis?characterEncoding=utf-8&serverTimezone=UTC&useSSL=false&allowP
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
- 启动类加上@MapperScan(basePackage = )注解
package cn.jishupeng.redis;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan(basePackages = "cn.jishupeng.redis.mapper")
@SpringBootApplication
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}
}
- 创建UserMapper包(该文件下都是接口文件, 每个文件都要加上@Mapper注解, 否则扫描不到)
package cn.jishupeng.redis.mapper;
import cn.jishupeng.redis.domain.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("select * from user")
User find();
}
- domain/User 实体类文件
package cn.jishupeng.redis.domain;
import org.springframework.stereotype.Repository;
public class User {
private int id;
private String username;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
'}';
}
}
- controller/TestController(常规使用, 直接使用@Autowired注入UserMapper文件, 就可以快乐玩耍啦...)
package cn.jishupeng.redis.controller;
import cn.jishupeng.redis.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@RestController
public class test {
@Autowired
private UserMapper userMapper;
@Resource
private RedisTemplate redisTemplate;
@GetMapping("/setAndget")
public String index(String name) {
redisTemplate.opsForValue().set("name", name);
return (String)redisTemplate.opsForValue().get("name");
}
@GetMapping("/getUser")
public String getUser() {
return (String)userMapper.find().getUsername();
}
}
redis作为mybatis缓存整合
- 用户第一次访问的时候获取数据库的值, 再次访问时直接从缓存中获取数据
- 设置缓存过期时间
- 项目8080端口是对外端口(向外部暴露的端口), 区别内部进程号, 查内部端口用ps -ef|grep, 查外部端口用 lsof -i:8080
- 缓存级别
- 一级缓存: sqlSession, sql建立链接到关闭链接的数据缓存
- 二级缓存: 全局
- springboot cache的使用: 可以结合redis, ehcache等缓存
- @Cacheable: (查询时使用)来划分可缓存的方法, 即, 结果存储在缓存中的方法, 以便在后续调用(具有相同的参数)时, 返回缓存中的值而不必实际执行该方法
- @CachePut: (更新时使用)当需要更新缓存而不干扰方法执行时, 可以使用@CachePut注释, 也就是说, 始终执行该方法并将其结果放入缓存中(根据@CachePut选项)
- @CacheEvict:(删除时使用) 对于从缓存中删除旧或未使用的数据非常有用, 指示缓存范围内的驱逐是否需要执行而不仅仅是一个条目驱逐
- springboot整合cache的步骤
- 引入依赖 spring-boot-starter-cache
- 开启缓存注解: @EnableCaching
- 在方法上面加入SpEL
redis分布式缓存
- 引入依赖:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
- 加入注解 @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 50)
- controller方法
package cn.jishupeng.redis.controller;
import org.springframework.http.HttpRequest;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@RequestMapping("/session")
@RestController
public class RedisHttpSession {
@RequestMapping("/set")
@ResponseBody
public Map<String, String> set(HttpServletRequest request) {
Map<String, String> ret = new HashMap<>();
request.getSession().setAttribute("request Uri", request.getRequestURI());
ret.put("request Uri", request.getRequestURI());
return ret;
}
@RequestMapping("/get")
@ResponseBody
public Map<String, Object> get(HttpServletRequest request) {
Map<String, Object> ret = new HashMap<>();
Object id = request.getSession().getId();
ret.put("request Uri", id);
return ret;
}
}
- redis客户端中
- keys * 查找所有的键
- ttl 查看超时时间
redis项目实战值排行榜实现(上)
- 排行榜
- 排行榜功能是一个很普遍的需求, 使用redis中有序集合的特性来实现排行榜是又好又快的实现
- 一般排行榜都是有时效性, 比如""用户积分榜", 游戏中活跃度排行榜, 游戏装备排行榜等等
- 面临问题: 数据库设计复杂, 并发较高, 数据要求实时性高
- redis实现排行榜api讲解
浅谈mysql数据库设计
- 表设计过程中应该注意的点即数据类型
- 更小的通常更好, 控制字节长度
- 使用合适的数据类型
- 如tinyint只占8个位, char与varchar的对比
- 尽量避免NULL NOT NULL DEFAULT ''
- NULL的列会让索引统计和值比较都更复杂. 可为NULL的列会占据更多的磁盘空间, 在Mysql中也需要更多复杂的处理程序
- 索引设计过程中更应该注意的点
- 选择唯一性索引
- 唯一性索引的值是唯一的, 可以更快的通过该索引来确定某条记录
- 为经常需要排序, 分组和联合操作的字段建立索引
- 经常需要order by, group by, distinct和union等操作的字段, 排序操作会浪费更多的时间
- 长作为查询条件的字段建立索引
- 如果某个字段常用来做查询条件, 那么该字段的查询速度会影响整个表的查询速度
- 数据少的地方不必建立索引
- sql优化, explain查看执行计划
- 能够用between的就不要用in
- 能够用distinct的就不要用group by
- 避免数据强转
- 学会采用wxplain查看执行计划
- 上一篇:Redis从库失败导致集群概率读不到
- 下一篇:Redis的持久化
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)