redis 系列5 數據結構之字典(上)

来源:https://www.cnblogs.com/MrHSR/archive/2018/11/04/9889117.html
-Advertisement-
Play Games

一. 概述 字典又稱符號表(symbol table),關聯數組(associative array), 映射(map),是一種用於保存鍵值對(key-value pair)的抽象數據結構。在字典中,一個key和一個value進行關聯稱為鍵值對。在字典中每個鍵都是唯一的,程式可以在字典中根據鍵查找關 ...


一. 概述

  字典又稱符號表(symbol table),關聯數組(associative array), 映射(map),是一種用於保存鍵值對(key-value pair)的抽象數據結構。在字典中,一個key和一個value進行關聯稱為鍵值對。在字典中每個鍵都是唯一的,程式可以在字典中根據鍵查找關聯的值,或通過鍵更新刪除值等操作。在C語言中並沒有內置這種數據結構,因此Redis構建了自己的字典實現。在Redis中應用廣泛, 對資料庫的增,刪,查,改 都是構建在對字典的操作之上的。

-- 例1
127.0.0.1:6379> set msg "hello world"
OK
127.0.0.1:6379> get msg
"hello world"

  在例1中資料庫創建一個鍵為"msg",值為"hello world"的鍵值對,這個鍵值對就是保存在資料庫的字典裡面。字典還是哈希鍵的底層實現之一,當哈希鍵包含的鍵值對比較多,或者鍵值對中的元素都是比較長的字元串時,Redis就會使用字典作為哈希鍵的底層實現。

-- 例2: website是一個包含3個鍵值對的哈希鍵(也叫哈希表),哈希鍵(key)為 website,哈希鍵的節點鍵是:資料庫名字,哈希鍵的節點值是:網址
    127.0.0.1:6379> hmset website redis "Redis.io" mariadb "mariadb.org" mongodb "mongodb.org" 
OK
127.0.0.1:6379> hlen website
(integer) 3
127.0.0.1:6379> hgetall website
1) "redis"
2) "Redis.io"
3) "mariadb"
4) "mariadb.org"
5) "mongodb"
6) "mongodb.org"

  在例2中,website哈希鍵的底層實現就是一個字典。字典中包含了3個鍵值對。字典除了用來實現資料庫和哈希鍵之處,Redis在後續學習中會看到各種不同應用。

 

二. 字典的實現

   一個哈希(鍵)表裡面可以有多個哈希節點(key-vlaue), 每個哈希節點保存了字典的一個鍵值對。下麵三個小節將分別介紹Redis的哈希表,哈希表節點,以及字典的實現。

  2.1 哈希表定義

typedef struct dictht
      {
         //哈希表數組,C語言中,*號是為了表明該變數為指針,有幾個* 號就相當於是幾級指針,這裡是二級指針,理解為指向指針的指針
         dictEntry **table;

         //哈希表大小
         unsigned long size;

         //哈希表大小掩碼,用於計算索引值
         unsigned long sizemask;

         //該哈希已有節點的數量
          unsigned long used;

      }dictht;

    上面table屬性是一個數組,數組中的每個元素都是一個指向dict.h/dictEntry結構的指針,每個dictEntry結構保存著一個鍵值對,size屬性記錄了哈希表的大小,也是table數組的大小,而used屬性則記錄哈希表目前已有節點(鍵值對)的數量。sizemask屬性的值總是等於 size-1(從0開始),這個屬性和哈希值一起決定一個鍵應該被放到table數組的哪個索引上面。

    例如:上面例2中,哈希表叫website,  對應一個dictht 結構,鍵值對table數組值是[3], 哈希表size值是3,索引值sizemask值是2,已有節點數量used值是3。

  2.2 哈希表節點定義 (鍵值對)

//哈希表節點定義dictEntry結構表示,每個dictEntry結構都保存著一個鍵值對。
    typedef struct dictEntry
      {
         //
         void *key;
         //
         union{
           void *val;
            uint64_tu64;
            int64_ts64;
            }v;

         // 指向下個哈希表節點,形成鏈表
         struct dictEntry *next;
      }dictEntry;

    上面dictEntry 結構中,key屬性保存著鍵值中的鍵,而v屬性則保存著鍵值對中的值,其中鍵值(v屬性)可以是一個指針,或uint64_t整數,或int64_t整數。 next屬性是指向另一個哈希表節點的指針,這個指針可以將多個哈希值相同的鍵值對連接在一起,解決鍵衝突問題。

    下圖通過next指針,將兩個索引值相同(索引是2)的鍵k1和k0連接在一起。

  2.3 字典定義

// Redis中的字典由dict.h/dict結構表示
          typedef struct dict
      {
         //類型特定函數
         void *type;

         //私有數據
         void *privdata;

         //哈希表
         dictht ht[2];

         // rehash 索引
         int  trehashidx; 
      }dict;

     type屬性和privdata屬性是針對不同類型的鍵值對,為創建多態字典而設置的,type屬性是一個指向dictType結構的指針,每個dictType用於操作特定類型鍵值對的函數,Redis會為用途不同的字典設置不同的類型特定函數。 而privdata屬性則保存了需要傳給給那些類型特定函數的可選參數。

 typedef struct dictType
      {
         //計算哈希值的函數 
        unsigned int  (*hashFunction) (const void *key);

         //複製鍵的函數
         void *(*keyDup) (void *privdata,const void *key);

         //複製值的函數
         void *(*keyDup) (void *privdata,const void *obj);

          //複製值的函數
         void *(*keyCompare) (void *privdata,const void *key1, const void *key2);

         //銷毀鍵的函數
         void (*keyDestructor) (void *privdata, void *key);

         //銷毀值的函數
         void (*keyDestructor) (void *privdata, void *obj);
      }dictType;
View Code

    ht屬性是一個包含兩個項的數組,數組中的每個項都是一個dictht哈希表, 一般情況下,字典只使用ht[0] 哈希表, ht[1]哈希表只會對ht[0] 哈希表進行rehash時使用。另一個和rehash有關的屬性是rehashidx,它記錄了rehash目前的進度,如果目前沒有進行rehash,值為-1。下麵圖是一個沒有進行rehash的字典。

  rehash是指漸進式的哈希,一張表是舊表,一張表是新表,當hashtable的大小需要動態改變的時候,舊表中的元素就往新開闢的新表中遷移,當下一次變動大小,當前的新表又變成了舊表,以此達到資源的復用和效率的提升。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • linux中創建目錄當然使用命令工具mkdir == (make directory),聯想記憶法能讓你記得牢固。 如果你要創建幾個目錄,例如:dir1目錄,dir2目錄,dir3目錄可以這樣 怎麼樣?很不錯吧!再見~~~ ...
  • 2018-11-05 00:06:15開始寫 要配置2個MySQL環境變數 1.MYSQL_HOME: 2.PATH: 謝謝、Thank you、Salamat Do(撒拉瑪特朵)、あリがCám o*n(嘉蒙)とゥ(阿裡嘎都)、감사합 니다 (勘三哈咪瘩)、terima Kasih(得力馬卡系)、k ...
  • 一、關於安裝 SQL Server 資料庫的安裝,經過自己的安裝,總體還是比較容易,沒有太多難度,安裝包在網上也有很多,在此,就跳過安裝的這一步。 二、初次啟動SQL Server 安裝完成資料庫後,如果不啟動SQL Server的服務,是登錄不了資料庫的。啟動服務有三種方式啟動,具體如下。 1、“ ...
  • 關於SQL Server 2008 想起關於SQL Server 2008的故事,曾經在大一的時候跟著視頻學習過一段時間,那時因為想多學習一些技術,才去學,遺憾的是,曾經是三分熱度,沒學多久就被扔掉了,如今再次撿起來,重新學習,並且想要樹立長久的學習態度,在今後的學習中,要及時的把學習的內容更新到這 ...
  • 1、儘可能的早做選擇和投影,可使中間結果變小,節省幾個數量級的時間 2、把選擇和投影串接起來,一元運算序列可以一起執行,只需對整個關係掃描一遍 3、把投影與其前或後的二元運算結合起來,在第一次用關係時去掉一些屬性,可以避免多次掃描整個關係 4、把某些選擇與其前的笛卡兒積合併成一個連接,當R*S有選擇 ...
  • 一、 使用create關鍵字創建表 --(1)創建新表use 資料庫(在那個資料庫中建表)create table 表名(欄位名1(列名) 數據類型 列的特征,欄位名2(列名) 數據類型 列的特征(NOT NULL),......)--(2)創建帶有主鍵約束的表語法create table 表名(字 ...
  • 2018-11-04 19:35:12 開始寫 刷新後就可以看見導入的資料庫了(按F5刷新) 謝謝、Thank you、Salamat Do(撒拉瑪特朵)、あリがCám o*n(嘉蒙)とゥ(阿裡嘎都)、감사합니다 (勘三哈咪瘩)、terima Kasih(得力馬卡系)、kob-khun(寇布庫恩)、 ...
  • 資料庫 1. 資料庫伺服器:運行資料庫管理軟體的電腦 2. 資料庫管理軟體:mysql,oracle,db2,sqlserver 3. 庫:文件夾 4. 表:文件 5. 記錄:食物一系列典型的特征 6. 數據:描述事物特征的符號 資料庫的分類: 關係型:sqllite,db2,oracle,acc ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...