Redis常用的五種資料類型
String (Key-Value)
String是最常用的一種資料類型,普通的key/value儲存都可以歸為此類。
一個Key對應一個Value,string類型是二進位安全的。
Redis的string可以包含任何資料,比如jpg圖片(產生二進位)或者序列化的對象。
基本操作如下:
//基礎資料型別 (Elementary Data Type)var client = new RedisClient("127.0.0.1", 6379);client.Set<int>("pwd", 1111);int pwd=client.Get<int>("pwd");Console.WriteLine(pwd);//對象UserInfo userInfo = new UserInfo() { UserName = "zhangsan", UserPwd = "1111" };//底層使用json序列化client.Set<UserInfo>("userInfo", userInfo);UserInfo user=client.Get<UserInfo>("userInfo");Console.WriteLine(user.UserName);//對象集合List<UserInfo> list = new List<UserInfo>() { new UserInfo(){UserName="lisi",UserPwd="111"},new UserInfo(){UserName="wangwu",UserPwd="123"} };client.Set<List<UserInfo>>("list",list);List<UserInfo>userInfoList=client.Get<List<UserInfo>>("list");foreach (UserInfo userInfo in userInfoList){Console.WriteLine(userInfo.UserName);}
Hash(Key-Value)
hash是一個string 類型的field和value的映射表。
hash特別適合儲存物件。相對於將對象的每個欄位存成單個string 類型。一個Object Storage Service在hash類型中會佔用更少的記憶體,並且可以更方便的存取整個對象。
Redis的Hash資料類型的value內部是一個HashMap,如果該Map的成員比較少,則會採用一維數組的方式來緊湊儲存該MAP,省去了大量指標的記憶體開銷,這個參數在redis.conf設定檔中下面2項。
Hash-max-zipmap-entries 64
Hash-max-zipmap-value 512.
含義是當value這個Map內部不超過多少個成員時會採用線性緊湊格式儲存,預設是64,即value內部有64個以下的成員就是使用線性緊湊儲存,超過該值自動轉成真正的HashMap.
Hash-max-zipmap-value含義是當value這個MAP內部的每個成員值長度不超過多少位元組就會採用線性緊湊儲存來節省空間的。以上兩個條件任意一個條件超過設定值都會轉成真正的HashMap,也就不會再節省記憶體了,這個值設定多少需要權衡,HashMap的優勢就是尋找和操作時間短。
採用key—field—value的方式。一個key可對應多個field,一個field對應一個value。這裡同時需要注意,Redis提供了介面(hgetall)可以直接取到全部的屬性資料,但是如果內部Map的成員很多,那麼涉及到遍曆整個內部Map的操作,由於Redis單執行緒模式的緣故,這個遍曆操作可能會比較耗時,而令其它用戶端的請求完全不響應,這點需要格外注意
建議使用物件類別和ID構成鍵名,使用欄位表示對象屬性,欄位值儲存屬性值,
對比
1. 採用String類型的儲存物件,需要將對象進行序列化。
增加了序列化/還原序列化的開銷,並且在需要修改其中一項資訊時,需要把整個對象取回。 2. 使用Hash資料類型則不需要
Key仍然是使用者ID, value是一個Map,這個Map的key是成員的屬性名稱,value是屬性值,這樣對資料的修改和存取都可以直接通過其內部Map的Key(Redis裡稱內部Map的key為field), 也就是通過 key(使用者ID) + field(屬性標籤) 就可以操作對應屬性資料了,既不需要重複儲存資料,也不會帶來序列化和還原序列化。
//SetEntryInHash key—field—value這種方式client.SetEntryInHash("userId", "userName", “changliang");List<string> list = client.GetHashKeys(“userId");List<string> list = client.GetHashValues("userName");//擷取值List<string> list = client.GetAllKeys();//擷取所有的key。
List
list是一個鏈表結構,主要功能是push, pop, 擷取一個範圍的所有的值等。操作中key理解為鏈表名字。 Redis的list類型其實就是一個每個子項目都是string類型的雙向鏈表。我們可以通過push,pop操作從鏈表的頭部或者尾部添加刪除元素,這樣list既可以作為棧,又可以作為隊列(棧就是insertFirst+deleteFirst,隊列就是insertLast+deleteFirst)。可以支援反向尋找和遍曆,方便操作,不過帶來了部分額外的記憶體開銷。Redis內部的很多實現,包括髮送緩衝隊列等也都是用的這個資料結構。
//隊列使用--入隊client.EnqueueItemOnList("name", "zhangsan");client.EnqueueItemOnList("name", "lisi");int count= client.GetListCount("name");for (int i = 0; i < count; i++){ Console.WriteLine(client.DequeueItemFromList("name"));}//棧使用--壓棧client.PushItemToList("name2", "wangwu");client.PushItemToList("name2", "maliu");int count = client.GetListCount("name2");for (int i = 0; i < count; i++){Console.WriteLine(client.PopItemFromList("name2"));}
Set
它是string類型的無序集合。set是通過hash table實現的,可以進行添加、刪除和尋找。對集合我們可以取並集,交集,差集.
集合可以進行 交集、並集 如新浪微博中擷取兩個使用者共同的關注人
新浪微博使用redis有兩種應用情境:
1. 直接把資料放到redis中進行儲存,這些資料是獨立的
2. 有些資料包含表與表之間的邏輯關係,這些資料又訪問比較頻繁,如果直接從資料庫中進行查詢效能比較差。先將資料寫到redis中,再將資料儲存到mysql資料庫
//對Set類型進行操作 集合名 後面可以放key-value對,也可以是基本類型client.AddItemToSet("a3", "ddd");client.AddItemToSet("a3", "ccc");client.AddItemToSet("a3", "tttt");client.AddItemToSet("a3", "sssh");client.AddItemToSet("a3", "hhhh");System.Collections.Generic.HashSet<string>hashset=client.GetAllItemsFromSet("a3");foreach (string str in hashset){Console.WriteLine(str);}求並集//集合1 a3集合client.AddItemToSet("a3", "ddd");client.AddItemToSet("a3", "ccc");client.AddItemToSet("a3", "tttt");client.AddItemToSet("a3", "sssh");client.AddItemToSet("a3", "hhhh");//集合2 a4集合client.AddItemToSet("a4", "hhhh");client.AddItemToSet("a4", "h777");System.Collections.Generic.HashSet<string>hashset= client.GetUnionFromSets(new string[] { "a3","a4"});foreach (string str in hashset){ Console.WriteLine(str);}//求交集System.Collections.Generic.HashSet<string> hashset = client.GetIntersectFromSets(new string[] { “a3”, “a4” });//求差集. //返回存在於第一個集合,但是不存在於其他集合的資料。差集 System.Collections.Generic.HashSet<string> hashset = client.GetDifferencesFromSet("a3",new string[] { "a4"});
zset
Redis sorted set的使用情境與set類似,區別是set不是自動有序的,而sorted set可以通過使用者額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。
可以理解為一列存 value,一列存順序。操作中key理解為zset的名字.
當你需要一個有序的並且不重複的集合列表,那麼可以選擇sorted set資料結構
//儲存插入時的順序,並放到集合a5中client.AddItemToSortedSet("a5","ffff");client.AddItemToSortedSet("a5","bbbb");client.AddItemToSortedSet("a5","gggg");client.AddItemToSortedSet("a5","cccc");client.AddItemToSortedSet("a5","waaa");System.Collections.Generic.List<string>list =client.GetAllItemsFromSortedSet("a5");foreach (string str in list){ Console.WriteLine(str);}
總結
資料類型 |
Key |
value |
String |
正常的key |
正常的value |
Hash |
正常的Key 如使用者ID |
HashMap(field,value) 代表對象 |
List |
鏈表名字 |
每個子項目都是string類型的雙向鏈表 |
Set |
Set名字 |
string類型的無序集合 |
Zset |
Zset名字 |
一列存 value,一列存順序 |