Redis系列(六)-SortedSets設計技巧

來源:互聯網
上載者:User

標籤:

閱讀目錄:

  1. 介紹
  2. Score佔位
  3. 更多位資訊
  4. 總結
介紹

Redis Sorted Sets是類似Redis Sets資料結構,不允許重複項的String集合。不同的是Sorted Sets中的每個成員都分配了一個分數值(score),它用於在Sorted Sets中進行成員排序,從最小值到最大值。Sorted Sets中所有的成員都是唯一的,其分數(score)是可以重複的,即是說一個分數可能會對應多個值。

用Sorted Sets可以非常快的進行添加、刪除、或更新成員,其複雜度是O(m*log(n)),m是添加或查詢的成員數量。因為成員是按照順序添加的,所以可以非常快的通過score或者索引進行範圍查詢。訪問Sorted Sets中間的元素也是非常快的,因此可以用sort sets作為一個不重複的小型有序列表。 通過Sorted Sets可以快速控制項目任何你想做的事情:排序的成員,判斷成員是否在集合中,快速存取集合中間的成員。

如果多次添加相同的值到Sorted Sets上,redis會以最後一次的值分數為準。

總的來說,在其他資料庫比較難完成的任務,用Sorted Sets可以更快更優效能的完成。

更多Sorted Sets的用法可以查看官方文檔。

Score佔位

Sorted Sets中的Score是個64位整數類型,其範圍在-9007199254740992到9007199254740992之間,這是一個非常有用的關鍵點。

我們通常可以用它進行簡單的範圍查詢,比如把年齡當分數,通過ZRANGEBYSCORE查詢某個年齡段的所有使用者。
查詢18-35年齡的使用者:

ZRANGEBYSCORE user 18 35

如果有更複雜的需求,比如通過日期,使用者類型等來查詢,就比較困難了。 如果用其他資料結構的話,想查詢多條時就要多次往返操作,有效能上的損耗。 這裡可以用Score整數類型的長度特性,來儲存查詢的條件資訊。

比如有些資料需要通過日期範圍查詢,這是個很常見的情境。

使用Sorted Sets當儲存的資料結構,添加key時把日期進行簡單的轉碼。

一年有365天,在score中預留三位來儲存天份,通過DayOfYear計算出一年第多少天:

var time1=DateTime.Now.DayOfYear

因為第100天前的資料不滿三位,需要進行用0補全,寫個方法:

string AutoCompletion(int length, int num)    {        string str = num.ToString();        if (str.Length > length)            throw new Exception("max length");        var real = length - str.Length;        var sb = new StringBuilder(length);        for (int j = 0; j < real; j++)        {            sb.Append((char) 48);        }        sb.Append(str);        return sb.ToString();    }

因為資料的日期可能跨年,在天位前預留2位,儲存年份。現在長度是5位,如15200表示的是15年19號(第200天)。 

通過年份+天數計算出當前資料項目score的值。

var score= long.Parse(dateTime.Year.ToString().Substring(2, 2) + AutoCompletion(3, dateTime.DayOfYear));

把實際值和分數值儲存到redis裡面:

ZADD test socre value

查詢時把需要查詢的日期範圍轉換到分數,這裡查詢前10天的資料:

        int time1 = DateTime.Now.DayOfYear;        var score1 = AutoCompletion(time1, 2) + AutoCompletion(DateTime.Now.DayOfYear, 3);        int time2 = DateTime.Now.DayOfYear;        var score2 = AutoCompletion(time1, 2) + AutoCompletion(DateTime.Now.AddDays(-10).ToLocalTime().DayOfYear, 3);

在redis中查詢:

ZRANGEBYSCORE user score1 score2

查詢當天(分數)下的資訊:

ZRANGEBYSCORE user score2 score2 
更多位資訊

r64位整數類型有16個位置,意味著還可以儲存更多維度資訊。這裡以日期為主,在增加個類型維度,日期位置左移4位,預留4位來儲存類型維度。

如152003456,其3456四位是儲存類型的,可以根據類型種類的多少可以增加位或減少位佔用。

如果單純以日期來查詢時,類型不用傳,後面4位在查詢時補千位最小值和最大值即可。

查詢前10天的資料:

ZRANGEBYSCORE user 151900000 152009999

查詢15年19號3578類型的資料:

ZRANGEBYSCORE user 152003578 152003578 

查詢15年19號1000-4000類型的資料:

ZRANGEBYSCORE user 152001000 152004000

關於類型往往不是簡單的資料類型那麼簡單,可以做個簡單的mapping表。

abcd 1000dcda 1001以此類推...

在添加時或查詢時注意轉換。

總結

需要注意的是score是整數類型按從小到大排序儲存的,按照上面的設計是不能在指定類型的情況下,進行日期範圍尋找的,因為我們定義日期作為主維度。

通常在資料庫中有很多層級關係的表,比如大分類、子分類、小分類等一級一級遞減。 使用Sorted Sets我們可以類比這種關係去設計Score值,主維度->次維度->低維度,這樣就可以更快的進行範圍分類資訊的查詢,有個前提是64位整數的位置夠用。

如果沒有類似的需求,可以使用時間戳作為值的分數值,這樣就不需要額外的轉換了。

簡單分享了Sorted Sets儲存設計的經驗,希望對大家有所協助。

Redis系列(六)-SortedSets設計技巧

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.