Redis常用的五種數據類型
String (Key-Value)
String是最常用的一種數據類型,普通的key/value存儲都可以歸爲此類。
一個Key對應一個Value,string類型是二進制安全的。
Redis的string可以包含任何數據,比如jpg圖片(生成二進制)或者序列化的對象。
基本操作如下:
- //基本數據類型
- 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 類型。一個對象存儲在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,一列存順序 |