Redis從認識安裝到實現增刪改查

Redis從一無所知,到知道一點點

Redis是一個使用ANSI C編寫的開源、支持網絡、基於內存、可選持久性的鍵值對存儲數據庫 ——維基百科java

能夠簡單的說,Redis就是一款高性能的NoSQL數據庫linux

什麼是NoSQL?

咱們前面所學習的MySQL數據庫是典型的的SQL數據庫也就是傳統的關係型數據庫,而咱們今天學習的Redis數據庫則是一款NoSQL數據庫,也叫做非關係型數據庫,它與咱們熟悉的MySQL等的概念徹底是不同的,它是一項全新的數據庫理念,咱們帖一組百度百科的解釋git

NoSQL,泛指非關係型的數據庫。隨着互聯網web2.0網站的興起,傳統的關係數據庫在處理web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,出現了不少難以克服的問題,而非關係型的數據庫則因爲其自己的特色獲得了很是迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題 ——百度百科github

說明:咱們如今所看到的的博客,RSS,P2P,微博,抖音等均屬於 Web2.0的產物,Web2.0相比較過去的Web1.0更加註重於用戶的交互,用戶不只能夠瀏覽,還能夠上傳一些資源到網站上,例如圖片文字或者說短視頻等,使得用戶也參與到了網站內容的製造中去了web

爲何使用NoSQL?

  1. 部署成本低:部署操做簡單,以開源軟件爲主
  2. 存儲格式豐富:支持 key-value形式、文檔、圖片等衆多形式,包括對象或者集合等格式
  3. 速度快:數據存儲在緩存中,而不是硬盤中,並且例如Redis基於鍵值對,同時不須要通過SQL層解析,性能很是高
  4. 無耦合性,易擴展
    • 在SQL中,一個正在使用的數據是不容許刪除的,但NoSQL卻能夠操做

NoSQL能夠替代SQL嗎?

有人會說,NoSQL = Not SQL ,可是我更傾向這樣理解 NoSQL = Not only SQL ,咱們不能以一個絕對的結論來斷定兩項技術的好壞,每一項技術的產生都有其特定的緣由,在我看來,NoSQL更適合做爲SQL數據庫的補充,因爲海量數據的出現,性能的要求高了起來,而NoSQL這種產物,對於結構簡單可是數據量大的數據處理起來要比傳統的SQL快不少,可是一樣的,其邏輯運算就必須很簡單,不然它也是力不從心的redis

在我看來,能夠簡單的說,NoSQL就是以功能換取性能,可是須要處理複雜的業務邏輯還須要使用關係型數據庫,因此說想要在模型中徹底用NoSQL替代SQL是不現實的,二者更像是互補的關係sql

SQL的好處:數據庫

  1. 支持在一個表以及多表以前進行復雜的查詢操做
  2. 支持對事物的處理,能保證數據的安全要求
  3. 學習成本低,資料較多

市面上的NoSQL產品很是多,咱們今天所要介紹的就是其中一款基於鍵值存儲的數據庫——Rediswindows

初識Redis

咱們在一開始提到了,Redis就是一款高性能的NoSQL數據庫,那麼它的應用場景是什麼呢?緩存

  • 用於用戶內容緩存,能夠處理大量數據的高訪問負載,例如:數據查詢,新聞,商品內容
  • 任務隊列,例如:秒殺,12306

  • 在線好友列表

  • 應用、網站訪問統計排行

因爲其基於鍵值存儲,那麼能夠支持的存儲的類型有什麼呢?

  • 字符串類型 - String

  • 列表 - list:linkedlist

  • 集合 - set

  • 有序集合 - sortedset

  • 哈希 - hash:map

下載安裝

linux

官網:https://redis.io

因爲官網訪問速度過慢,咱們能夠訪問對應的中文網:http://www.redis.net.cn

下載,解壓,編譯:

$ wget http://download.redis.io/releases/redis-5.0.4.tar.gz
$ tar xzf redis-5.0.4.tar.gz
$ cd redis-5.0.4
$ make

二進制文件是編譯完成後在src目錄下. 運行以下:

$ src/redis-server

你能使用Redis的內置客戶端進行進行redis代碼的編寫,例如咱們存入一個鍵值 name-zhangsan

$ src/redis-cli
redis> set name zhangsan
OK
redis> get name
"zhangsan"

windows

咱們能夠去github中尋找windows版本,不過版本會有所滯後

https://github.com/microsoftarchive/redis/releases

解壓便可用

  • redis-server.exe:redis服務器端

  • redis-cli.exe:redis的客戶端
  • redis.windows.conf:配置文件

常見支持類型—存取刪除命令操做

(一) 字符串類型 - String

(1) 存儲
  • set key value
- 127.0.0.1:6379> set address beijing
- OK
(2) 獲取
  • get key
- 127.0.0.1:6379> get address
- 「beijing」
(2) 刪除
  • del key
- 127.0.0.1:6379> del address
- (integer) 1

(二) 列表類型 - list

添加一個元素到列表的頭部(左邊)或者尾部(右邊)

(1) 添加
  • lpush key value:將元素添加到列表左邊
  • Rpush key value:將元素添加到列表右邊
127.0.0.1:6379> lpush listDemo zhangsan
(integer) 1
127.0.0.1:6379> lpush listDemo lisi
(integer) 2
127.0.0.1:6379> rpush listDemo wangwu
(integer) 3
(2) 獲取:lrange key start end
  • 127.0.0.1:6379> lrange listDemo 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
(2) 刪除
  • lpop key:刪除列表最左邊的元素,且返回元素
  • rpop key:刪除列表最右邊的元素,且返回元素

(三) 集合類型 - set

set:String 類型的無序集合,且元素不能重複

(1) 存儲
  • sadd key value
127.0.0.1:6379> sadd setDemo aaa
(integer) 1
127.0.0.1:6379> sadd setDemo aaa
(integer) 0
(2) 獲取
  • smembers key:獲取set集合中的全部元素
127.0.0.1:6379> smembers setDemo
1) "aaa「
(2) 刪除
  • srem key value:刪除set集合中某元素
127.0.0.1:6379> srem setDemo aaa
(integer) 1

(四) 有序集合類型 - sortedset

sortedset 和 set 同樣也是 string 類型元素的集合,且不容許重複的元素

不一樣的是每一個元素都會關聯一個double類型的分數,redis正是經過分數來爲集合中的成員進行從小到大的排序

有序集合的成員是惟一,但分數(score)卻能夠重複

(1) 存儲
  • zadd key score value
127.0.0.1:6379> zadd sortedsetDemo 20 zhangsan
(integer) 1
127.0.0.1:6379> zadd sortedsetDemo 10 lisi
(integer) 1
127.0.0.1:6379> zadd sortedsetDemo 60 wangwu
(integer) 1
(2) 獲取
  • zrange key start end [withscores]
127.0.0.1:6379> zrange sortedsetDemo 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
(2) 刪除
  • zrem key value
127.0.0.1:6379> zrem sortedsetDemo wangwu
(integer) 1

(五) 哈希類型 - hash

(1) 存儲
  • hset key field value
127.0.0.1:6379> hset hashDemo username admin
(integer) 1
127.0.0.1:6379>  hset hashDemo password admin
(integer) 1
(2) 獲取
  • hget key field:獲取指定的field對應的值
127.0.0.1:6379> hget hashDemo password
"admin"
  • hgetall key:獲取全部的field和value
127.0.0.1:6379> hgetall hashDemo
1) "username"
2) "admin"
3) "password"
4) "admin"
(2) 刪除
  • hdel key field
127.0.0.1:6379> hdel hashDemo username
(integer) 1

數據持久化

開篇已經講過,Redis是一個內存數據庫,也就是說,咱們的數據所有存儲在內存中,而咱們常見的MySQL和Oracle等SQL數據庫會將數據存儲到硬盤中,凡事都是有利有弊,雖然內存數據庫讀寫速度要比在硬盤中讀寫的數據庫快的多,可是卻出現了一個很麻煩的問題,也就是說,當 Redis 服務器重啓或者宕機後,內存中的數據會所有丟失,爲了解決這個問題,Redis提供了一種持久化的技術,也就是將內存中的數據存儲到硬盤中去,往後方便咱們使用這些文件恢復數據庫中的數據

RDB 方式 (默認方式)

RDB:必定的時間內,檢測key的變化狀況,而後持久化數據

咱們想要配置它,須要編輯 redis.windows.conf 配置文件

# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#   ......省略部分

save 900 1
save 300 10
save 60 10000

咱們須要修改的就是最後三行,前面的說明的意思是,若是給定的秒數和給定的對數據庫的寫操做數同時發生,那麼將保存數據庫,也就是說,它的配置是根據save後面的兩個數字,根聽說明可知,第一個數字表明間隔時間,第二個數表明操做數據的數量

例如第一個 save 900 1 ,就是說每900秒且,至少一個 key 被改變則保存數據

咱們根據本身具體項目的須要設置好後,須要從新啓動Redis的服務器,而且咱們須要指定配置文件,咱們先指向到Redis指定目錄下, 而後輸入命令 redis-server.exe redis.windows.conf

例如我本地:D:\Tools\Redis-x64-3.2.100>redis-server.exe redis.windows.conf

AOF 方式

AOF:每一次操做後,就持久化數據

咱們一樣能夠在 redis.windows.conf 文件配置

咱們找到這一行

appendonly no no表明關閉aof,改成yes表明開啓

還有這一行

# appendfsync no:不進行持久化

咱們能夠修改 no 位置的值

  • appendfsync always:每一次操做都進行持久化
  • appendfsync everysec:每隔一秒進行一次持久化

Jedis - Java中操做Redis數據庫

Jedis is a blazingly small and sane Redis java client.

Jedis was conceived to be EASY to use.

Jedis 是一款可讓咱們在java中操做redis數據庫的工具,下載其jar包導入便可,使用仍是很是簡單的

(一) 字符串類型 - String

//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();

//存儲
jedis.set("address","beijing");

//獲取
String address = jedis.get("address");

//關閉鏈接
jedis.close();

補充:setex() 方法能夠存儲數據,而且指定過時時間

//將aaa-bbb存入,且10秒後過時
jedis.setex("aaa",10,"bbb")

(二) 列表類型 - list

//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();

//存儲
jedis.lpush("listDemo","zhangsan","lisi","wangwu");//從左
jedis.rpush("listDemo","zhangsan","lisi","wangwu");//從右
    
//獲取
List<String> mylist = jedis.lrange("listDemo", 0, -1);
            
//刪除,而且返回元素
String e1 = jedis.lpop("listDemo");//從左
String e2 = jedis.rpop("listDemo");//從右

//關閉鏈接
jedis.close();

(三) 集合類型 - set

//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();

//存儲
jedis.sadd("setDemo","zhangsan","lisi","wangwu");

//獲取
Set<String> setDemo = jedis.smembers("setDemo");

//關閉鏈接
jedis.close();

(四) 有序集合類型 - sortedset

//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();

//存儲
jedis.zadd("sortedsetDemo",20,"zhangsan");
jedis.zadd("sortedsetDemo",10,"lisi");
jedis.zadd("sortedsetDemo",60,"wangwu");
    
//獲取
Set<String> sortedsetDemo = jedis.zrange("sortedsetDemo", 0, -1);

//關閉鏈接
jedis.close();

(五) 哈希類型 - hash

//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();

//存儲
jedis.hset("hashDemo","name","lisi");
jedis.hset("hashDemor","age","20");
    
//獲取
String name = jedis.hget("hashDemo", "name");

//獲取全部數據
Map<String, String> user = jedis.hgetAll("hashDemo");
    

Set<String> keySet = user.keySet();
for (String key : keySet) {
    //獲取value
    String value = user.get(key);
    System.out.println(key + ":" + value);
}

//關閉鏈接
jedis.close();

Jedis 鏈接池

爲何咱們要使用鏈接池呢?

咱們要使用Jedis,必須創建鏈接,咱們每一次進行數據交互的時候,都須要創建鏈接,Jedis雖然具備較高的性能,但創建鏈接卻須要花費較多的時間,若是使用鏈接池則能夠同時在客戶端創建多個鏈接而且不釋放,鏈接的時候只須要經過必定的方式獲取已經創建的鏈接,用完則歸還到鏈接池,這樣時間就大大的節省了

//建立一個配置對象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(10);
        
//建立Jedis鏈接池對象
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
        
//獲取鏈接
Jedis jedis = jedisPool.getResource();

//使用
jedis.set("setDemo","zhangsan");

//關閉 歸還到鏈接池中
jedis.close();

鏈接池工具類

public class JedisPoolUtils {
    private static JedisPool jedisPool;
    //靜態代碼初始化池配置
    static{
        
        //建立Properties對象
        Properties pro = new Properties();
        
        //讀取配置文件
        InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
        
        //關聯文件
        try {
            pro.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //獲取數據,配置到JedisPoolConfig
        JedisPoolConfig config = new JedisPoolConfig();                 
        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
            
        //實例化JedisPool
        jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
        
        }

        /**
        * 獲取鏈接
        */
        public static Jedis getJedis(){
            return jedisPool.getResource();
        }
}

結尾:

若是文章中有什麼不足,或者錯誤的地方,歡迎你們留言分享想法,感謝朋友們的支持!

若是能幫到你的話,那就來關注我吧!若是您更喜歡微信文章的閱讀方式,能夠關注個人公衆號

在這裏的咱們素不相識,卻都在爲了本身的夢而努力 ❤

一個堅持推送原創開發技術文章的公衆號:理想二旬不止

相關文章
相關標籤/搜索