1、Redis簡介
對於一個稍有經驗的程序員,都應知道:內存條的讀寫速度是遠高於硬盤的讀寫速度的,而在以往的數據庫中,我們往往以硬盤爲主,這樣導致了讀寫硬盤頻繁,系統效率低下,而Redis則是以內存爲主,讀寫都儘可能的發生在內存中。
舉個例子:在剛開始學習Java語言的時候,小松還沒學到數據庫,可是他需要保存數據,於是自己寫了一個文件管理API,供自己使用。(弱化版的數據庫)
後來,他發現因爲只是演示作用,所以根本不需要持久化,而且又對開發效率有很大要求,於是他直接使用了HashMap做存儲。(將數據存儲在HashMap中,HashMap的數據放在內存中,這就是一個弱化版的Redis)。
爲了方便Java程序員理解,我推薦將 Redis 理解爲一個大號的HashMap。
- HashMap是鍵值對,Redis的數據也是以鍵值對的形式存儲。
- HashMap不支持線程安全,Redis則是單線程應用。
- HashMap使用的是拉鍊法,Redis能存儲List並對其操作。(強行理解)
你可以認爲Redis就是C語言寫出來的HashMap,並增加了遠程訪問,本地備份,主從複製等功能。
Redis的安裝:
2、 爲什麼選擇Redis
在簡介中,我們提到了HashMap,其實在很多應用中HashMap就已經足夠程序員優化數據了。
如果Redis就是一個大號的HashMap,那麼爲什麼還需要Redis呢?
- 這裏的答案應該與“爲什麼我們不自己實現一個文件操作系統,而使用別人寫好的數據庫?”相同。
- 別人寫好的Redis支持了遠程訪問,本地備份,主從複製等等功能。
- 自己的HashMap除了操作方便(其實就是懶得學Redis,學了Jedis後會發現其實差不多方便)。沒啥其他優點了。
- Redis是C語言寫的,距離底層更近。(我沒說C一定比Java快,Java是世界第一的語言)
- Redis花了大把大把的代碼做了HashMap做不到的功能,我們爲什麼要重複造輪子呢?
2.1 Redis的幾個特性
Redis 的持久化:
- 定期保存最新的Redis快照。
- 將所有Redis操作都保存到一個文件中。
- 以上兩種都是思想,實際上做了非常多的優化,這裏不展開講。
Redis的線程安全:
- Redis是單線程應用,所以沒有線程問題。
- 實際上,,Redis是有多線程的,不過絕大多數操作都是單線程,而上面的持久化就是一個多線程操作(持久化是一個只讀操作)。
Redis的主從複製:
- 最開始:執行復制的從服務器會連接上主服務器,接受主服務器發送的整個數據庫的初始副本;
- 之後:所有主服務執行的寫命令都會發送給從服務器,讓他們執行寫操作。
- 很明顯,主從架構可以實現讀寫分離,提升系統效率。
3、Redis能存儲什麼?
在回答這個問題之前,我先隨手提下Java中最常見的幾個類。
幾個小問題:
Q: 爲什麼八大基本類型只留下了兩個?
> 因爲其他六個都可以用最基本的這兩個表示,這兩個的數據組織方式不同,所以不可以再刪除。
Q: Set底層不是Map嗎? 爲什麼還要保留?
> 因爲Redis能存儲Set類型,我刪了還怎麼講?
接下來畫出來Redis能存儲的數據結構
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gBeyOI3w-1577699124536)(C:\Users\Administrator\Pictures\Redis\Redis能存儲的數據結構.png)]
Q: Redis不直接支持int和double?
對,Redis支持int和double,不過需要存入和取出時仍是String,當然你依然可以按照int來自增自減,而且其是原子操作。
4、Redis數據結構簡介
先來一個沒人會看的表格。
結構類型 | 結構存儲的值 | 結構的讀寫能力 |
---|---|---|
STRING | 能存儲string,int,double | 字符串基本操作和自增自減操作 |
LIST | 類比於:LinkedList< STRING > | 支持雙向隊列操作,支持偏移量trimLIST 支持同時讀取多個元素。 |
SET | 類比於:Set< STRING > | 支持Set的基本操作(增刪改查去重) |
HASH | 類比於:HASHMAP< STRING> | 增刪查單個元素,獲取所有鍵值對。 |
ZSET | 有序集合,按照指定規則排序 | 增刪查單個元素,根據規則獲取相對的鍵值對們。 |
接下來涉及到Redis操作,請根據其他博客裝上Redis後進行操作。
4.1 Redis中的字符串(STRING)
與其說是字符串,就是一個標準的HashMap<String,String>.
字符串首先是一個鍵值對形式,我們看看鍵值對的基礎操作。
我們啓動redis做一個演示.
127.0.0.1:6379> set hello world # 放入鍵值對<hello, world>
OK # 操作成功
127.0.0.1:6379> get hello # 得到鍵爲hello的value
"world"
127.0.0.1:6379> del hello # 刪除key = hello
(integer) 1 # 影響元素的個數
127.0.0.1:6379> get hello # 驗證已刪除
(nil) # null
上述操作很簡單,也無需介紹,除這些以外,redis提供了許多對字符串的操作。不過這些內容我們等到後面專門的章節進行講述。
4.2 Redis中的列表(LIST)
相當於HashMap<String,LinkedList< String>>.
列表相對於STRING來說,增加了許多操作,比如兩端都可以進入和拋出,還可以打印下標位於(left,right)的元素。
直接上操作.
# 下面的意思是 從右側依次放入 item,item2,item
# rpush = rightpush
127.0.0.1:6379> rpush list-key item
(integer) 1
127.0.0.1:6379> rpush list-key item2
(integer) 2
127.0.0.1:6379> rpush list-key item3
(integer) 3
# lrange 是打印下表屬於 [start,stop]的所有元素。 -1爲全部
127.0.0.1:6379> lrange list-key 0 -1
1) "item"
2) "item2"
3) "item3"
# get操作 lindex = 從left數的[i]個。
127.0.0.1:6379> lindex list-key 1
"item2"
# 拋出最左側元素: lpop = leftpop;
127.0.0.1:6379> lpop list-key
"item"
# 驗證是否
127.0.0.1:6379> lrange list-key 0 -1
1) "item2"
2) "item3"
127.0.0.1:6379>
4.3 Redis中的集合(SET)
相當於 HashMap<String, Set< String>>
直接上操作吧.
# set 添加操作,sadd = setAdd, 通俗易懂.
127.0.0.1:6379> sadd set-key item
(integer) 1
127.0.0.1:6379> sadd set-key item2
(integer) 1
127.0.0.1:6379> sadd set-key item3
(integer) 1
# set添加重複元素,自然會失敗,所以return 0.
127.0.0.1:6379> sadd set-key item
(integer) 0
# 查看所有元素,順序很玄學。
127.0.0.1:6379> smembers set-key
1) "item2"
2) "item3"
3) "item"
# 是否包含操作, sismember = setIsMember.詢問是否是這個集合中的元素。
127.0.0.1:6379> sismember set-key item4
(integer) 0
127.0.0.1:6379> sismember set-key item
(integer) 1
# srem = set remove.刪除元素.
127.0.0.1:6379> srem set-key item2
(integer) 1
127.0.0.1:6379> srem set-key item2
(integer) 0
# 查看所有元素.
127.0.0.1:6379> smembers set-key
1) "item3"
2) "item"
4.4 Redis的散列
相當於Java中的HashMap<String, HashMap<String, String>>
# hset = hash set《key,<key,value>》
127.0.0.1:6379> hset hash-key sub-key1 v1
(integer) 1
127.0.0.1:6379> hset hash-key sub-key2 v2
(integer) 1
127.0.0.1:6379> hset hash-key sub-key1 v1
(integer) 0
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "v1"
# 其實,我覺得如果能打印成: "sub-key1"<--->"v1"就好了。
3) "sub-key2"
4) "v2"
# hdel = hash_delete
127.0.0.1:6379> hdel hash-key sub-key2
(integer) 1
127.0.0.1:6379> hget hash-key sub-key1
"v1"
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "v1"
127.0.0.1:6379> hset hash-key sub-key1 v2
(integer) 0
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "v2"
4.5 Redis的有序集合.
有序集合可以類比Java中的TreeMap,這個是字定義分數。
操作:
127.0.0.1:6379> zadd zset-key 728 m1
(integer) 1
127.0.0.1:6379> zadd zset-key 982 m0
(integer) 1
127.0.0.1:6379> zadd zset-key 982 m0
(integer) 0
127.0.0.1:6379> zrange zset-key 0 -1 withscores
1) "m1"
2) "728"
3) "m0"
4) "982"
127.0.0.1:6379> zrangebyscore zset-key 0 800 withscores
1) "m1"
2) "728"
127.0.0.1:6379> zrem zset-key m1
(integer) 1
127.0.0.1:6379> zrem zset-key m1
(integer) 0
127.0.0.1:6379> zrange zset-key 0 -1 withscores
1) "m0"
2) "982"
127.0.0.1:6379>