Redis三种特殊数据类型:HyperLogLog、BigMap、Geo

引语:

Redis 是一个高性能、(key/value)、分布式,基于内存运行、支持持久化的NoSQL数据库。

它也常被称为数据结构服务器,因为它存储的值(value)可以是String 、hash、list(有序、可索引;实现队列、栈)、set、zset(有序集合)等数据类型。这也是redis相比于其他缓存工具的一个优势:可以支持丰富的数据结构。

今天想与大家介绍的便是,redis另三种特殊的数据结构:Geo、HyperLogLog、 BitMap

浅谈数据类型与数据结构的不同

  1. 数据类型定义了数据在计算机存储的大小及数据的操作。比如int类型的数据,在计算机存储是两个字节的长度。int类型有一些加、减、乘、除的操作。

数据结构定义了数据存储及组织数据的方式。比如mysql数据库索引,使用的是B+树结构,提高了数据的检索效率,减少了io的操作。

  1. 数据类型是一类事物的集合

数据结构是一种解决问题的思想

  1. 数据类型中也会用到数据结构,如HashMap的低层结构是数组+链表+红黑树

  • 数据结构:数组、栈、队列、链表、树、图、堆、散列表等。

数据类型:基本数据类型(byte、short、int、long、double、float、boolean、char),引用数据类型,(以JAVA为例)

一般可以这样说,

? 某某类型实现了(用到)某某结构,如HashMap的低层结构是数组+链表+红黑树

? 某某功能实现了(用到)某某结构,如mysql数据库索引,使用的是B+树结构

官网的介绍:

Redis数据类型简介页面,有Bitmap与HyperLogLog,但没geo

翻译:

redis还支持位图和超级日志,它们实际上是基于字符串基类型的数据类型,但具有自己的语义。有关这些类型的信息,请参阅Redis数据类型介绍。

Redis数据类型介绍页面


HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

Redis HyperLogLog 是用来做基数统计的算法,这个结构可以非常省内存的去统计各种计数,比如统计注册 IP 数、每日访问 IP 数、页面实时UV、在线用户数等场景。但是它也有局限性,就是只能统计数量,而没办法去知道具体的内容是什么。

HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

它一个基于基数估算的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值。

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

浅谈数据结构与算法的区别

数据结构和算法其实是同一个内容的两种表达。

算法是数据结构的动态特征,用编程语言来表示就是语义。

数据结构是算法的静态本质,用编程语言来说就是语法。

用编程语言来描述数据结构和算法,就是程序。

pfadd,pfcount 命令演示

127.0.0.1:6379> pfadd db redis
(integer) 1
127.0.0.1:6379> pfadd db mysql
(integer) 1
127.0.0.1:6379> pfadd db mongodb
(integer) 1
127.0.0.1:6379> pfcount db
(integer) 3
127.0.0.1:6379> pfadd db redis
(integer) 0
127.0.0.1:6379> pfcount db
(integer) 3

pfmerge 命令演示

127.0.0.1:6379> del num1 num2
(integer) 0
127.0.0.1:6379> pfadd num1 1 2 3
(integer) 1
127.0.0.1:6379> pfadd num2 2 3 4
(integer) 1
127.0.0.1:6379> pfmerge num3 num1 num2
OK
127.0.0.1:6379> pfcount num1
(integer) 3
127.0.0.1:6379> pfcount num2
(integer) 3
127.0.0.1:6379> pfcount num3
(integer) 4


BitMap

BitMap 就是通过一个 bit 位来表示某个元素对应的值或者状态, 其中的 key 就是对应元素本身,实际上底层也是通过对字符串的操作来实现。Redis 从 2.2 版本之后新增了setbit, getbit, bitcount 等几个 bitmap 相关命令。虽然是新命令,但是本身都是对字符串的操作

语法:setbit key offset value

其中 offset 必须是数字,value 只能是 0 或者 1

当我们使用命令 setbit key (0,2,5,9,12) 1后,它的具体表示为:

可以看出 bit 的默认值是 0,那么 BitMap 在实际开发的运用呢?这里举一个例子:储存用户在线状态。这里只需要一个 key,然后把用户 ID 作为 offset,如果在线就设置为 1,不在线就设置为 0。实例代码:

127.0.0.1:6379> setbit online 5 1
(integer) 0
127.0.0.1:6379> setbit online 7 1
(integer) 0
127.0.0.1:6379> setbit online 9 1
(integer) 0
127.0.0.1:6379> setbit online 123456789 1
(integer) 0
127.0.0.1:6379> getbit online 9
(integer) 1
127.0.0.1:6379> getbit online 6
(integer) 0
127.0.0.1:6379> getbit online 123456789
(integer) 1
127.0.0.1:6379> bitcount online 0 0
(integer) 2
127.0.0.1:6379> bitcount online 1 1
(integer) 1
127.0.0.1:6379> bitcount online 0 -1
(integer) 4


Geo

Redis3.2.0版本推出
可以将用户给定的地理位置信息存储起来,并对这些信息进行操作

用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。geo的底层实现是zset。

  • geoadd

    命令:geopos key member [member...]

    命令描述:将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。

    ? 有效的经度介于-180-180度之间
    ? 有效的纬度介于-85.05112878 度至 85.05112878 度之间。
    ? 当用户尝试输入一个超出范围的经度或者纬度时,geoadd命令将返回一个错误。

    返回值:添加到sorted set元素的数目,但不包括已更新score的元素。

    示例:

    127.0.0.1:6379> geoadd cities 116.28 39.55 beijing
    (integer) 1
    127.0.0.1:6379> geopos cities beijing
    1) 1) "116.28000229597091675"
       2) "39.5500007245470826"
  • geopos

    命令:geopos key member [member ...]

    命令描述:从key里返回所有给定位置元素的位置(经度和纬度)。

    返回值:GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。当给定的位置元素不存在时, 对应的数组项为空值。

    示例:

    127.0.0.1:6379> geoadd cities 117.12 39.08 tianjin 114.29 38.02 shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding
    (integer) 1
    127.0.0.1:6379> geopos cities tianjin shijiazhuang
    1) 1) "117.12000042200088501"
       2) "39.0800000535766543"
    2) 1) "114.29000169038772583"
       2) "38.01999994251037407"
  • geodist

    命令:geodist key member1 member2 [unit]

    命令描述:返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。指定单位的参数 unit 必须是以下单位的其中一个:

    • m 表示单位为米(默认)。
    • km 表示单位为千米。
    • mi 表示单位为英里。
    • ft 表示单位为英尺。

    geodist命令在计算距离时会假设地球为完美的球形,在极限情况下,这一假设最大会造成0.5%的误差。

    返回值: 计算出的距离会以双精度浮点数的形式被返回。如果给定的位置元素不存在,那么命令返回空值。

    示例:

    127.0.0.1:6379> geoadd cities 117.12 39.08 tianjin 114.29 38.02 shijiazhuang
    (integer) 0
    127.0.0.1:6379> geodist cities tianjin shijiazhuang
    "272929.6477"
    127.0.0.1:6379> geodist cities tianjin shijiazhuang km
    "272.9296"
    127.0.0.1:6379> geodist cities beijing aaa
    (nil)
  • georadius

    命令:georadius key longitude latitude radius m|km|ft|mi [withcoord][withdist][withhash][asc|desc][count count]

    命令描述:以给定的经纬度为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素。

    范围可以使用以下其中一个单位:

    • m 表示单位为米。
    • km 表示单位为千米。
    • mi 表示单位为英里。
    • ft 表示单位为英尺。

    在给定以下可选项时, 命令会返回额外的信息:

    • WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
    • WITHCOORD: 将位置元素的经度和维度也一并返回。
    • WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。

    命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:

    • ASC: 根据中心的位置, 按照从近到远的方式返回位置元素。
    • DESC: 根据中心的位置, 按照从远到近的方式返回位置元素。

    在默认情况下, georadius命令会返回所有匹配的位置元素。 虽然用户可以使用 COUNT 选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。 但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。

    返回值:

    • 在没有给定任何 WITH 选项的情况下, 命令只会返回一个像 [“New York”,”Milan”,”Paris”] 这样的线性(linear)列表。
    • 在指定了 WITHCOORDWITHDISTWITHHASH 等选项的情况下, 命令返回一个二层嵌套数组, 内层的每个子数组就表示一个元素。

    示例:

    #withdist 返回位置名称和中心距离
    127.0.0.1:6379> georadius cities 117 39 200 km withdist
    1) 1) "baoding"
       2) "158.0144"
    2) 1) "beijing"
       2) "87.0941"
    3) 1) "tianjin"
       2) "13.6619"
    4) 1) "tangshan"
       2) "96.7842"
    #withcoord 返回位置名称和经纬度
    127.0.0.1:6379> georadius cities 117 39 200 km withcoord
    1) 1) "baoding"
       2) 1) "115.28999894857406616"
          2) "38.50999956342798924"
    2) 1) "beijing"
       2) 1) "116.28000229597091675"
          2) "39.5500007245470826"
    3) 1) "tianjin"
       2) 1) "117.12000042200088501"
          2) "39.0800000535766543"
    4) 1) "tangshan"
       2) 1) "118.01000028848648071"
          2) "39.37999951111137165"
    #withdist withcoord 返回位置名称 距离 和经纬度
    127.0.0.1:6379> georadius cities 117 39 200 km withdist withcoord
    1) 1) "baoding"
       2) "158.0144"
       3) 1) "115.28999894857406616"
          2) "38.50999956342798924"
    2) 1) "beijing"
       2) "87.0941"
       3) 1) "116.28000229597091675"
          2) "39.5500007245470826"
    3) 1) "tianjin"
       2) "13.6619"
       3) 1) "117.12000042200088501"
          2) "39.0800000535766543"
    4) 1) "tangshan"
       2) "96.7842"
       3) 1) "118.01000028848648071"
          2) "39.37999951111137165"
    
  • georadiusbymember

    命令:georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

    命令描述:这个命令和 georadius命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的。

    示例:

    127.0.0.1:6379> geoadd cities 117.12 39.08 tianjin 114.29 38.02 shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding
    (integer) 4
    127.0.0.1:6379> georadiusbymember cities tianjin 100 km
    1) "tianjin"
    2) "tangshan"
    127.0.0.1:6379> georadiusbymember cities:locations tianjin 100 km count 1
    1) "tianjin"
  • geohash

    命令:geohash key member [member...]

    命令描述: Redis使用geohash将二维经纬度转换为一维字符串,字符串越长表示位置更精确,两个字符串越相似表示距离越近。

    返回值:一个数组,数组的每个项都是一个geohash。命令返回的geohash的位置与用户给定的位置元素的位置一一对应。

    示例:

    127.0.0.1:6379> geoadd cities 118.01 39.38 tangshan 115.29 38.51 baoding
    (integer) 0
    127.0.0.1:6379> geohash cities tangshan baoding
    1) "wx5bj2um070"
    2) "wwcgp6x9580"
  • zrem

    GEO没有提供删除成员的命令,但是因为GEO的底层实现是zset,所以可以借用zrem命令实现对地理位置信息的删除.

    示例:

    127.0.0.1:6379> zrem cities tianjin
    (integer) 1

原文地址:https://www.cnblogs.com/sleepingspring/p/12120623.html

时间: 2024-11-02 22:15:19

Redis三种特殊数据类型:HyperLogLog、BigMap、Geo的相关文章

pl/sql三种特殊数据类型

pl/sql除了可以使用Orecle规定的基本类型外,还提供了3种特殊的数据类型%type类型.record类型和%rowtype类型. [%type类型] 使用%type可以声明一个与指定列名称相同的数据类型,例如 :v_id emp.id%type 是声名一个和emp表中id字段相同类型的变量. 使用%type定义变量有两点好处:第一,定义变量时不必查看表中各个列的数据类型:第二,如果表中列数据类型进行了修改,使用%type定义的变量会自动进行调整. [ record类型] 也称记录类型,使

Python三种基础数据类型:列表list,元祖tuple和字典dict

Python的三种基本数据类型,列表list,元祖tuple和字典dict 列表List:python最基础的数据类型,列表内的数据项不需要具有相同的类型,可以包含重复值.列表包括两个模块,元素及对应的索引,其中索引正值表示从头开始取,负值表示倒项取数. 操作:索引.切片.加.减.乘.检查成员 索引:查看某个索引的值my_list[1],查看系列的值my_list[1:5] 切片:my_list[1:5],注意:my_list[::n]该用法表示从取的元素开始取第n元素,依次类推 加和乘:表示对

Jedis连接Redis三种模式

这里说的三种工作模式是指: 1.单机模式 2.分片模式 3.集群模式(since 3.0) 说明图详见以下: 使用单机模式连接: 1 private String addr="192.168.1.1"; 2 private String port="6236"; 3 private String key="key"; 4 private Jedis jedis=new Jedis(addr,port);//Jedis获取到的Redis数据在jed

Redis 5种主要数据类型和命令

redis是键值对的数据库,有5中主要数据类型: 字符串类型(string),散列类型(hash),列表类型(list),集合类型(set),有序集合类型(zset) 一:字符串类型string 字符串类型是Redis的最基本类型,它可以存储任何形式的字符串.其它的四种类型都是字符串类型的不同形式. 最基本的命令:GET.SET         语法:GET key,SET key value   value如果有空格需要双引号以示区分 整数递增:INCR                    

Python的三种基本数据类型

数字 int(整型) long(长整型),python对长整型没有限制,理论上可以无限大.python3后没有long了. float 字符串 加了引号的都是字符串. 单引号和双引号没有约束,尽量避免使用反斜杠转移 words = 'Hi,this\'s my buddy' words = "Hi,this's my buddy" 如果表达一段话的话只能用三个单引号或者双引号,否则会报错. 字符串拼接: In [1]: name = 'Edward' In [2]: age = '27

Redis三种集群模式-哨兵机制

Redis哨兵机制,一主二从 注:Redis哨兵切换,建议一主多从 一.一主二从 教程步骤:https://www.cnblogs.com/pinghengxing/p/11139997.html 二.哨兵配置(sentinel.conf) 哨兵机制也分单台以及集群,在此我们只构建哨兵集群      cd /usr/software/redis/redis-ms/ 1.创建哨兵目录 /usr/software/redis/redis-ms/sentinel/26001 /usr/software

redis三种连接方式

安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接make 编译 make #可使用root用户执行`make install`,将可执行文件拷贝到/usr/local/bin目录下.这样就可以直接敲名字运行程序了. make install 启动 #加上`&`号使redis以后台程序方式运行 ./redis-server & 检测 #检测后台进程是否存在 ps -ef |grep redis #检测6379端口是否在监听 netstat -

Redis五种常用数据类型

string 字符串常用操作 1.存入字符串键值对  SET key value 2.批量存储字符串键值对  MSET key value [key value ...] 3.获取一个字符串键值  GET key 4.批量获取字符串键值  MGET key [key ...] 5.删除一个键  DEL key [key ...] 6.设置一个键的过期时间(秒)  EXPIRE key seconds 原子加减 1.将key中存储的数字值加一  INCR key 2.将key中存储的数字值减一  

[redis]redis五种数据类型命令汇总整理

redis所有命令参考中文版 键key 命令 时间复杂度 命令描述 返回值 del key O(N) 在key存在时删除key 被移除key的数量 dump key O(N) 序列话给定key,并返回被序列化的值 exists key O(1) 检查给定key是否存在 若key存在,返回1,否则返回0. expire key seconds O(1) 为给定key设置过期时间 设置成功返回1. 当key不存在或者不能为key设置生存时间时(比如在低于2.1.3中你尝试更新key的生存时间),返回