# 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)

## 二、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
~~~

集合{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