国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

菜鳥爬坑--Redis學(xué)習(xí)與探索(二):Redis的數(shù)據(jù)類型

2019-11-14 16:09:45
字體:
供稿:網(wǎng)友

.NET使用Redis

和MongoDB一樣,在.NET中使用Redis其實(shí)也是使用第三方驅(qū)動(dòng),官網(wǎng)推薦的是使用ServiceStack.Redis 

不過看CapQueen的博客時(shí),有提到ServiceStack.Redis 4.0開始收費(fèi)了,3.9功能不是特別全,一些地方存在不足。而使用了 StactkExchange.Redis ,具體以后詳細(xì)研究,這里還是使用了ServiceStack.Redis 。 

點(diǎn)擊下載壓縮包,解壓 ServiceStack.Redis-master.zip/ServiceStack.Redis-master/build/release/MonoDevelop  下的ServiceStack.Redis.zip 壓縮包 

會(huì)有4個(gè)dll,我們直接在項(xiàng)目中添加引用即可。

Redis數(shù)據(jù)類型

Redis目前提供五種數(shù)據(jù)類型:string(字符串)、list(鏈表)、Hash(哈希)、set(集合)及zset(sorted set)  (有序集合)。下面我們來一一實(shí)踐一下。

String類型

String是最常用的一種數(shù)據(jù)類型,普通的key/value存儲(chǔ)都可以歸為此類。一個(gè)Key對(duì)應(yīng)一個(gè)Value,string類型是二進(jìn)制安全的。Redis的string可以包含任何數(shù)據(jù),比如jpg圖片(生成二進(jìn)制)或者序列化的對(duì)象。

示例:

 1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7  8 namespace String 9 {10     class PRogram11     {12         static void Main(string[] args)13         {14             RedisClient client = new RedisClient("127.0.0.1", 6379);15             Console.WriteLine("請(qǐng)輸入用戶名:");16             string username = Console.ReadLine();17             client.Set<string>("username", username);18         19             int exist=client.Exists("username");20             Console.WriteLine("是否添加到Redis:" + exist.ToString());// 存在返回1,否則返回021           22             username = client.Get<string>("username");23             Console.WriteLine("獲取剛剛輸入用戶名:" + username);24 25             int a= client.Del("username");//刪除已存在的key 成功返回126             int b = client.Del("username2");//刪除不存在的key,失敗返回027             Console.WriteLine("輸出刪除結(jié)果:" +a.ToString()+","+b.ToString());28             Console.ReadKey();29         }30     }31 }
View Code

 

Hash類型

hash是一個(gè)string 類型的field和value的映射表。hash特別 適合存儲(chǔ)對(duì)象。相對(duì)于將對(duì)象的每個(gè)字段存成單個(gè)string 類型。一個(gè)對(duì)象存儲(chǔ)在hash類型中會(huì)占用更少的內(nèi)存,并且可以更方便的存取整個(gè)對(duì)象。省內(nèi)存的原因是新建一個(gè)hash對(duì)象時(shí)開始是用zipmap(又稱為small hash)來存儲(chǔ)的。這個(gè)zipmap其實(shí)并不是hash table,但是zipmap相比正常的hash實(shí)現(xiàn)可以節(jié)省不少hash本身需要的一些元數(shù)據(jù)存儲(chǔ)開銷。盡管zipmap的添加,刪除,查找都是O(n),但是由于一般對(duì)象的field數(shù)量都不太多。所以使用zipmap也是很快的,也就是說添加刪除平均還是O(1)。如果field或者value的大小超出一定限制后,redis會(huì)在內(nèi)部自動(dòng)將zipmap替換成正常的hash實(shí)現(xiàn). 這個(gè)限制可以在配置文件中指定。

如上圖。Redis的Hash實(shí)際是內(nèi)部存儲(chǔ)的Value為一個(gè)HashMap,這個(gè)HashMap的key是成員的屬性名,value是屬性值,這樣對(duì)數(shù)據(jù)的修改和存取都可以直接通過其內(nèi)部HashMap的Key(Redis里稱內(nèi)部HashMap的key為field), 也就是通過key(用戶ID) + field(屬性標(biāo)簽) 就可以操作對(duì)應(yīng)屬性數(shù)據(jù)了。

示例:

 1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7  8 namespace String 9 {10     class Program11     {12         static void Main(string[] args)13         {14             RedisClient client = new RedisClient("127.0.0.1", 6379);15             Console.WriteLine("請(qǐng)輸入用戶名:");16             string username = Console.ReadLine();17             Console.WriteLine("請(qǐng)輸入密碼:");18             string passWord = Console.ReadLine();19             client.SetEntryInHash("userinfo", "username", username);20             client.SetEntryInHash("userinfo", "password", password);21             List<string> keylist = client.GetHashKeys("userinfo");22             List<string> valuelist = client.GetHashValues("userinfo");23             for (int i = 0; i < keylist.Count; i++) 24             {25                 Console.WriteLine("key為:{0},value為:{1}", keylist[i], valuelist[i]);26             }27             Console.ReadKey();28         }29     }30 }
View Code

List類型

list是一個(gè)鏈表結(jié)構(gòu),主要功能是push,pop,獲取一個(gè)范圍的所有的值等,操作中key理解為鏈表名字。 Redis的list類型其實(shí)就是一個(gè)每個(gè)子元素都是string類型的雙向鏈表。我們可以通過push,pop操作從鏈表的頭部或者尾部添加刪除元素,這樣list既可以作為棧,又可以作為隊(duì)列。

Redis list的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷,Redis內(nèi)部的很多實(shí)現(xiàn),包括發(fā)送緩沖隊(duì)列等也都是用的這個(gè)數(shù)據(jù)結(jié)構(gòu)。
示例:
 1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7  8 namespace String 9 {10     class Program11     {12         static void Main(string[] args)13         {14             RedisClient client = new RedisClient("127.0.0.1", 6379);15             Console.WriteLine("請(qǐng)輸入第一個(gè)數(shù):");16             string num1 = Console.ReadLine();17             Console.WriteLine("請(qǐng)輸入第二個(gè)數(shù):");18             string num2 = Console.ReadLine();19             //隊(duì)列20             client.EnqueueItemOnList("queue", num1);21             client.EnqueueItemOnList("queue", num2);22             int Qcount = client.GetListCount("queue");23             Console.WriteLine("輸出隊(duì)列:");24             for (int i = 0; i < Qcount; i++)25             {26                 Console.Write(client.DequeueItemFromList("queue")+",");27             }28             Console.WriteLine("/n");29             //30             client.PushItemToList("stack", num1);31             client.PushItemToList("stack", num2);32             int Scount = client.GetListCount("stack");33             Console.WriteLine("輸出棧:");34             for (int i = 0; i < Scount; i++)35             {36                 Console.Write(client.PopItemFromList("stack") + ",");37             }38             Console.ReadKey();39         }40     }41 }
View Code

看以看出隊(duì)列是FIFO,先入先出,而隊(duì)列是LIFO,后入先出,具體的等后續(xù)有時(shí)間來填填數(shù)據(jù)結(jié)構(gòu)的坑。

Redis鏈表經(jīng)常會(huì)被用于消息隊(duì)列的服務(wù),以完成多程序之間的消息交換。假設(shè)一個(gè)應(yīng)用程序正在執(zhí)行LPUSH操作向鏈表中添加新的元素,我們通常將這樣的程序稱之為"生產(chǎn)者(Producer)",而另外一個(gè)應(yīng)用程序正在執(zhí)行RPOP操作從鏈表中取出元素,我們稱這樣的程序?yàn)?消費(fèi)者(Consumer)"。如果此時(shí),消費(fèi)者程序在取出消息元素后立刻崩潰,由于該消息已經(jīng)被取出且沒有被正常處理,那么我們就可以認(rèn)為該消息已經(jīng)丟失,由此可能會(huì)導(dǎo)致業(yè)務(wù)數(shù)據(jù)丟失,或業(yè)務(wù)狀態(tài)的不一致等現(xiàn)象的發(fā)生。然而通過使用RPOPLPUSH命令,消費(fèi)者程序在從主消息隊(duì)列中取出消息之后再將其插入到備份隊(duì)列中,直到消費(fèi)者程序完成正常的處理邏輯后再將該消息從備份隊(duì)列中刪除。同時(shí)我們還可以提供一個(gè)守護(hù)進(jìn)程,當(dāng)發(fā)現(xiàn)備份隊(duì)列中的消息過期時(shí),可以重新將其再放回到主消息隊(duì)列中,以便其它的消費(fèi)者程序繼續(xù)處理。

Set類型

 在Redis中,我們可以將Set類型看作為沒有排序的字符集合,和List類型一樣,我們也可以在該類型的數(shù)據(jù)值上執(zhí)行添加、刪除或判斷某一元素是否存在等操作。需要說明的是,這些操作的時(shí)間復(fù)雜度為O(1),即常量時(shí)間內(nèi)完成次操作。Set可包含的最大元素?cái)?shù)量是4294967295。
      和List類型不同的是,Set集合中不允許出現(xiàn)重復(fù)的元素,這一點(diǎn)和C++標(biāo)準(zhǔn)庫中的set容器是完全相同的。換句話說,如果多次添加相同元素,Set中將僅保留該元素的一份拷貝。和List類型相比,Set類型在功能上還存在著一個(gè)非常重要的特性,即在服務(wù)器端完成多個(gè)Sets之間的聚合計(jì)算操作,如unions、intersections和differences。由于這些操作均在服務(wù)端完成,因此效率極高,而且也節(jié)省了大量的網(wǎng)絡(luò)IO開銷。

示例:

 1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7  8 namespace String 9 {10     class Program11     {12         static void Main(string[] args)13         {14             RedisClient client = new RedisClient("127.0.0.1", 6379);15             client.AddItemToSet("a", "aaaa1");16             client.AddItemToSet("a", "aaaa2");17             client.AddItemToSet("a", "aaaa3");18             Console.WriteLine("輸出Set a:");19             System.Collections.Generic.HashSet<string> hashset = client.GetAllItemsFromSet("a");20             foreach (string str in hashset)21             {22                 Console.WriteLine(str);23             }24 25             Console.ReadKey();26         }27     }28 }
View Code

可以看出 Set 是無序的。

我們也可以對(duì)多個(gè)Set進(jìn)行聚合等操作

例如:

            System.Collections.Generic.HashSet<string> hashset = client.GetUnionFromSets(new string[] { "a", "b" });//求并集            hashset = client.GetIntersectFromSets(new string[] { "a", "b" });//求交集            hashset = client.GetDifferencesFromSet("a", new string[] { "b" });//求差集

應(yīng)用場(chǎng)景:     

      1). 可以使用Redis的Set數(shù)據(jù)類型跟蹤一些唯一性數(shù)據(jù),比如訪問某一博客的唯一IP地址信息。對(duì)于此場(chǎng)景,我們僅需在每次訪問該博客時(shí)將訪問者的IP存入Redis中,Set數(shù)據(jù)類型會(huì)自動(dòng)保證IP地址的唯一性。
      2). 充分利用Set類型的服務(wù)端聚合操作方便、高效的特性,可以用于維護(hù)數(shù)據(jù)對(duì)象之間的關(guān)聯(lián)關(guān)系。比如所有購買某一電子設(shè)備的客戶ID被存儲(chǔ)在一個(gè)指定的Set中,而購買另外一種電子產(chǎn)品的客戶ID被存儲(chǔ)在另外一個(gè)Set中,如果此時(shí)我們想獲取有哪些客戶同時(shí)購買了這兩種商品時(shí),Set的intersections命令就可以充分發(fā)揮它的方便和效率的優(yōu)勢(shì)了。

 

Sorted Set類型

Sorted Set 是Set的一個(gè)升級(jí)版本,它在set的基礎(chǔ)上增加了一個(gè)順序的屬性,這一屬性在添加修改   .元素的時(shí)候可以指定,每次指定后,zset(表示有序集合)會(huì)自動(dòng)重新按新的值調(diào)整順序。可以理解為有列的表,一列存 value,一列存順序。操作中key理解為zset的名字.

示例:

 1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7  8 namespace String 9 {10     class Program11     {12         static void Main(string[] args)13         {14             RedisClient client = new RedisClient("127.0.0.1", 6379);15             client.AddItemToSortedSet("s", "123");16             client.AddItemToSortedSet("s", "456");17             client.AddItemToSortedSet("s", "789");18             client.AddItemToSortedSet("s", "1234");19             client.AddItemToSortedSet("s", "56789");20             System.Collections.Generic.List<string> list = client.GetAllItemsFromSortedSet("s");21             foreach (string str in list)22             {23                 Console.WriteLine(str);24             }25             Console.ReadKey();26         }27     }28 }
View Code

應(yīng)用場(chǎng)景:    

Redis sorted set的使用場(chǎng)景與set類似,區(qū)別是set不是自動(dòng)有序的,而sorted set可以通過用戶額外提供一個(gè)優(yōu)先級(jí)(score)的參數(shù)來為成員排序,并且是插入有序的,即自動(dòng)排序。當(dāng)你需要一個(gè)有序的并且不重復(fù)的集合列表,那么可以選擇sorted set數(shù)據(jù)結(jié)構(gòu)。

  1). 可以用于一個(gè)大型在線游戲的積分排行榜。每當(dāng)玩家的分?jǐn)?shù)發(fā)生變化時(shí),可以執(zhí)行ZADD命令更新玩家的分?jǐn)?shù),此后再通過ZRANGE命令獲取積分TOP TEN的用戶信息。當(dāng)然我們也可以利用ZRANK命令通過username來獲取玩家的排行信息。最后我們將組合使用ZRANGE和ZRANK命令快速的獲取和某個(gè)玩家積分相近的其他用戶的信息。
  2). Sorted-Sets類型還可用于構(gòu)建索引數(shù)據(jù)。

參考文獻(xiàn)

1.傳智播客-Redis公開課,感謝傳智播客

2.Stephen Liu的Redis學(xué)習(xí)手冊(cè)(目錄):http://m.survivalescaperooms.com/stephen-liu74/archive/2012/04/16/2370212.html


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 新津县| 抚顺市| 桃江县| 小金县| 青川县| 南昌县| 邳州市| 惠水县| 广昌县| 嘉祥县| 沙洋县| 富宁县| 徐州市| 开远市| 凤翔县| 泰州市| 寻甸| 永寿县| 黄大仙区| 衡水市| 上蔡县| 桃园市| 剑川县| 米泉市| 阿尔山市| 从化市| 麻栗坡县| 岑溪市| 南充市| 桑日县| 遵义市| 界首市| 福鼎市| 洪泽县| 永顺县| 尚义县| 多伦县| 九江县| 阳谷县| 定安县| 沙湾县|