jsp 提交表單到 action 中文亂碼(GETPOST)
Redis系統裡一共有五種物件,包括字串物件,列表物件,雜湊物件,集合物件和有序集合物件。
每種物件的實現都比較靈活,可以根據不同的使用場景自由選擇之前講過的合適的資料結構(整數,字串,字典,雙端列表,壓縮列表,整數集合,跳躍表)
物件和型別和編碼
Redis中每一個物件都是由一個redisObject結構表示,該結構與儲存資料有關的三個屬性是type,encoding,ptr
typedef struct redisObject{ //物件的型別 unsigned type:4; //編碼 unsigned encoding:4; //指向底層實現資料結構的指標 void *ptr; ... }robj
每次使用set
命令在資料庫中建立鍵值對時,總是建立了兩個物件,其中鍵的物件型別總是一個字串物件
字串物件
字串物件的編碼可以是int,raw,embstr
如果一個字串物件儲存的是整數值,並且這個整數值可以用long型別來表示,那麼字串物件編碼就是int
如果一個字串物件儲存的是字串值,並且字串的長度大於39位元組,那麼字串物件使用一個簡單動態字串(SDS)來儲存這個字串值 ,並將編碼設定為raw
如果一個字串物件儲存的是字串值,並且字串的長度小於等於39位元組,那麼字串物件就使用embstr編碼的方式儲存這個字串值。
embstr編碼
embstr編碼是專門用來儲存短字串的一種優化方式,這種編碼和raw編碼一樣,都使用redisObject結構和sdshdr結構來表示字串物件,但是raw編碼會呼叫兩次記憶體分配函式來分別建立redisObject結構和sdshdr結構,而embstr會呼叫一次記憶體分配函式建立一塊連續的記憶體空間,空間中依次包含redisObject和sdshdr兩個結構。
編碼的轉換
對於int編碼型別的字串物件來說,如果執行APPEND
指令在整數值後追加了一個字串,那麼會將整數值轉化為字串值(raw或者embstr),然後再執行追加操作
對於embstr編碼的字串物件來說。embstr沒有編寫任何修改程式,因此embstr編碼的字串是隻讀的,如果要修改它的值,則需要先將物件的編碼從embstr轉化為raw,載執行修改
列表物件
列表物件的編碼可以是ziplist(壓縮列表)或者linkedlist(連結串列)
ziplist編碼的列表物件底層使用壓縮列表作為底層實現,每個壓縮列表節點儲存了一個列表元素。
linkedlist編碼的列表物件底層使用雙端連結串列作為底層實現,每個雙端連結串列節點都儲存了一個字串物件
注意,linkedlist編碼的列表物件在底層的雙端連結串列的結構中包含了多個字串物件,這種巢狀字串物件的行為在稍後介紹的雜湊物件,集合物件和有序集合物件中都會出現,字串物件是Redis五種型別的物件中唯一一種會被其他四種物件巢狀的物件。
編碼轉換
列表物件可以同時滿足一下兩個條件時,列表物件使用ziplist編碼:
- 列表物件儲存的所有字串元素的長度都小於64位元組
- 列表物件儲存的元素數量小於512個
不能滿足這兩個條件的列表物件使用linkedlist編碼
雜湊物件
雜湊物件的編碼可以是ziplist或hashtable
ziplist編碼的雜湊物件底層實現為壓縮列表。每當有新的鍵值對要加入到雜湊物件中,程式會先將儲存了鍵的壓縮列表節點推入到壓縮列表表尾,然後再將儲存了值的壓縮列表節點推入到壓縮列表表尾。因此:
- 儲存了同一鍵值對的兩個節點總是緊挨在一起,儲存鍵的節點在前,儲存值的節點在後。
- 先新增到雜湊物件中的鍵值對會被放在壓縮列表表頭方向,後新增的鍵值對會被放在壓縮列表表尾方向。
(查詢的效率退化為o(n))
hashtable編碼的雜湊物件使用字典作為底層實現,雜湊物件中的每一個鍵值對都使用一個字典鍵值對來儲存。
- 字典的每一個鍵都是一個字串物件,物件中儲存了鍵值對的鍵
- 字典的每一個值都是一個字串物件,物件中儲存了鍵值對的值
編碼轉換
當雜湊物件可以同時滿足以下兩個條件時,雜湊物件使用ziplist編碼:
- 雜湊物件儲存的所有鍵值對的鍵和值的字串長度都小於64位元組
- 雜湊物件儲存的鍵值對數量小於512個
不能滿足這兩個條件的雜湊物件使用hashtable編碼
我有一壺酒 足以慰風塵 盡傾江海里 贈飲天下人