redis——對象

剛寫了redis主要的數據結構:

動態字符串、雙端鏈表、字典、壓縮列表、整數集合、跳表等

redis肯定不能直接使用這些數據結構來實現數據庫,它用這些數據庫建立了一個對象系統,包含:

字符串對象、列表對象、哈希對象、集合對象、有序集合對象

我們可以針對不同的使用場景,為對象設置多種分不同的數據結構實現,從而優化對象在不同場景下的效率。

鍵值對

對于redis的鍵值對來說:key只有字符串類型,而v可以是各種類型,

我們習慣把“這個鍵所對應的值是一個列表”表達為這是一個“列表鍵。

TYPE?命令的實現方式也與此類似, 當我們對一個數據庫鍵執行?TYPE?命令時, 命令返回的結果為數據庫鍵對應的值對象的類型, 而不是鍵對象的類型:

# 鍵為字符串對象,值為列表對象redis> RPUSH numbers 1 3 5
(integer) 6redis> TYPE numbers
list

對象

我們看一下redis對象的組成:

typedef struct redisObject {// 類型unsigned type:4;// 編碼unsigned encoding:4;// 指向底層實現數據結構的指針void *ptr;// ...
} robj;

通過?encoding?屬性來設定對象所使用的編碼, 而不是為特定類型的對象關聯一種固定的編碼, 極大地提升了 Redis 的靈活性和效率, 因為 Redis 可以根據不同的使用場景來為一個對象設置不同的編碼, 從而優化對象在某一場景下的效率。

字符串對象

字符串對象的編碼可以是?int?、?raw?或者?embstr?。

如果一個字符串對象保存的是整數值, 并且這個整數值可以用?long?類型來表示, 那么字符串對象會將整數值保存在字符串對象結構的?ptr屬性里面(將?void*?轉換成?long?), 并將字符串對象的編碼設置為?int?。

如果字符串對象保存的是一個字符串值, 并且這個字符串值的長度大于?39?字節, 那么字符串對象將使用一個簡單動態字符串(SDS)來保存這個字符串值, 并將對象的編碼設置為?raw?。

如果字符串對象保存的是一個字符串值, 并且這個字符串值的長度小于等于?39?字節, 那么字符串對象將使用?embstr?編碼的方式來保存這個字符串值。

embstr?編碼是專門用于保存短字符串的一種優化編碼方式, 這種編碼和?raw?編碼一樣, 都使用?redisObject?結構和?sdshdr?結構來表示字符串對象,但?raw?編碼會調用兩次內存分配函數來分別創建?redisObject?結構和?sdshdr?結構,而?embstr?編碼則通過調用一次內存分配函數來分配一塊連續的空間, 空間中依次包含?redisObject?和?sdshdr?兩個結構。

?embstr?編碼有以下好處:

  1. embstr?編碼創建刪除字符串對象只需操作一次內存
  2. 因為數據都保存在一塊連續的內存, 所以這種編碼的字符串對象比?raw?編碼字符串對象能更好地利用緩存帶來的優勢。

列表對象

列表對象的編碼可以是?ziplist?或者?linkedlist?。

當列表對象可以同時滿足以下兩個條件時, 列表對象使用?ziplist?編碼:

  1. 列表對象保存的所有字符串元素的長度都小于?64?字節;
  2. 列表對象保存的元素數量小于?512?個;

不能滿足這兩個條件的列表對象需要使用?linkedlist?編碼。

哈希對象

哈希對象的編碼可以是?ziplist?或者?hashtable?。

當哈希對象可以同時滿足以下兩個條件時, 哈希對象使用?ziplist?編碼:

  1. 哈希對象保存的所有鍵值對的鍵和值的字符串長度都小于?64?字節;
  2. 哈希對象保存的鍵值對數量小于?512?個;

不能滿足這兩個條件的哈希對象需要使用?hashtable?編碼。

集合對象

集合對象的編碼可以是?intset?或者?hashtable?。

當集合對象可以同時滿足以下兩個條件時, 對象使用?intset?編碼:

  1. 集合對象保存的所有元素都是整數值;
  2. 集合對象保存的元素數量不超過?512?個;

不能滿足這兩個條件的集合對象需要使用?hashtable?編碼。

有序集合對象

有序集合的編碼可以是?ziplist?或者?skiplist?。

當有序集合對象可以同時滿足以下兩個條件時, 對象使用?ziplist?編碼:

  1. 有序集合保存的元素數量小于?128?個;
  2. 有序集合保存的所有元素成員的長度都小于?64?字節;

不能滿足以上兩個條件的有序集合對象將使用?skiplist?編碼。

這里多說兩句,各個語言的對象其實都差不多,底層實現也就那幾個,比如java中的容器,c++的STL。java的hashset就是一個哈希而已,hashmap就是k帶了一個v,而”有序的“Treemap使用了紅黑樹這種有平衡性的搜索二叉樹。

redis的有序集合并沒有再采取hash+紅黑樹的操作,而是把平衡樹換成了跳表,實際上性能真的沒差多少,甚至有時比紅黑樹有優勢,比如跳表的性能較為平均,紅黑樹攢了很多次不平衡要調整可能會帶來資源需求的一個高峰,再加上跳表實現簡單的優點,紅黑樹真的沒什么優勢。

并且就算是真的想用一種帶平衡性的搜索樹,現在競賽也是用的華人之光發明的SB樹。

有序集合的優點就是它的有序操作,比如拿最大最小值,紅黑樹時間o(logN),而哈希表只能一個一個遍歷。缺點在于插入一個值的時間也是o(logN),跳表也是。而哈希表插入數是o(1).

要了解底層和這些優缺點

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445406.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445406.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445406.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

劍指offer(刷題31-40)--c++,Python版本

文章目錄目錄第31 題:解題思路:代碼實現:cpython第32題:解題思路:代碼實現:cpython第33題:解題思路:代碼實現:cpython第34題:解題思路:代碼實現&a…

redis——數據庫

redis服務器將所有數據庫都保存在redis/redisServer中,數組db存放所有數據庫,每一項是一個redisdb結構。dbnum代表數據庫數量。 客戶端有一個指針指向當前數據庫,可以切換,也就是移動指針。 鍵空間 現在稍微介紹一下redisdb結構…

劍指offer(刷題41-50)--c++,Python版本

文章目錄目錄第41題:解題思路:代碼實現:cpython第42題:解題思路:代碼實現:cpython第43題:解題思路:代碼實現:cpython第44題:解題思路:代碼實現&am…

redis——持久化

因為redis是內存數據庫,他把數據都存在內存里,所以要想辦法實現持久化功能。 RDB RDB持久化可以手動執行,也可以配置定期執行,可以把某個時間的數據狀態保存到RDB文件中,反之,我們可以用RDB文件還原數據庫…

redis原理總結

數據結構(字典、鏈表、字符串) 數據結構(整數集合,壓縮列表) 數據結構(跳表介紹和手撕) LRU介紹和實現 對象(字符串對象、列表對象、哈希對象、集合對象、有序集合總結&#xff…

劍指offer(刷題51-60)--c++,Python版本

文章目錄目錄第51題:解題思路:代碼實現:cpython第52題:解題思路:代碼實現:cpython第53題:解題思路:代碼實現:cpython第54題:解題思路:代碼實現&am…

2017第一屆河北省大學生程序設計競賽題解

超級密碼 小明今年9歲了,最近迷上了設計密碼!今天,他又設計了一套他認為很復雜的密碼,并且稱之為“超級密碼”. 說實話,這套所謂的“超級密碼”其實并不難:對于一個給定的字符串,你只要提取其中…

劍指offer(刷題61-65)--c++,Python版本

文章目錄目錄第61題:解題思路:代碼實現:cpython第62題:解題思路:代碼實現:cpython第63題:解題思路:代碼實現:cpython第64題:解題思路:代碼實現&am…

2018第二屆河北省大學生程序設計競賽題解

icebound的賬單 題目描述 icebound從小就有記賬的習慣。又到了月末icebound統計資金狀況的時候。icebound每個月除了不停的揮霍以外,有時他會良心發現,勤工儉學,因此會有一些微薄的收入。然而icebound數學不好,需要你來幫助他統計…

大數的四則運算(加法、減法、乘法、除法)

大數的四則運算(加法、減法、乘法、除法) 前言: 在計算機中數字表示的范圍是有限制的,比如我們熟知的 int、float、double 等數據類型所能表示的范圍都是有限的,如果我們要對位數達到幾十位、幾百位、上千位的大整數進…

數組基操三連(1)

題目: 給定一個數組arr,求出需要排序的最短子數組長度 要求: 時間o(n),空間o(1) 思路: 有序的數組中,任意一個數字,一定小于左邊的數大于右邊的數。 我們找到的需要排序的子數組,顯然是比右邊…

IT互聯網公司的筆試的輸入輸出- c++ python

文章目錄目錄c方式1&#xff1a;方式2&#xff1a;Python方式1&#xff1a;方式2&#xff1a;方式3&#xff1a;目錄 c 方式1&#xff1a; 第一種情況&#xff1a;輸入n個數&#xff0c;存放在數組中 #include <iostream> #include <vector> using namespace st…

隨機過程1

隨機過程1概述1.參考書目2.主要內容3.概率論--基本概念回顧3.1對“不確定性”的認識3.2 應對“不確定性”應該怎么做3.3隨機變量&#xff08;Random Variable&#xff09;3.4分布函數&#xff08;Distribution Function&#xff09;3.5概率密度&#xff08;Density&#xff09;…

數組基操三連(4)

題目一 給定一個長度為N的整型數組arr&#xff0c;其中有N個互不相等的自然數1~N 請實現arr的排序 但是不要把下標0~N-1位置上的數值通過直接賦值的方式替換成1~N。 要求&#xff1a;時間復雜度為O(N)&#xff0c;額外空間復雜度為O(1)。 思路&#xff1a;從左向右檢查&…

Linux(1)-touch,mkdir,rm,mv,cp,ls,cd,cat

Linux1-實用終端命令1. touch, mkdir2. rm, mv, cp3. ls(通配符),cd(絕對/相對路徑)4. cat, more/less文件內容瀏覽文件/目錄-增刪查改, 文件內容查看.1. touch, mkdir touch新文件 &#xff1a;在當前文件夾下&#xff0c;創建文件。文件不存在則創建新文件&#xff1b;文件存…

java常用類介紹及源碼閱讀(ArrayList)

java.util 類 ArrayList<E> 繼承關系&#xff1a; java.lang.Objectjava.util.AbstractCollection<E>java.util.AbstractList<E>java.util.ArrayList<E>List 接口的動態數組的實現。 實現了所有可選列表操作&#xff0c;并允許包括 null 在內的所有…