# Redis的数据类型
## 一、Redis的安装
可以直接去[中文官网](http://www.redis.net.cn/)中直接下载安装,进入这个网站,[点击下载](http://www.redis.cn/download.html),下载稳定版的即可。将该tar包下载后加压到一个没有中文字符路径的空文件夹中,即可直接使用,不用进行额外的配置。本地使用方式如下:
1. 打开redis-server.exe:这是一个redis的服务器端,相当于mysql软件
2. 打开redis-cli.ext:这是一个redis的客户端,可以供我们在本地操作redis数据库,类似与图形化界面,当然这里是使用命令行的方式操作redis数据库的。
例如:在redis-cli客户端中保存键为“name",值为”zhangsan"的一条数据,并获取该数据(相当于name=zhangsan)
![](https://img.kancloud.cn/c1/be/c1be7d60e15776533295884108fa72ed_1067x145.png)
## 二、Redis的数据类型
Redis底层是由C语言编写的,redis里面内置的数据结构即是用C语言的结构体实现的。有五种基础的数据类型,在redis6之后新增了三种。
> 值得说明的是这里的数据结构指的是值的类型,redis的键都是有字符串构成的。
### 2.1 数据类型分类
1. string:字符串类型;
2. hash:哈希类型,相当于map类型,值也是以键值对的形式存在的;
3. list:列表类型,可以支持重复性的数据;
4. set:集合类型,与list的区别是不支持重复性的数据;
5. sortedset:有序集合类型,在不支持重复的同时还保证数据是有序的。
6. Bitmaps:位图
7. HyperLogLog:
8. Geographic:
#### string
* 存储数据:
> set key value
* 取出数据:
> get key
* 删除键:
> del key
~~~
127.0.0.1:6379> set username zhangsan // 设置username的值为zhangsan
127.0.0.1:6379> get username //取出username对应的值
"zhangsan"
127.0.0.1:6379> del username //username的值将会被删除
~~~
#### hash类型
* 存储数据:
> hset key field value
即创建一个类型为hash,其键为key,里面有个字段为field,值为value,相当于{"key": {"filed":value}}
* 取出数据:
> hget key field
获取字段field中的值
* 取出hash中键值key的所有的字段数据:
> hgetall key
将会获取键值对,field=value
* 删除字段:
> hdel key field
删除键key的字段field
~~~
127.0.0.1:6379> hset person name zhangsan
127.0.0.1:6379> hset person age 21
// 即相当于创建了:person = {"name":"张三", "age":21}
127.0.0.1:6379> hget person name
"zhangsan"
127.0.0.1:6379> hgetall person
"name"
"zhangsan"
"age"
21
127.0.0.1:6379> hdel person name // 删除字段name
~~~
#### list类型
可以选择将一个元素添加到头部还是到尾部,很像一个双端队列结构
* 存储数据:
> lpush key value //将数据从左边添加到列表中
> rpush key value //将数据从右边添加到列表中
* 取出数据:
> lrange key start end
将start到end范围的索引的数据取出,从0开始,-1表示后一个元素
* 移除数据:
> lpop key //删除列表中最左边的元素,并将元素返回
> rpop key //删除列表中最右边的元素,并将元素返回
~~~
127.0.0.1:6379>lpush userlist zhangsan
127.0.0.1:6379>rpush userlist lisi
127.0.0.1:6379>lrange userlist 0 -1 //取出列表中所有的元素
"zhangsan"
"lisi"
127.0.0.1:6379>lpop userlist
"zhangsan"
127.0.0.1:6379>rpop userlist
"lisi"
~~~
#### set类型
与list类型类似,但是不会添加重复数据
* 存储数据:
> sadd key value
* 获取数据:
> smembers key
取出所有的值
* 删除数据:
> srem key value
~~~
127.0.0.1:6379>sadd myset a //给myset中添加"a"
127.0.0.1:6379>sadd myset b
127.0.0.1:6379>smembers myset
"a"
"b"
127.0.0.1:6379>srem myset a //删除a的值
~~~
#### sortedset类型
有序集合类型,不允许重复数据,存储数据时要为每个值设置一个double类型的score(分数)用来排序
* 存储数据:
> zadd key score value
* 取出数据:
> zrange key start end \[withscores\]
可选的withscores表示是否要将分数一起展示出来,起始索引下标为0,-1表示最后一个元素
* 删除数据:
> zrem key value
~~~
127.0.0.1:6379> zadd mysort 60 zhangsan //值zhangsan的score为60
(integer) 1
127.0.0.1:6379> zadd mysort 50 lisi //值lisi的score为50
(integer)1
127.0.0.1:6379> zadd mysort 80 wangwu //值wangwu的score为80
(integer) 1
127.0.0.1:6379> zrange mysort 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
127.0.0.1:6379> zrange mysort 0 -1 withscores
1) "zhangsan"
2) "60"
3) "wangwu"
4) "80"
5) "lisi"
6) "500"
127.0.0.1:6379> zrem mysort lisi //删除lisi的值
(integer) 1
~~~
#### Bitmaps
bitmaps(位图)严格上讲并不是新的一种数据类型,而是定义了字符串类型面向位的一组操作。通过在不同位上设置0或者1来存储不同的状态。
1. 创建位图对象的命令
~~~
localhost:6379>setbit key offset value
~~~
offset为偏移量,表示要将哪一位设置成0/1。
2. 获取某一位的状态命令
~~~
localhost:6379>getbit key offset
~~~
offset为偏移量。返回值为0或者1。对没有设置的位都会返回0。
3. 统计为1的个数
~~~
localhost:6379>bitcount key
~~~
或者是
~~~
localhost:6379>bitcount key 0, 1
~~~
这样可以获取`字节`0和1中位为1的个数。
4. 两个key之间进行逻辑运算
~~~
localhost:6379>bitop operate destkey key1 key2
~~~
operate可选类型为:and,or,xor等逻辑运算。
5. 找到第一指定为0或者1的位
~~~
localhost:6379>bitpos key 0/1 [start] [end]
~~~
> 应用场景
1. 可以用在统计网站的日活跃用户。
2. 各种实时分析,例如和对象ID相关的,可以将对象的ID的大小表示为第几位,进而统计相关的信息。
#### HyperLogLog
是一种概率数据结构,用来统计一个集合中的基数。当数据的量特别大的时候,使用HyperLogLog就可以节省大量的内存,HyperLogLog使用的是固定的大小存储基数,为12KB,可以统计2^64个数据。Redis中统计出来的结果可能与实际的有1%的偏差。
1. 创建:
~~~
localhost:6379>pfadd key value
~~~
基数增加成功会返回1,否则返回0.
2. 统计基数数量:
~~~
localhost:6379>pfcount key
~~~
![](https://img.kancloud.cn/ec/d8/ecd8155bff1ae6137cefea40f8dbe480_843x66.png)
集合{1,2,3, 4, 1, 1, 1, 1} 统计出来的基数就是4。
3. 合并两个HyperLogLog类型
~~~
localhost:6379>pfmerge key key1 key2
~~~
> 应用场景
1. 统计网站的页面访问量。
2. 统计独立访客的数量。
#### Geographic
地图的坐标类型,可以设置经纬度,查询,范围查询的等操作。
1. 创建
~~~
geoadd key 经度 纬度 地点
~~~
2. 获取:
~~~
geopos key 地点
~~~
3. 获取两个地点的直线距离
~~~
geodist key 地点1 地点2 显示单位
~~~
显示单位的可取值为:
`km,m,mi(英里),ft(英尺)`。
4. 获取一定范围内的数据:
~~~
georadius key 经度 纬度 半径长度 显示单位
~~~
### 2.2 其他通用命令操作
* keys \* :查询所有键,可以使用正则表达式的方式
* type key:查询该键的类型
* del key:删除指定的键
## 三、java操作Redis
~~~
java使用Jedis工具来操作redis数据库。如果还没有下载Jedis相关的jar的话,可以到<a href="https://jar-download.com/artifacts/redis.clients/jedis/3.3.0">这里下载</a>。或者如果是使用maven的话,可以在pom.xml配置如下引入相关依赖
~~~
~~~
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
~~~
(版本号可以选择自己想要)
### 3.1使用方式
Jedis的使用非常简便,只要创建对应的Jedis对象即可。
~~~
Jedis jedis = new Jedis("localhost", 6379); //连接本地的Jedis数据库,无参构造的话默认就是这两个值 注意要将本地的redis服务端打开
jedis.set("name", "zhangsan"); //设置一个字符串类型的数据 name=zhangsan
jedis.get("name"); // zhangsan
~~~
jedis中对数据操作的那些方法的方法名是和上面将的redis中的命令是一致的,只是Jedis中命名是驼峰命名,有一些名称可能要区分一下大小写。例如
~~~
jedis.hset("user", "name", "zhangsan"); //设置一个map数据
jedis.hset("user", "age", "22");
jedis.hget("user", "name");
jedis.hgetAll("user");
~~~
可见其使用方式和命名行的使用方式是类似的,只不过把数据当成参数进行传递,就不在这里过多赘述了。
其他方法:
~~~
jedis.close(); //关闭连接jedis.setex(String key, int seconds, String value); //设置seconds秒数之后自动删除该键值对
~~~
### 3.2 连接池
与mysql类似的,redis也有一个数据连接池对象为JedisPool,下面创建一个redis数据库连接的工具类,用于获取JedisPool连接池和获取Jedis连接对象。
~~~
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public final class JedisUtil {
/** * JedisPool连接池对象 */
private static JedisPool jedisPool;
static {
JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(50); //最大连接数,设置为0表示没有限制 config.setMaxIdle(10); //最大等待的连接数,设置为0表示没有限制 jedisPool = new JedisPool(config, "localhost", 6379);
}
/** * 获取Jedis连接对象 */
public static Jedis getJedis() {
return jedisPool.getResource();
}
/** * 关闭jedis连接 */
public static void close(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
}
~~~
### 3.3 与Spring Boot整合
1. 引入依赖
~~~
<!-- 整合redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.x版本集成redis所需common-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
~~~
2. application.yml中配置属性
~~~
spring:
# redis配置
redis:
host: localhost
port: 6379
database: 0 # 数据库索引,默认为0
timeout: 1800000 # 连接超时时间
lettuce:
pool:
max-active: 20 # 连接池中的最大连接数,负值表示没有限制
max-wait: 1 # 连接池中的最大等待数
max-idle: 5 # 连接池中的最大空闲数
min-idle: 0 # 连接池中的最小空闲数
~~~
3. 书写Redis配置类
~~~
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置key的序列化方式
redisTemplate.setKeySerializer(redisSerializer);
// 设置值的序列化方式
redisTemplate.setValueSerializer(redisSerializer);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 解决查询缓存转换异常的问题
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 配置序列化,解决乱码问题,过期时间设置为10分钟
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.disableCachingNullValues();
RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(configuration)
.build();
return redisCacheManager;
}
}
~~~
`配置类的内容都差不多。`
4. 注入RedisTemplate对象
~~~
@Autowried
private RedisTemplate redisTemplate;
~~~
## 四、概念补充
Redis(Remote Dictionary Server),即远程字典服务,是一款有**C语言开发**的,**高性能**的NOSQL系列的存储**键值对**类型的数据库。
NoSQL:not only sql,不仅仅是sql,指的是一种非关系型数据库,区别于mysql这种关系型数据库,能够处理大规模的数据和高并发的场景。
注意redis并不是用来替代关系型数据库,是用来在某些特定的场合下能和关系型数据库相互补充。例如,在一些需要频繁从数据库获取相同的数据的场合中,在第一次读取数据时,可以先将数据从mysql读取,同时保存在redis数据库中,之后再读取时直接从redis数据库中读取。
### 4.1常用的NoSQL系列的数据库
**键值对系列**
* 相关产品:Redis, Voldemort, Berkeley DB等
* 使用场景:内容缓存,主要用于处理大量数据的高访问负载为题。
* 数据存储类型:键值对,key-value,value是非结构化的。
**列存储数据库**
* 相关产品:HBase,Riak,Cassandra
* 使用场景:分布式的文件系统
* 数据存储类型:以列簇式存储,将一列数据放在一起
**文档型数据库**
* 相关产品:MongoDB, CouchDB
* 使用场景:web应用
* 数据存储类型:一系列键值对,与key-value类似,但是value是结构化的。
**图形数据库**
* 相关产品:Noe4J, InfoGrid, Infinite Graph
* 使用场景:社交网络
* 数据存储类型:图结构
### 4.2 Redis的使用场景
1. 缓存:数据查询,新闻内容,短连接,商品内容, 可以让数据只从关系型数据库中获取一次,之后从缓存中获取将会大大加快速度
2. 聊天室在线好友列表
3. 任务队列,例如秒杀操作,抢购(12306)
4. 排行榜
5. 网站访问统计
6. 数据过期处理,可以精确到毫秒值
7. 分布式集群架构中的session分离
- 第一章 Java基础
- ThreadLocal
- Java异常体系
- Java集合框架
- List接口及其实现类
- Queue接口及其实现类
- Set接口及其实现类
- Map接口及其实现类
- JDK1.8新特性
- Lambda表达式
- 常用函数式接口
- stream流
- 面试
- 第二章 Java虚拟机
- 第一节、运行时数据区
- 第二节、垃圾回收
- 第三节、类加载机制
- 第四节、类文件与字节码指令
- 第五节、语法糖
- 第六节、运行期优化
- 面试常见问题
- 第三章 并发编程
- 第一节、Java中的线程
- 第二节、Java中的锁
- 第三节、线程池
- 第四节、并发工具类
- AQS
- 第四章 网络编程
- WebSocket协议
- Netty
- Netty入门
- Netty-自定义协议
- 面试题
- IO
- 网络IO模型
- 第五章 操作系统
- IO
- 文件系统的相关概念
- Java几种文件读写方式性能对比
- Socket
- 内存管理
- 进程、线程、协程
- IO模型的演化过程
- 第六章 计算机网络
- 第七章 消息队列
- RabbitMQ
- 第八章 开发框架
- Spring
- Spring事务
- Spring MVC
- Spring Boot
- Mybatis
- Mybatis-Plus
- Shiro
- 第九章 数据库
- Mysql
- Mysql中的索引
- Mysql中的锁
- 面试常见问题
- Mysql中的日志
- InnoDB存储引擎
- 事务
- Redis
- redis的数据类型
- redis数据结构
- Redis主从复制
- 哨兵模式
- 面试题
- Spring Boot整合Lettuce+Redisson实现布隆过滤器
- 集群
- Redis网络IO模型
- 第十章 设计模式
- 设计模式-七大原则
- 设计模式-单例模式
- 设计模式-备忘录模式
- 设计模式-原型模式
- 设计模式-责任链模式
- 设计模式-过滤模式
- 设计模式-观察者模式
- 设计模式-工厂方法模式
- 设计模式-抽象工厂模式
- 设计模式-代理模式
- 第十一章 后端开发常用工具、库
- Docker
- Docker安装Mysql
- 第十二章 中间件
- ZooKeeper