Redis数据类型大全:“5种基础”数据类型+“3种特殊”数据类型 您所在的位置:网站首页 redis基本数据类型 Redis数据类型大全:“5种基础”数据类型+“3种特殊”数据类型

Redis数据类型大全:“5种基础”数据类型+“3种特殊”数据类型

#Redis数据类型大全:“5种基础”数据类型+“3种特殊”数据类型| 来源: 网络整理| 查看: 265

一、“5种基础”数据类型

Redis 有望所有的key(键)都是字符串。我们在谈基础数据结构时,讨论的是存储值的数据类型,主要包括常见的5种数据类型,分别是:String、List、Set、Zset、Hash

image.png 1.1 Redis数据结构简介

Redis基础文章非常多,关于基础数据结构类型,我推荐你先看下官方网站内容 (opens new window),然后再看下面的小结

首先对redis来说,所有的key(键)都是字符串。我们在谈基础数据结构时,讨论的是存储值的数据类型,主要包括常见的5种数据类型,分别是:String、List、Set、Zset、Hash。

image.png image.png 1.2 基础数据结构详解

内容其实比较简单,我觉得理解的重点在于这个结构怎么用,能够用来做什么?所以我在梳理时,围绕图例,命令,执行和场景来阐述

1.2.1 String字符串

String是redis中最基本的数据类型,一个key对应一个value。

String类型是二进制安全的,意思是 redis 的 string 可以包含任何数据。如数字,字符串,jpg图片或者序列化的对象。

图例

下图是一个String类型的实例,其中键为hello,值为world

image.png 命令使用 image.png 命令执行 127.0.0.1:6379> set hello world OK 127.0.0.1:6379> get hello "world" 127.0.0.1:6379> del hello (integer) 1 127.0.0.1:6379> get hello (nil) 127.0.0.1:6379> get counter "2" 127.0.0.1:6379> incr counter (integer) 3 127.0.0.1:6379> get counter "3" 127.0.0.1:6379> incrby counter 100 (integer) 103 127.0.0.1:6379> get counter "103" 127.0.0.1:6379> decr counter (integer) 102 127.0.0.1:6379> get counter "102" 实战场景 缓存: 经典使用场景,把常用信息,字符串,图片或者视频等信息放到redis中,redis作为缓存层,mysql做持久化层,降低mysql的读写压力。 计数器:redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。 session:常见方案spring session + redis实现session共享 1.2.2 List列表

Redis中的List其实就是链表(Redis用双端链表实现List)。

使用List结构,我们可以轻松地实现最新消息排队功能(比如新浪微博的TimeLine)。List的另一个应用就是消息队列,可以利用List的 PUSH 操作,将任务存放在List中,然后工作线程再用 POP 操作将任务取出进行执行。

图例 image.png 命令使用 image.png 使用列表的技巧 lpush+lpop=Stack(栈) lpush+rpop=Queue(队列) lpush+ltrim=Capped Collection(有限集合) lpush+brpop=Message Queue(消息队列) 命令执行 127.0.0.1:6379> lpush mylist 1 2 ll ls mem (integer) 5 127.0.0.1:6379> lrange mylist 0 -1 1) "mem" 2) "ls" 3) "ll" 4) "2" 5) "1" 127.0.0.1:6379> lindex mylist -1 "1" 127.0.0.1:6379> lindex mylist 10 # index不在 mylist 的区间范围内 (nil) 实战场景微博 TimeLine: 有人发布微博,用lpush加入时间轴,展示新的列表信息。 消息队列 1.2.3 Set集合

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

图例 image.png 命令使用 image.png 命令执行 127.0.0.1:6379> sadd myset hao hao1 xiaohao hao (integer) 3 127.0.0.1:6379> smember myset 1) "xiaohao" 2) "hao1" 3) "hao" 127.0.0.1:6379> sismember myset hao (integer) 1 实战场景 标签(tag),给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人。 点赞,或点踩,收藏等,可以放到set中实现 1.2.4 Hash散列

Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

图例 image.png 命令使用 image.png 命令执行 127.0.0.1:6379> hset user name1 hao (integer) 1 127.0.0.1:6379> hset user email1 [email protected] (integer) 1 127.0.0.1:6379> hgetall user 1) "name1" 2) "hao" 3) "email1" 4) "[email protected]" 127.0.0.1:6379> hget user user (nil) 127.0.0.1:6379> hget user name1 "hao" 127.0.0.1:6379> hset user name2 xiaohao (integer) 1 127.0.0.1:6379> hset user email2 [email protected] (integer) 1 127.0.0.1:6379> hgetall user 1) "name1" 2) "hao" 3) "email1" 4) "[email protected]" 5) "name2" 6) "xiaohao" 7) "email2" 8) "[email protected]" 实战场景 缓存: 能直观,相比string更节省空间,的维护缓存信息,如用户信息,视频信息等 1.2.5 Zset有序集合

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

图例 image.png 命令使用 127.0.0.1:6379> zadd myscoreset 100 hao 90 xiaohao (integer) 2 127.0.0.1:6379> ZRANGE myscoreset 0 -1 1) "xiaohao" 2) "hao" 127.0.0.1:6379> ZSCORE myscoreset hao "100" 实战场景 排行榜:有序集合经典使用场景。例如小说视频等网站需要对用户上传的小说视频做排行榜,榜单可以按照用户关注数,更新时间,字数等打分,做排行 二、3种特殊类型详解

Redis除了上文中5种基础数据类型,还有三种特殊的数据类型,分别是 HyperLogLogs(基数统计), Bitmaps (位图) 和 geospatial (地理位置)

2.1 HyperLogLogs(基数统计)

Redis 2.8.9 版本更新了 Hyperloglog 数据结构!

什么是基数?

举个例子,A = {1, 2, 3, 4, 5}, B = {3, 5, 6, 7, 9};那么基数(不重复的元素)= 1, 2, 4, 6, 7, 9; (允许容错,即可以接受一定误差)

HyperLogLogs 基数统计用来解决什么问题?

这个结构可以非常省内存的去统计各种计数,比如注册 IP 数、每日访问 IP 数的页面实时UV、在线用户数,共同好友数等。

它的优势体现在哪?

一个大型的网站,每天 IP 比如有 100 万,粗算一个 IP 消耗 15 字节,那么 100 万个 IP 就是 15M。而 HyperLogLog 在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值,不管存储的内容是什么,它一个基于基数估算的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的的唯一元素。而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值(对于可以接受一定容错的业务场景,比如IP数统计,UV等,是可以忽略不计的)。

相关命令使用 127.0.0.1:6379> pfadd key1 a b c d e f g h i # 创建第一组元素 (integer) 1 127.0.0.1:6379> pfcount key1 # 统计元素的基数数量 (integer) 9 127.0.0.1:6379> pfadd key2 c j k l m e g a # 创建第二组元素 (integer) 1 127.0.0.1:6379> pfcount key2 (integer) 8 127.0.0.1:6379> pfmerge key3 key1 key2 # 合并两组:key1 key2 -> key3 并集 OK 127.0.0.1:6379> pfcount key3 (integer) 13 2.2 Bitmap (位存储)

Bitmap 即位图数据结构,都是操作二进制位来进行记录,只有0 和 1 两个状态。

用来解决什么问题?

比如:统计用户信息,活跃,不活跃! 登录,未登录! 打卡,不打卡! 两个状态的,都可以使用 Bitmaps!

如果存储一年的打卡状态需要多少内存呢? 365 天 = 365 bit 1字节 = 8bit 46 个字节左右!

相关命令使用

使用bitmap 来记录 周一到周日的打卡! 周一:1 周二:0 周三:0 周四:1 ......

127.0.0.1:6379> setbit sign 0 1 (integer) 0 127.0.0.1:6379> setbit sign 1 1 (integer) 0 127.0.0.1:6379> setbit sign 2 0 (integer) 0 127.0.0.1:6379> setbit sign 3 1 (integer) 0 127.0.0.1:6379> setbit sign 4 0 (integer) 0 127.0.0.1:6379> setbit sign 5 0 (integer) 0 127.0.0.1:6379> setbit sign 6 1 (integer) 0

查看某一天是否有打卡!

127.0.0.1:6379> getbit sign 3 (integer) 1 127.0.0.1:6379> getbit sign 5 (integer) 0

统计操作,统计 打卡的天数!

127.0.0.1:6379> bitcount sign # 统计这周的打卡记录,就可以看到是否有全勤! (integer) 3 2.3 geospatial (地理位置)

Redis 的 Geo 在 Redis 3.2 版本就推出了! 这个功能可以推算地理位置的信息: 两地之间的距离, 方圆几里的人

2.3.1 geoadd

添加地理位置

127.0.0.1:6379> geoadd china:city 118.76 32.04 manjing 112.55 37.86 taiyuan 123.43 41.80 shenyang (integer) 3 127.0.0.1:6379> geoadd china:city 144.05 22.52 shengzhen 120.16 30.24 hangzhou 108.96 34.26 xian (integer) 3 规则

两级无法直接添加,我们一般会下载城市数据(这个网址可以查询 GEO: http://www.jsons.cn/lngcode)!

有效的经度从-180度到180度。 有效的纬度从-85.05112878度到85.05112878度。 # 当坐标位置超出上述指定范围时,该命令将会返回一个错误。 127.0.0.1:6379> geoadd china:city 39.90 116.40 beijin (error) ERR invalid longitude,latitude pair 39.900000,116.400000 2.3.2 geopos

获取指定的成员的经度和纬度

127.0.0.1:6379> geopos china:city taiyuan manjing 1) 1) "112.54999905824661255" 1) "37.86000073876942196" 2) 1) "118.75999957323074341" 1) "32.03999960287850968"

获得当前定位, 一定是一个坐标值!

2.3.3 geodist

如果不存在, 返回空

单位如下 m km mi 英里 ft 英尺 127.0.0.1:6379> geodist china:city taiyuan shenyang m "1026439.1070" 127.0.0.1:6379> geodist china:city taiyuan shenyang km "1026.4391" 2.3.4 georadius

附近的人 ==> 获得所有附近的人的地址, 定位, 通过半径来查询

获得指定数量的人

127.0.0.1:6379> georadius china:city 110 30 1000 km 以 100,30 这个坐标为中心, 寻找半径为1000km的城市 1) "xian" 2) "hangzhou" 3) "manjing" 4) "taiyuan" 127.0.0.1:6379> georadius china:city 110 30 500 km 1) "xian" 127.0.0.1:6379> georadius china:city 110 30 500 km withdist 1) 1) "xian" 2) "483.8340" 127.0.0.1:6379> georadius china:city 110 30 1000 km withcoord withdist count 2 1) 1) "xian" 2) "483.8340" 3) 1) "108.96000176668167114" 2) "34.25999964418929977" 2) 1) "manjing" 2) "864.9816" 3) 1) "118.75999957323074341" 2) "32.03999960287850968"

参数 key 经度 纬度 半径 单位 [显示结果的经度和纬度] [显示结果的距离] [显示的结果的数量]

2.3.5 georadiusbymember

显示与指定成员一定半径范围内的其他成员

127.0.0.1:6379> georadiusbymember china:city taiyuan 1000 km 1) "manjing" 2) "taiyuan" 3) "xian" 127.0.0.1:6379> georadiusbymember china:city taiyuan 1000 km withcoord withdist count 2 1) 1) "taiyuan" 2) "0.0000" 3) 1) "112.54999905824661255" 2) "37.86000073876942196" 2) 1) "xian" 2) "514.2264" 3) 1) "108.96000176668167114" 2) "34.25999964418929977"

参数与 georadius 一样

2.3.6 geohash(较少使用)

该命令返回11个字符的hash字符串

127.0.0.1:6379> geohash china:city taiyuan shenyang 1) "ww8p3hhqmp0" 2) "wxrvb9qyxk0"

将二维的经纬度转换为一维的字符串, 如果两个字符串越接近, 则距离越近

2.3.7 底层

geo底层的实现原理实际上就是Zset, 我们可以通过Zset命令来操作geo

127.0.0.1:6379> type china:city zset

查看全部元素 删除指定的元素

127.0.0.1:6379> zrange china:city 0 -1 withscores 1) "xian" 2) "4040115445396757" 3) "hangzhou" 4) "4054133997236782" 5) "manjing" 6) "4066006694128997" 7) "taiyuan" 8) "4068216047500484" 9) "shenyang" 1) "4072519231994779" 2) "shengzhen" 3) "4154606886655324" 127.0.0.1:6379> zrem china:city manjing (integer) 1 127.0.0.1:6379> zrange china:city 0 -1 1) "xian" 2) "hangzhou" 3) "taiyuan" 4) "shenyang" 5) "shengzhen"

原文链接:https://pdai.tech/md/db/nosql-redis/db-redis-data-types.html 原文链接:https://pdai.tech/md/db/nosql-redis/db-redis-data-type-special.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有