成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Redis如何實現(xiàn)分頁+多條件模糊查詢?答案來了

數(shù)據(jù)庫 Redis
Redis是一個高效的內(nèi)存數(shù)據(jù)庫,它支持包括String、List、Set、SortedSet和Hash等數(shù)據(jù)類型的存儲,在Redis中通常根據(jù)數(shù)據(jù)的key查詢其value值,Redis沒有模糊條件查詢,在面對一些需要分頁、排序以及條件查詢的場景時(如評論,時間線,檢索等),只憑借Redis所提供的功能就不太好不處理了。

導(dǎo)言

Redis是一個高效的內(nèi)存數(shù)據(jù)庫,它支持包括String、List、Set、SortedSet和Hash等數(shù)據(jù)類型的存儲,在Redis中通常根據(jù)數(shù)據(jù)的key查詢其value值,Redis沒有模糊條件查詢,在面對一些需要分頁、排序以及條件查詢的場景時(如評論,時間線,檢索等),只憑借Redis所提供的功能就不太好不處理了。

本文不對Redis的特性做過多贅述。由于之前基于業(yè)務(wù)問題需要實現(xiàn)基于Redis的條件查詢和分頁功能,在百度上查詢了不少文章,基本不是只有分頁功能就是只有條件查詢功能的實現(xiàn),缺少兩者組合的解決方案。因此,本文將基于Redis提供條件查詢+分頁的技術(shù)解決方案。

注:本文只提供實現(xiàn)思路,并不提供實現(xiàn)的代碼

本文將從四個部分進行說明:

  • 分頁實現(xiàn)
  • 模糊條件查詢實現(xiàn)
  • 分頁和模糊條件查詢的組合實現(xiàn)
  • 優(yōu)化方案

大家可以直接跳到自己需要的部分進行閱讀。

Redis的分頁實現(xiàn)

我們通常習(xí)慣于在Mysql、Oracle這樣持久化數(shù)據(jù)庫中實現(xiàn)分頁查詢,但是基于某些特殊的業(yè)務(wù)場景下,我們的數(shù)據(jù)并未持久化到了數(shù)據(jù)庫中或是出于查詢速度上的考慮將熱點數(shù)據(jù)加載到了緩存數(shù)據(jù)庫中。因此,我們可能需要基于Redis這樣的緩存數(shù)據(jù)庫去進行分頁查詢。

Redis的分頁查詢的實現(xiàn)是基于Redis提供的ZSet數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的,ZSet全稱為Sorted Set,該結(jié)構(gòu)主要存儲有序集合。下面是它的指令描述以及該指令在分頁實現(xiàn)中的作用:

  • ZADD:SortedSet的添加元素指令ZADD key score member [[score,member]…]會給每個添加的元素member綁定一個用于排序的值score,SortedSet就會根據(jù)score值的大小對元素進行排序。我們?yōu)橥ǔA?xí)慣于將數(shù)據(jù)的時間屬性當作score用于排序,當然大家也可以根據(jù)具體的業(yè)務(wù)場景去選擇排序的目標。
  • ZREVRANGE:SortedSet中的指令ZREVRANGE key start stop可以返回指定區(qū)間內(nèi)的成員,可以用來做分頁。
  • ZREM:SortedSet的指令ZREM key member可以根據(jù)key移除指定的成員,能滿足刪評論的要求。

所以SortedSet用來做分頁是非常適合的。下面是分頁實現(xiàn)的演示圖,包含插入新記錄后的查詢情況。

事實上,Redis中的List結(jié)構(gòu)也是可以實現(xiàn)分頁,但List無法實現(xiàn)自動排序,并且Zset還可以根據(jù)score進行數(shù)據(jù)篩選,取出目標score區(qū)間內(nèi)數(shù)據(jù)。

所以在實現(xiàn)上,ZSet往往更加適合我們。當然如果你需要插入重復(fù)數(shù)據(jù)的情況下,分頁就可能就需要借助List來實現(xiàn)了。具體使用那種結(jié)構(gòu)來實現(xiàn)分頁還是需要根據(jù)實際的業(yè)務(wù)場景來進行選擇的。

Redis的多條件模糊查詢實現(xiàn)

Redis是key-value類型的內(nèi)存數(shù)據(jù)庫,通過key直接取數(shù)據(jù)雖然很方便,但是并未提供像mysql那樣方便的sql條件查詢支持。因此我們需要借助Redis提供的結(jié)構(gòu)和功能去自己實現(xiàn)模糊條件查詢功能。

事實上,Redis的模糊條件查詢是基于Hash實現(xiàn)的,我們可以將數(shù)據(jù)的某些條件值作為hash的key值,并數(shù)據(jù)本身作為value進行存儲。然后通過Hash提供的HSCAN指令去遍歷所有的key進行篩選,得到我們符合條件的所有key值(hscan可以進行模式匹配)。

為了方便,我們通常將符合條件的key全部放入到一個Set或是List中。這樣一來,我們就可以根據(jù)得到的key值去取出相應(yīng)的數(shù)據(jù)了。下面是模糊查詢的演示圖(其中field中的命名規(guī)則為<id>:<姓名>:<性別>,value為用戶詳情的json串)。

查詢所有性別為女的用戶

查詢所有名字中姓阿的用戶

HSCAN雖然為我們提供了模式匹配的功能,但這種匹配是基于遍歷實現(xiàn)的,每一次匹配都需要遍歷全部的key,效率上并不高。因此在下面一節(jié)會這方面進行補充,本節(jié)只談如何實現(xiàn)模糊匹配。

Redis的分頁+多條件模糊查詢組合實現(xiàn)

前面分別單獨敘述了如何實現(xiàn)Redis的分頁和多條件某查詢。在實際使用中,單獨使用ZSet實現(xiàn)分頁已經(jīng)能夠展現(xiàn)不錯的性能了,但存在一個問題是我們所分頁的數(shù)據(jù)往往是伴隨著一些動態(tài)的篩選條件的,而ZSet并不提供這樣的功能。

面對這種情況,我們通常有兩種解決方案:

  1. 如果數(shù)據(jù)已經(jīng)存儲在了持久化數(shù)據(jù)庫中,我們可以每次在數(shù)據(jù)庫中做好條件查詢再將數(shù)據(jù)放入Redis中進行分頁。
  2. 在Redis中實現(xiàn)多條件模糊查詢并分頁。

前者方案其實是一個不錯的選擇,但缺點在于數(shù)據(jù)有時候并不一定都在持久化數(shù)據(jù)庫中。在有些業(yè)務(wù)場景下,我們的數(shù)據(jù)為了展現(xiàn)更好的并發(fā)性以及高響應(yīng),我們的數(shù)據(jù)會先放置在緩存數(shù)據(jù)庫中,等到某個時間或者滿足某種條件時再持久化到數(shù)據(jù)庫中。

在這種情況下我們第一個方案就不起作用了,需要使用第二個方案。因此,下面將介紹如何實現(xiàn)多條件模糊查詢的基礎(chǔ)上進行分頁。

實現(xiàn)思路

首先我們可以采用多條件模糊查詢章節(jié)所說的方式,將我們所涉及到的條件字段作為hash的field,而數(shù)據(jù)的內(nèi)容則作為對應(yīng)value進行存儲(一般以json格式存儲,方便反序列化)。

我們需要實現(xiàn)約定好查詢的格式,用前面一節(jié)的例子來說,field中的命名規(guī)則為<id>:<姓名>:<性別>,我們每次可以通過"*"來實現(xiàn)我們希望的模糊匹配條件,比如“*:*:男”就是匹配所有男性數(shù)據(jù),“100*:*:*”就是匹配所有id前綴為100的用戶。

當我們拿到了匹配串后我們先去Redis中尋找是否存在以該匹配串為key的ZSet,如果沒有則通過Redis提供的HSCAN遍歷所有hash的field,得到所有符合條件的field,并將其放入一個ZSet集合,同時將這個集合的key設(shè)置為我們的條件匹配串。如果已經(jīng)存在了,則直接對這個ZSet進行分頁查詢即可。對ZSet進行分頁的方式已經(jīng)在前面敘述過了。通過這樣的方式我們就實現(xiàn)了最簡單的分頁+多條件模糊查詢。另外,搜索公眾號GitHub猿后臺回復(fù)“賺錢”,獲取一份驚喜禮包。

上圖中,由于并未在緩存數(shù)據(jù)庫中找到符合的ZSet集合,我們將根據(jù)匹配串生成一個新的集合用于分頁。

性能優(yōu)化方案

雖然上文實現(xiàn)了多條件模糊查詢+分頁的功能,但是在時間開發(fā)中,我們不能無限制的生成新的集合,因為匹配串是很多樣化的,這會給緩存帶來巨大的壓力。

因此我們在生成集合時可以賦予這個集合一個過期時間,到期集合會自動銷毀。因為根據(jù)時間局部性原理,我們在一段時間內(nèi)不訪問的數(shù)據(jù)大概率在很長一頓時間內(nèi)也不會再訪問。而對于命中的集合,我們將更新其過期時間。

同時,我們數(shù)據(jù)的實時性也是一個問題,因為我們的集合是在生成集合時的Hash內(nèi)容決定的,對于新插入到Hash的數(shù)據(jù),集合是無法探知的,因此有兩種解決方案:

  • 第一種是插入到Hash時同時再插入到其他相應(yīng)的集合中,保證數(shù)據(jù)一直是最新的,這種方式需要增加特殊前綴用于識別,否則我們也不清楚到底要插入到哪些集合中。
  • 第二種方式是定時更新,這種方式比較省力,但無法保證分頁數(shù)據(jù)的實時性。因此具體怎么選擇還是取決于業(yè)務(wù)場景。

總結(jié)

本文大概地描述了實現(xiàn)分頁和多條件模糊查詢的方案,希望能夠?qū)Υ蠹矣兴鶐椭?/p>

責(zé)任編輯:華軒 來源: 架構(gòu)精進之路
相關(guān)推薦

2025-02-06 10:00:52

RedisSpring高性能

2025-05-07 09:32:00

2010-05-06 14:11:55

Oracle多條件查詢

2009-09-15 11:34:47

Linq多條件查詢

2010-04-30 09:34:24

Oracle多條件查詢

2010-11-09 15:18:37

SQL Server多

2009-09-15 09:33:46

linq多條件查詢

2009-06-29 09:03:31

Hibernate多條

2010-11-18 16:27:37

2010-09-25 16:42:45

sql語句

2025-04-03 08:35:00

分頁查詢開發(fā)代碼

2022-09-14 08:11:06

分頁模糊查詢

2010-10-29 16:41:12

Oracle模糊查詢

2018-12-25 16:30:15

SQL Server高效分頁數(shù)據(jù)庫

2010-04-28 16:45:27

Oracle Inst

2010-11-24 10:35:34

MySQL單表多字段

2019-09-11 10:40:49

MySQL大分頁查詢數(shù)據(jù)庫

2009-09-21 13:42:47

Hibernate查詢

2010-11-18 13:40:48

mysql分頁查詢

2009-08-04 14:23:36

ASP.NET查詢分頁
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲高清在线 | 欧美一区二区三区,视频 | 免费一区二区在线观看 | 精品综合久久 | 亚洲国产精品99久久久久久久久 | 岛国午夜| a在线视频 | 精品免费av| 中文字幕日韩欧美一区二区三区 | 精品久久香蕉国产线看观看亚洲 | 成人不卡一区二区 | 日本在线视频不卡 | 久久久无码精品亚洲日韩按摩 | 精品日韩一区二区三区av动图 | 韩国欧洲一级毛片 | 中文字幕四虎 | 2018天天干天天操 | 99精品网站 | 欧美片网站免费 | 日本视频在线播放 | 欧美日韩一区在线观看 | 亚洲乱码国产乱码精品精的特点 | 国产综合精品 | 色橹橹欧美在线观看视频高清 | 国产一区二区 | 亚洲高清视频一区二区 | 毛片免费看的 | 成人在线不卡 | 91精品国产色综合久久 | 亚洲精品久久久久avwww潮水 | 久草久 | 颜色网站在线观看 | 91精品国产乱码久久久 | 国产成人一区二区三区精 | 欧美国产视频一区二区 | av在线播放网站 | 国产精品久久久久久久久久久久午夜片 | 久久国产精品-国产精品 | julia中文字幕久久一区二区 | 一区二区成人 | www.久草|