前言
Redis是一個(gè)開(kāi)源的,基于內(nèi)存的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)系統(tǒng),可以用作數(shù)據(jù)庫(kù)、緩存和消息中間件。它支持多種數(shù)據(jù)類型,包括字符串(String)、哈希表(Hash)、列表(List)、集合(Set)、有序集合(ZSet )、地理空間(Geo)、位圖(Bitmaps)、基數(shù)統(tǒng)計(jì)(HyperLogLog)、流信息(Streams)。下面是這些類型的詳細(xì)介紹以及它們的操作和應(yīng)用場(chǎng)景。
一、字符串(String)
1. 簡(jiǎn)介
-
String 類型是 Redis 最基本的數(shù)據(jù)類型,一個(gè) key 對(duì)應(yīng)一個(gè) value。
-
String 類型是二進(jìn)制安全的,意思是 redis 的 string 可以包含任何數(shù)據(jù)。比如jpg圖片或者序列化的對(duì)象。
-
默認(rèn)情況下,單個(gè) Redis 字符串的最大值為 512 MB。
2. 常用命令
3. 使用場(chǎng)景
String類型一般用于緩存、限流、計(jì)數(shù)器、分布式鎖、分布式Session。
4.?使用例子文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-803064.html
1). 緩存token
redisTemplate.opsForValue().set("ZHANGSAN", "92c48b47-573f-455c-8f37-3746f85bf6a5", 30, TimeUnit.MINUTES);
2).?計(jì)數(shù)器
redisTemplate.opsForValue().increment("views_num", 1);
二、哈希表(Hash)
1.?簡(jiǎn)介
Redis Hash是一個(gè)string類型的field和value的映射表,hash特別適用于存儲(chǔ)對(duì)象。每個(gè)hash可以存儲(chǔ)232 - 1(42億左右)鍵值對(duì)??梢钥闯蒏EY和VALUE的MAP容器。
2.?常用命令
3.?使用場(chǎng)景
通常用來(lái)存儲(chǔ)對(duì)象型數(shù)據(jù),如用戶信息的對(duì)象數(shù)據(jù)?人(屬性,值,屬性,值)。
4.?使用例子
//設(shè)置哈希字段的值
redisTemplate.opsForHash().put("myhash", "field1", "value1");
//設(shè)置多個(gè)哈希字段的值
Map<String, Object> map = new HashMap<>();
map.put("field1", "value1");
map.put("field2", "value2");
redisTemplate.opsForHash().putAll("myhash", map);
//獲取哈希字段的值
redisTemplate.opsForHash().get("myhash", "field1");
//獲取多個(gè)哈希字段的值
redisTemplate.opsForHash().multiGet("myhash", Arrays.asList("field1", "field2"));
//判斷哈希中是否存在指定的字段
redisTemplate.opsForHash().hasKey("myhash", "field1");
//獲取哈希的所有字段
redisTemplate.opsForHash().keys("myhash");
//獲取哈希的所有值
redisTemplate.opsForHash().values("myhash");
//獲取哈希的所有字段和對(duì)應(yīng)的值
redisTemplate.opsForHash().entries("myhash");
//將指定字段的值增加指定步長(zhǎng)
redisTemplate.opsForHash().increment("myhash", "field1", 5);
//刪除指定的字段
redisTemplate.opsForHash().delete("myhash", "field1");
三、列表(List)
1.?簡(jiǎn)介
Redis List是簡(jiǎn)單的字符串列表,按照插入順序排序。你可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)一個(gè)列表最多可以包含 2^32^ - 1 個(gè)元素 (4294967295, 每個(gè)列表超過(guò)40億個(gè)元素)。
2.?常用命令
3.?使用場(chǎng)景
List類型一般用于簡(jiǎn)單隊(duì)列、列表顯示、關(guān)注列表、粉絲列表、留言評(píng)價(jià)…分頁(yè)、熱點(diǎn)新聞等。
4.?使用例子
//從列表的左側(cè)插入一個(gè)或多個(gè)元素
redisTemplate.opsForList().leftPush("mylist", "value1");
//從列表的右側(cè)插入一個(gè)或多個(gè)元素
redisTemplate.opsForList().rightPush("mylist", "value1");
//移除并返回列表最左側(cè)的元素
redisTemplate.opsForList().leftPop("mylist");
//移除并返回列表最右側(cè)的元素
redisTemplate.opsForList().rightPop("mylist");
//獲取列表指定范圍內(nèi)的元素
redisTemplate.opsForList().range("mylist", 0, -1);
//獲取列表中指定索引處的元素
redisTemplate.opsForList().index("mylist", 1);
//獲取列表的長(zhǎng)度
redisTemplate.opsForList().size("mylist");
//截取指定范圍內(nèi)的元素,保留指定范圍內(nèi)的元素,其它元素將被刪除
redisTemplate.opsForList().trim("mylist", 0, 2);
//移除列表中指定數(shù)量的元素
redisTemplate.opsForList().remove("mylist", 2, "value1");
//設(shè)置列表中指定索引處的元素的值
redisTemplate.opsForList().set("mylist", 2, "newvalue");
四、集合(Set)
1.?簡(jiǎn)介
Redis Set 是 String 類型的無(wú)序集合。集合中成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)。Redis 中集合是通過(guò)哈希表實(shí)現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是 O(1)。集合中最大的成員數(shù)為 2^32^ - 1 (4294967295)。
2.?常用命令
3.?使用場(chǎng)景
-
Set類型一般用于贊、踩、標(biāo)簽、好友關(guān)系等;
-
利用唯一性統(tǒng)計(jì)獨(dú)立IP等;
-
利用對(duì)交集、并集、差集的計(jì)算對(duì)數(shù)據(jù)進(jìn)行過(guò)濾處理,如共同好友、推薦信息的數(shù)據(jù)過(guò)濾等。
4.?使用例子
//向集合中添加一個(gè)或多個(gè)元素
redisTemplate.opsForSet().add("myset", "value1", "value2", "value3");
//獲取集合中的所有成員
redisTemplate.opsForSet().members("myset");
//獲取集合的大小
redisTemplate.opsForSet().size("myset");
//判斷元素是否是集合的成員
redisTemplate.opsForSet().isMember("myset", "value1");
//獲取集合中的隨機(jī)元素
redisTemplate.opsForSet().randomMember("myset");
//彈出并返回集合中的一個(gè)隨機(jī)元素
redisTemplate.opsForSet().pop("myset");
//從集合中移除一個(gè)或多個(gè)元素
redisTemplate.opsForSet().remove("myset", "value1", "value2");
//計(jì)算多個(gè)集合的交集,并返回結(jié)果集合
redisTemplate.opsForSet().intersect("set1", "set2");
//計(jì)算多個(gè)集合的并集,并返回結(jié)果集合
redisTemplate.opsForSet().union("set1", "set2");
//計(jì)算兩個(gè)集合的差集,并返回結(jié)果集合
redisTemplate.opsForSet().difference("set1", "set2");
五、有序集合(ZSet )
1.?簡(jiǎn)介
Redis 有序集合和集合一樣也是string類型元素的集合且不允許重復(fù)的成員。不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)==double類型的分?jǐn)?shù)==。redis正是通過(guò)分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行從小到大的排序。有序集合的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)。
集合是通過(guò)哈希表實(shí)現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。集合中最大的成員數(shù)為 2^32^ - 1 (4294967295)。
2.?常用命令
3.?使用場(chǎng)景
Zset類型一般用于排行榜、商品進(jìn)行排序顯示等。
4.?使用例子
//向有序集合中添加一個(gè)成員,同時(shí)指定該成員的分?jǐn)?shù)
redisTemplate.opsForZSet().add("myzset", "member1", 0.5);
redisTemplate.opsForZSet().add("myzset", "member2", 0.8);
redisTemplate.opsForZSet().add("myzset", "member3", 1.2);
//獲取有序集合中指定范圍內(nèi)的成員集合(按分?jǐn)?shù)從低到高排序)
redisTemplate.opsForZSet().range("myzset", 0, -1);
//獲取有序集合中指定范圍內(nèi)的成員集合(按分?jǐn)?shù)從高到低排序)
redisTemplate.opsForZSet().reverseRange("myzset", 0, -1);
//獲取有序集合中的成員數(shù)量
redisTemplate.opsForZSet().zCard("myzset");
//獲取有序集合中指定成員的分?jǐn)?shù)
redisTemplate.opsForZSet().score("myzset", "member1");
//從有序集合中移除指定的成員
redisTemplate.opsForZSet().remove("myzset", "member1", "member2");
//統(tǒng)計(jì)有序集合中指定分?jǐn)?shù)范圍內(nèi)的成員數(shù)量
redisTemplate.opsForZSet().count("myzset", 1.0, 2.0);
//將指定成員的分?jǐn)?shù)增加指定數(shù)值
redisTemplate.opsForZSet().incrementScore("myzset", "member1", 0.2);
//獲取指定成員在有序集合中的排名(按分?jǐn)?shù)從低到高排序)
redisTemplate.opsForZSet().rank("myzset", "member1");
//獲取指定成員在有序集合中的排名(按分?jǐn)?shù)從高到低排序)
redisTemplate.opsForZSet().reverseRank("myzset", "member1");
六、地理空間(GEO)
1.?簡(jiǎn)介
Redis 3.2 中增加了對(duì)GEO類型的支持。GEO,Geographic,地理信息的縮寫(xiě)。該類型,就是元素的2維坐標(biāo),在地圖上就是經(jīng)緯度。redis基于該類型,提供了經(jīng)緯度設(shè)置,查詢,范圍查詢,距離查詢,經(jīng)緯度Hash等常見(jiàn)操作。
2.?常用命令
3.?使用場(chǎng)景
地理空間索引,附件商家、酒店等
4.?使用例子
//添加一個(gè)或多個(gè)地理位置到指定的Geo鍵中
redisTemplate.opsForGeo().add("mygeo", new Point(116.397128, 39.916527), "Beijing");
redisTemplate.opsForGeo().add("mygeo", new Point(121.472641, 31.231707), "Shanghai");
redisTemplate.opsForGeo().add("mygeo", new Point(113.264435, 23.129163), "Guangzhou");
//獲取指定成員的地理位置
redisTemplate.opsForGeo().position("mygeo", "Beijing");
//計(jì)算兩個(gè)成員之間的距離(默認(rèn)以米為單位)
redisTemplate.opsForGeo().distance("mygeo", "Beijing", "Shanghai");
//獲取指定成員的Geohash值
redisTemplate.opsForGeo().hash("mygeo", "Beijing");
//根據(jù)給定的中心點(diǎn),返回與中心點(diǎn)距離在指定范圍內(nèi)的成員(按距離由近到遠(yuǎn)排序)
Circle circle = new Circle(new Point(116.397128, 39.916527), new Distance(200, Metrics.KILOMETERS));
redisTemplate.opsForGeo().radius("mygeo", circle);
//根據(jù)給定的成員,返回與該成員距離在指定范圍內(nèi)的其他成員(按距離由近到遠(yuǎn)排序)
redisTemplate.opsForGeo().radiusByMember("mygeo", "Beijing", new Distance(200, Metrics.KILOMETERS));
//從指定的Geo鍵中移除一個(gè)或多個(gè)成員
redisTemplate.opsForGeo().remove("mygeo", "Beijing", "Shanghai");
七、位圖(Bitmaps)
1.?簡(jiǎn)介
Redis 6 中提供了 Bitmaps 這個(gè)“數(shù)據(jù)類型”可以實(shí)現(xiàn)對(duì)位的操作。
Bitmaps本身不是一種數(shù)據(jù)類型,實(shí)際上它就是字符串(key-value),但是它可以對(duì)字符串的位進(jìn)行操作。
由于字符串是二進(jìn)制安全的,最大長(zhǎng)度是512MB,轉(zhuǎn)換成位可以設(shè)置 2^32不同的位。位圖的最大優(yōu)點(diǎn)之一,存儲(chǔ)信息時(shí)可以節(jié)省大量空間。
Bitmaps單獨(dú)提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同??梢园袯itmaps想象成一個(gè)以位為單位的數(shù)組, 數(shù)組的每個(gè)單元只能存儲(chǔ)0和1, 數(shù)組的下標(biāo)在Bitmaps中叫做偏移量。
2.?常用命令
3.?使用場(chǎng)景
Bitmaps一般用于記錄狀態(tài),比如登錄狀態(tài)、簽到等,并可以對(duì)狀態(tài)進(jìn)行統(tǒng)計(jì)。
4.?使用例子
//給指定key的值的第offset賦值val
redisTemplate.opsForValue().setBit("key",1,false);
//獲取指定key的第offset位
redisTemplate.opsForValue().getBit("key",1);
//獲取多個(gè)數(shù)據(jù)
BitFieldSubCommands command = BitFieldSubCommands.create()
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(1)
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(2)
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(3)
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(4)
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(5)
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(6)
.get(BitFieldSubCommands.BitFieldType.unsigned(1)).valueAt(7);
redisTemplate.opsForValue().bitField("key",command);
八、基數(shù)統(tǒng)計(jì)(HyperLogLog)
1.?簡(jiǎn)介
屬于一種概率算法,(LC,LLC,HLL)三種越來(lái)越節(jié)省內(nèi)存,降低誤差率。
HyperLogLog優(yōu)點(diǎn),在輸入元素的數(shù)量或者體積非常大時(shí)。計(jì)算基數(shù)所需的空間總是固定很小的。每個(gè)HyperLogLog的鍵只需要花費(fèi)12KB內(nèi)存,在標(biāo)準(zhǔn)誤差0.81%的前提下,就可以計(jì)算接近2^64個(gè)不同的基數(shù)。
用bitmap存儲(chǔ)1一億個(gè)統(tǒng)計(jì)數(shù)據(jù)大概需要12M內(nèi)存;而在HLL中,只需要不到1K內(nèi)存就能做到。
HyperLogLog只會(huì)根據(jù)輸入元素來(lái)計(jì)算基數(shù),而不會(huì)存儲(chǔ)元素本身,所以不能返回各個(gè)元素。
HLL比 bitmap更節(jié)省內(nèi)存,但有一定誤差( 標(biāo)準(zhǔn)誤差 0.81%)
2.?常用命令
3.?使用場(chǎng)景
常用來(lái)統(tǒng)計(jì)一個(gè)集合中不重復(fù)的元素個(gè)數(shù),例如網(wǎng)站PV(Page View 頁(yè)面瀏覽量)、UV(UniqueVisitor,獨(dú)立訪客),搜索關(guān)鍵詞數(shù)量,數(shù)據(jù)分析、網(wǎng)絡(luò)監(jiān)控及數(shù)據(jù)庫(kù)優(yōu)化等領(lǐng)域。
4.?使用例子
// 新增元素
redisTemplate.opsForHyperLogLog().add("key", "V1");
// 獲取估算數(shù)量
redisTemplate.opsForHyperLogLog().size("key");
// 合并
redisTemplate.opsForHyperLogLog().union("newKey", "key1", "key2");
九、流信息(Streams)
1.?簡(jiǎn)介
Stream是Redis 5.0引入的一種新數(shù)據(jù)類型,是一個(gè)新的強(qiáng)大的支持多播的可持久化的消息隊(duì)列。
相比于現(xiàn)有的PUB/SUB、BLOCKED LIST,其雖然也可以在簡(jiǎn)單的場(chǎng)景下作為消息隊(duì)列來(lái)使用,但是Redis Stream無(wú)疑要完善很多。Redis Stream提供了消息的持久化和主備復(fù)制功能、新的RadixTree數(shù)據(jù)結(jié)構(gòu)來(lái)支持更高效的內(nèi)存使用和消息讀取、甚至是類似于Kafka的Consumer Group功能。
它以更抽象的方式對(duì)日志數(shù)據(jù)結(jié)構(gòu)進(jìn)行建模,但是日志的本質(zhì)仍然完好無(wú)損:像日志文件一樣,通常實(shí)現(xiàn)為僅在追加模式下打開(kāi)的文件, Redis流主要是僅追加數(shù)據(jù)結(jié)構(gòu)。至少?gòu)母拍钌现v,由于Redis是流式傳輸在內(nèi)存中表示的抽象數(shù)據(jù)類型,因此它們實(shí)現(xiàn)了更強(qiáng)大的操作,以克服日志文件本身的限制。
盡管數(shù)據(jù)結(jié)構(gòu)本身非常簡(jiǎn)單,但Redis流卻成為最復(fù)雜的Redis類型的原因在于它實(shí)現(xiàn)了其他非強(qiáng)制性功能:一組阻止操作,使消費(fèi)者可以等待生產(chǎn)者將新數(shù)據(jù)添加到流中,此外還有一個(gè)稱為“ 消費(fèi)群體”的概念。
消費(fèi)者群體最初是由流行的稱為Kafka(TM)的消息傳遞系統(tǒng)引入的。Redis用完全不同的術(shù)語(yǔ)重新實(shí)現(xiàn)了一個(gè)類似的想法,但是目標(biāo)是相同的:允許一組客戶合作使用同一消息流的不同部分。
2.?常用命令
-
XADD 將新條目添加到流中。
-
XREAD 讀取一個(gè)或多個(gè)條目,從給定位置開(kāi)始并按時(shí)間向前移動(dòng)。
-
XRANGE 返回兩個(gè)提供的條目 ID 之間的條目范圍。
-
XLEN 返回流的長(zhǎng)度。
3.?使用場(chǎng)景
消息隊(duì)列,和kafka, RocketMq ,RabbitMq等各種消息中間件要按照當(dāng)前環(huán)境的情況和要求合理使用。
4.?使用例子
//向指定Stream鍵中添加一條消息
MapRecord<String, String, String> message = StreamRecords.newRecord().ofStrings()
.withStreamKey("mystream")
.withStreamId(StreamOffset.create("mystream", "0-0"))
.withValues("field1", "value1", "field2", "value2");
redisTemplate.opsForStream().add(message);
//獲取指定范圍內(nèi)的消息
List<MapRecord<String, String, String>> messages = redisTemplate.opsForStream().range("mystream", Range.unbounded());
//刪除指定的Stream鍵
redisTemplate.opsForStream().delete("mystream");
//獲取Stream中消息的數(shù)量
Long size = redisTemplate.opsForStream().size("mystream");
//使用消費(fèi)者組從指定偏移量開(kāi)始讀取消息
StreamReadOptions<String, String> options = StreamReadOptions.empty()
.block(Duration.ofMillis(1000))
.count(10);
List<MapRecord<String, String, String>> messages = redisTemplate.opsForStream()
.read(Consumer.from("consumerGroup", "consumerName"), options, StreamOffset.create("mystream", ReadOffset.lastConsumed()));
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-803064.html
到了這里,關(guān)于【Redis】九種數(shù)據(jù)類型及應(yīng)用場(chǎng)景的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!