Redis學習筆記~關(guan)于空間換時間的(de)查詢(xun)案例
空間與時間
空間(jian)換(huan)時(shi)(shi)間(jian)是(shi)(shi)在(zai)(zai)數(shu)(shu)(shu)(shu)據(ju)庫中經常出現(xian)的(de)(de)(de)(de)術語,簡(jian)單說(shuo)(shuo)就(jiu)是(shi)(shi)把(ba)查(cha)詢需要(yao)(yao)的(de)(de)(de)(de)條件進行索(suo)引的(de)(de)(de)(de)存(cun)儲(chu),然后查(cha)詢時(shi)(shi)為O(1)的(de)(de)(de)(de)時(shi)(shi)間(jian)復(fu)雜(za)度來(lai)快(kuai)速獲取(qu)數(shu)(shu)(shu)(shu)據(ju),從而達到了使(shi)用空間(jian)存(cun)儲(chu)來(lai)換(huan)快(kuai)速的(de)(de)(de)(de)時(shi)(shi)間(jian)響應!對于(yu)redis這(zhe)(zhe)個(ge)(ge)k/v存(cun)儲(chu)系統來(lai)說(shuo)(shuo),復(fu)雜(za)的(de)(de)(de)(de)查(cha)詢不(bu)(bu)(bu)是(shi)(shi)它(ta)所(suo)建(jian)議的(de)(de)(de)(de),它(ta)的(de)(de)(de)(de)優勢在(zai)(zai)于(yu)通過(guo)key快(kuai)速定(ding)位(wei)(wei)數(shu)(shu)(shu)(shu)據(ju),它(ta)定(ding)位(wei)(wei)數(shu)(shu)(shu)(shu)據(ju)的(de)(de)(de)(de)速度與數(shu)(shu)(shu)(shu)據(ju)多少(shao)沒有直接(jie)關系,無論是(shi)(shi)1萬還(huan)(huan)是(shi)(shi)1億數(shu)(shu)(shu)(shu)據(ju),它(ta)定(ding)位(wei)(wei)的(de)(de)(de)(de)時(shi)(shi)間(jian)復(fu)雜(za)度都是(shi)(shi)O(1),而在(zai)(zai)實際使(shi)用中,可(ke)能(neng)不(bu)(bu)(bu)簡(jian)單使(shi)用key定(ding)位(wei)(wei)數(shu)(shu)(shu)(shu)據(ju)就(jiu)夠了,可(ke)能(neng)還(huan)(huan)需要(yao)(yao)數(shu)(shu)(shu)(shu)據(ju)里的(de)(de)(de)(de)某個(ge)(ge)屬性去定(ding)位(wei)(wei)數(shu)(shu)(shu)(shu)據(ju),這(zhe)(zhe)種(zhong)情況第一感覺(jue)不(bu)(bu)(bu)能(neng)用redis,或者說(shuo)(shuo),不(bu)(bu)(bu)能(neng)用k/v存(cun)儲(chu)系統了,但這(zhe)(zhe)不(bu)(bu)(bu)是(shi)(shi)我(wo)們(men)(men)應該(gai)說(shuo)(shuo)的(de)(de)(de)(de),我(wo)們(men)(men)要(yao)(yao)的(de)(de)(de)(de)是(shi)(shi)解(jie)決(jue)方案,換(huan)個(ge)(ge)角(jiao)度去思考,我(wo)們(men)(men)是(shi)(shi)否可(ke)以(yi)把(ba)那個(ge)(ge)屬性拿出來(lai)當(dang)新的(de)(de)(de)(de)key,把(ba)原來(lai)的(de)(de)(de)(de)key當(dang)作(zuo)它(ta)的(de)(de)(de)(de)value呢,答案是(shi)(shi)肯定(ding)的(de)(de)(de)(de),這(zhe)(zhe)就(jiu)是(shi)(shi)用空間(jian)到換(huan)時(shi)(shi)間(jian),只需要(yao)(yao)兩個(ge)(ge)查(cha)詢就(jiu)可(ke)以(yi)搞定(ding)了!
上面(mian)是(shi)(shi)一個100萬的hash集合,key是(shi)(shi)用(yong)戶id,value是(shi)(shi)一個用(yong)戶實體,我們通過(guo)RedisClient.RedisManager.Instance.GetDatabase().HashGet("VoteList", id)很方(fang)便的可以拿到對(dui)應的用(yong)戶實體!
我希望通過用戶名拿到用戶實體?
這種需求,我(wo)們不要直接解(jie)決(jue),如(ru)果直接解(jie)決(jue),那唯一的辦法就(jiu)是(shi)遍歷所有數據,然后一一對比,時間復雜度就(jiu)是(shi)O(N),太可怕了(le)!
通過添加(jia)新的(de)k/v,解(jie)決這個問(wen)題(ti),這類(lei)似于關系數據(ju)庫里的(de)全表(biao)掃描+索引技(ji)術(shu)!
實現程序:先通過userName找(zhao)到UserId,再通過UserId找(zhao)到用(yong)戶實體!
[TestMethod] public void FindBigData() { Stopwatch sw = new Stopwatch(); sw.Start(); var name = RedisClient.RedisManager.Instance.GetDatabase().HashGet("VoteList_UserName", "zzl15");//找到用戶ID if (name.HasValue) { var val = RedisClient.RedisManager.Instance.GetDatabase().HashGet("VoteList", name);//找到用戶實體 Console.WriteLine("name={0},value={1}", name, val); } else { Console.WriteLine("沒有發現(xian)這個Key"); } sw.Stop(); Console.WriteLine("查詢(xun)需要的時間:" + sw.ElapsedMilliseconds + "ms"); }
通(tong)過這個實例讓我們(men)知道,做(zuo)成(cheng)一(yi)件事,可能一(yi)步(bu)不行,但(dan)多幾(ji)步(bu)一(yi)定可以實現!