Redis存儲Key的一種設(shè)計(jì)實(shí)現(xiàn)方式:模式匹配
一、前言
Redis是Key-Value數(shù)據(jù)庫,存儲的時(shí)候需要一個(gè)***的Key值,查詢的時(shí)候根據(jù)根據(jù)key值進(jìn)行查詢,但是Redis畢竟只是key-value存儲,所以有很多局限性。例如:
(1)無法實(shí)現(xiàn)多條件組合的查詢,如:
硬要實(shí)現(xiàn)的話需要多條命令并計(jì)算并集或交集。
(2)模糊查詢中文比較費(fèi)勁;
因此,如何設(shè)計(jì)一個(gè)合適的Key來優(yōu)化我們的查詢操作,是一個(gè)比較有意義的事情。
對于Key的設(shè)計(jì)網(wǎng)上有很多資料,但對我來說,都太過于凌亂,并沒有找到一個(gè)合適的方案。下邊,和大家一起學(xué)習(xí)一種較為簡單的模式匹配方式的Key值設(shè)計(jì)方法。
下邊的學(xué)習(xí),主要介紹項(xiàng)目中使用的方式,有興趣的同學(xué)可以clone代碼一起學(xué)習(xí),倉庫地址:
https://git.oschina.net/xuliugen/redis-demo.git
二、項(xiàng)目結(jié)構(gòu)
SSM框架(Spring+Spring MVC+MyBatis),除了實(shí)現(xiàn)了對Redis的存儲,還通過注解的方式實(shí)現(xiàn)了數(shù)據(jù)庫的讀寫分離功能,實(shí)現(xiàn)了Spring對數(shù)據(jù)庫和Redis的事務(wù)管理,JSR303校驗(yàn),以及簡單的領(lǐng)域驅(qū)動DDD思想項(xiàng)目。
(1)項(xiàng)目結(jié)構(gòu):
(2)數(shù)據(jù)庫腳本:
(3)Spring配置文件位置:
其中,db-redis.xml文件中,如下代碼表示開啟Redis事務(wù):
(4)Redis和MyBatis代碼位置:
三、Key值設(shè)計(jì)
上述,大致看了依托的項(xiàng)目結(jié)構(gòu),還沒有開始Redis Key值得設(shè)計(jì),因此可以跳過,下邊主要學(xué)習(xí)一下,如何設(shè)計(jì)一種Key實(shí)現(xiàn)模式匹配查詢方式。
(1)情景假設(shè)
有實(shí)體對象SecurityUserDTO,如下:
這里假設(shè)用戶對象最常用的查詢條件是:用戶名(userName)和單位類型(unitType),因此,對于數(shù)據(jù)庫設(shè)計(jì)的時(shí)候,我們應(yīng)該對這兩個(gè)屬性加上索引(題外話,完全和Key的設(shè)計(jì)無關(guān)!只是在于點(diǎn)一下這種最常見的數(shù)據(jù)庫加索引的方式)。
數(shù)據(jù)庫做了索引,那我,我們將數(shù)據(jù)存儲到Redis中的時(shí)候,如何在把他取出來那?
(2)首先,看一下最終存放在Redis中的數(shù)據(jù)格式:
其中:
SU1_縣級單位_wangwu_0000000035
可以分為四個(gè)部分:
1、簡化的實(shí)體對象名稱,就是SecurityUserDTO的簡寫,為了縮短Key的長度;
2、unitType的值,***個(gè)查詢條件;
3、userName的值,第二個(gè)查詢條件;
4、ID的值,十位數(shù)值,前邊不足十位補(bǔ)0;
(3)如何拼接,核心代碼如下:
assembleRedisKeyPrefix()方法:
assemberIdForKey()方法:
到這里,基本已經(jīng)知道了大致拼接的過程,因此存放到Redis的數(shù)據(jù)是如下格式:
注:可以SecurityUserController#addUser(SecurityUserDTO userDTO)方法測試效果。
(4)如何查詢:
查詢的話可以參考SecurityUserController#listByCondition()方法:
查詢的時(shí)候,也是需要根據(jù)查詢條件構(gòu)造Key值,然后讀取數(shù)據(jù)。
如果,查詢條件都有的話,構(gòu)造的Key值如下:
如果,查詢條件只有一個(gè)的話,構(gòu)造的Key值如下:
(5)修改數(shù)據(jù)和刪除數(shù)據(jù):
因?yàn)镮D在拼接的時(shí)候肯定是***的,因此,刪除的直接拼接為如下形式即可:
四、總結(jié)
拼接Key的方式很簡單,以常用的查詢條件屬性作為拼接Key的依據(jù),當(dāng)然還可以通過其他的方式,但最主要的是如何去實(shí)踐。