网站如何做二维码我厂有大量手工活外发加工

当前位置: 首页 > news >正文

网站如何做二维码,我厂有大量手工活外发加工,全国被执行人名单查询,长沙河东做网站背景 之前#xff0c;我们学习了 Redis 的 5 大基本数据类型#xff1a;String、List、Hash、Set 和 Sorted Set#xff0c;它们可以满足大多数的数据存储需求#xff0c;但是在面对海量数据统计时#xff0c;它们的内存开销很大#xff0c;而且对于一些特殊的场景…背景 之前我们学习了 Redis 的 5 大基本数据类型String、List、Hash、Set 和 Sorted Set它们可以满足大多数的数据存储需求但是在面对海量数据统计时它们的内存开销很大而且对于一些特殊的场景它们是无法支持的。所以Redis 还提供了 3 种扩展数据类型分别是 Bitmap、HyperLogLog 和 GEO。前两种我们已经重点介绍过了今天再具体讲一讲 GEO。 面向 LBS 应用的 GEO 数据类型 在日常生活中我们越来越依赖搜索“附近的餐馆”、在打车软件上叫车这些都离不开基于位置信息服务Location-Based ServiceLBS的应用。LBS 应用访问的数据是和人或物关联的一组经纬度信息而且要能查询相邻的经纬度范围GEO 就非常适合应用在 LBS 服务的场景中我们来看一下它的底层结构。 GEO 的底层结构 一般来说在设计一个数据类型的底层结构时我们首先需要知道要处理的数据有什么访问特点。所以我们需要先搞清楚位置信息到底是怎么被存取的。 以叫车服务为例来分析下 LBS 应用中经纬度的存取特点 每一辆网约车都有一个编号例如 33网约车需要将自己的经度信息例如 116.034579和纬度信息例如 39.000452 发给叫车应用。用户在叫车的时候叫车应用会根据用户的经纬度位置例如经度 116.054579纬度 39.030452查找用户的附近车辆并进行匹配。等把位置相近的用户和车辆匹配上以后叫车应用就会根据车辆的编号获取车辆的信息并返回给用户。 可以看到一辆车或一个用户对应一组经纬度并且随着车或用户的位置移动相应的经纬度也会变化。 Hash 这种数据记录模式属于一个 key例如车 ID对应一个 value一组经纬度。当有很多车辆信息要保存时就需要有一个集合来保存一系列的 key 和 value。Hash 集合类型可以快速存取一系列的 key 和 value正好可以用来记录一系列车辆 ID 和经纬度的对应关系所以我们可以把不同车辆的 ID 和它们对应的经纬度信息存在 Hash 集合中如下图所示 同时Hash 类型的 HSET 操作命令会根据 key 来设置相应的 value 值所以我们可以用它来快速地更新车辆变化的经纬度信息。 到这里Hash 类型看起来是一个不错的选择。但问题是对于一个 LBS 应用来说除了记录经纬度信息还需要根据用户的经纬度信息在车辆的 Hash 集合中进行范围查询。一旦涉及到范围查询就意味着集合中的元素需要有序但 Hash 类型的元素是无序的显然不能满足我们的要求。 Sortted Set Sorted Set 类型也支持一个 key 对应一个 value 的记录模式其中key 就是 Sorted Set 中的元素而 value 则是元素的权重分数。更重要的是Sorted Set 可以根据元素的权重分数排序支持范围查询。这就能满足 LBS 服务中查找相邻位置的需求了。 实际上GEO 类型的底层数据结构就是用 Sorted Set 来实现的。咱们还是借着叫车应用的例子来加深下理解。 用 Sorted Set 来保存车辆的经纬度信息时Sorted Set 的元素是车辆 ID元素的权重分数是经纬度信息如下图所示 这时问题来了Sorted Set 元素的权重分数是一个浮点数float 类型而一组经纬度包含的是经度和纬度两个值是没法直接保存为一个浮点数的那具体该怎么进行保存呢 这就要用到 GEO 类型中的 GeoHash 编码了。 GeoHash 的编码方法 为了能高效地对经纬度进行比较Redis 采用了业界广泛使用的 GeoHash 编码方法这个方法的基本原理就是“二分区间区间编码”。 当我们要对一组经纬度进行 GeoHash 编码时我们要先对经度和纬度分别编码然后再把经纬度各自的编码组合成一个最终编码。 对于一个地理位置信息来说它的经度范围是[-180,180]。GeoHash 编码会把一个经度值编码成一个 N 位的二进制值我们来对经度范围[-180,180]做 N 次的二分区操作其中 N 可以自定义。 在进行第一次二分区时经度范围[-180,180]会被分成两个子区间[-180,0) 和[0,180]我称之为左、右分区。此时我们可以查看一下要编码的经度值落在了左分区还是右分区。如果是落在左分区我们就用 0 表示如果落在右分区就用 1 表示。这样一来每做完一次二分区我们就可以得到 1 位编码值。 然后我们再对经度值所属的分区再做一次二分区同时再次查看经度值落在了二分区后的左分区还是右分区按照刚才的规则再做 1 位编码。当做完 N 次的二分区后经度值就可以用一个 N bit 的数来表示了。 当一组经纬度值都编完码后我们再把它们的各自编码值组合在一起组合的规则是最终编码值的偶数位上依次是经度的编码值奇数位上依次是纬度的编码值其中偶数位从 0 开始奇数位从 1 开始。 我们刚刚计算的经纬度116.3739.86的各自编码值是 11010 和 10111组合之后第 0 位是经度的第 0 位 1第 1 位是纬度的第 0 位 1第 2 位是经度的第 1 位 1第 3 位是纬度的第 1 位 0以此类推就能得到最终编码值 1110011101如下图所示 用了 GeoHash 编码后原来无法用一个权重分数表示的一组经纬度116.3739.86就可以用 1110011101 这一个值来表示就可以保存为 Sorted Set 的权重分数了。 当然使用 GeoHash 编码后我们相当于把整个地理空间划分成了一个个方格每个方格对应了 GeoHash 中的一个分区。 举个例子。我们把经度区间[-180,180]做一次二分区把纬度区间[-90,90]做一次二分区就会得到 4 个分区。我们来看下它们的经度和纬度范围以及对应的 GeoHash 组合编码。 分区一[-180,0) 和[-90,0)编码 00分区二[-180,0) 和[0,90]编码 01分区三[0,180]和[-90,0)编码 10分区四[0,180]和[0,90]编码 11。 这 4 个分区对应了 4 个方格每个方格覆盖了一定范围内的经纬度值分区越多每个方格能覆盖到的地理空间就越小也就越精准。我们把所有方格的编码值映射到一维空间时相邻方格的 GeoHash 编码值基本也是接近的如下图所示 所以我们使用 Sorted Set 范围查询得到的相近编码值在实际的地理空间上也是相邻的方格这就可以实现 LBS 应用“搜索附近的人或物”的功能了。 不过我要提醒你一句有的编码值虽然在大小上接近但实际对应的方格却距离比较远。例如我们用 4 位来做 GeoHash 编码把经度区间[-180,180]和纬度区间[-90,90]各分成了 4 个分区一共 16 个分区对应了 16 个方格。编码值为 0111 和 1000 的两个方格就离得比较远如下图所示 所以为了避免查询不准确问题我们可以同时查询给定经纬度所在的方格周围的 4 个或 8 个方格。 好了到这里我们就知道了GEO 类型是把经纬度所在的区间编码作为 Sorted Set 中元素的权重分数把和经纬度相关的车辆 ID 作为 Sorted Set 中元素本身的值保存下来这样相邻经纬度的查询就可以通过编码值的大小范围查询来实现了。接下来我们再来聊聊具体如何操作 GEO 类型。 如何操作 GEO 类型 在使用 GEO 类型时我们经常会用到两个命令分别是 GEOADD 和 GEORADIUS。 GEOADD 命令用于把一组经纬度信息和相对应的一个 ID 记录到 GEO 类型集合中GEORADIUS 命令会根据输入的经纬度位置查找以这个经纬度为中心的一定范围内的其他元素。当然我们可以自己定义这个范围。 假设车辆 ID 是 33经纬度位置是116.03457939.030452我们可以用一个 GEO 集合保存所有车辆的经纬度集合 key 是 cars:locations。执行下面的这个命令就可以把 ID 号为 33 的车辆的当前经纬度位置存入 GEO 集合中 GEOADD cars:locations 116.034579 39.030452 33当用户想要寻找自己附近的网约车时LBS 应用就可以使用 GEORADIUS 命令。例如LBS 应用执行下面的命令时Redis 会根据输入的用户的经纬度信息116.05457939.030452 查找以这个经纬度为中心的 5 公里内的车辆信息并返回给 LBS 应用。当然 你可以修改“5”这个参数来返回更大或更小范围内的车辆信息。 GEORADIUS cars:locations 116.054579 39.030452 5 km ASC COUNT 10另外我们还可以进一步限定返回的车辆信息。 比如我们可以使用 ASC 选项让返回的车辆信息按照距离这个中心位置从近到远的方式来排序以方便选择最近的车辆还可以使用 COUNT 选项指定返回的车辆信息的数量。毕竟5 公里范围内的车辆可能有很多如果返回全部信息会占用比较多的数据带宽这个选项可以帮助控制返回的数据量节省带宽。 如何自定义数据类型 为了实现自定义数据类型首先我们需要了解 Redis 的基本对象结构 RedisObject因为 Redis 键值对中的每一个值都是用 RedisObject 保存的。 RedisObject 包括元数据和指针。其中元数据的一个功能就是用来区分不同的数据类型指针用来指向具体的数据类型的值。所以要想开发新数据类型我们就先来了解下 RedisObject 的元数据和指针。 Redis 的基本对象结构 RedisObject 的内部组成包括了 type、encoding、lru 和 refcount 4 个元数据以及 1 个*ptr指针。 type表示值的类型涵盖了我们前面学习的五大基本类型encoding是值的编码方式用来表示 Redis 中实现各个基本类型的底层数据结构例如 SDS、压缩列表、哈希表、跳表等lru记录了这个对象最后一次被访问的时间用于淘汰过期的键值对refcount记录了对象的引用计数ptr是指向数据的指针。 RedisObject 结构借助ptr指针就可以指向不同的数据类型例如ptr指向一个 SDS 或一个跳表就表示键值对中的值是 String 类型或 Sorted Set 类型。所以我们在定义了新的数据类型后也只要在 RedisObject 中设置好新类型的 type 和 encoding再用ptr指向新类型的实现就行了。 开发一个新的数据类型 了解了 RedisObject 结构后定义一个新的数据类型也就不难了。首先我们需要为新数据类型定义好它的底层结构、type 和 encoding 属性值然后再实现新数据类型的创建、释放函数和基本命令。 这里不再缀诉有兴趣的可以自己去研究一下。 小结 这篇文章我们学习了 Redis 的扩展数据类型 GEO。GEO 可以记录经纬度形式的地理位置信息被广泛地应用在 LBS 服务中。GEO 本身并没有设计新的底层数据结构而是直接使用了 Sorted Set 集合类型。 GEO 类型使用 GeoHash 编码方法实现了经纬度到 Sorted Set 中元素权重分数的转换这其中的两个关键机制就是对二维地图做区间划分以及对区间进行编码。一组经纬度落在某个区间后就用区间的编码值来表示并把编码值作为 Sorted Set 元素的权重分数。这样一来我们就可以把经纬度保存到 Sorted Set 中利用 Sorted Set 提供的“按权重进行有序范围查找”的特性实现 LBS 服务中频繁使用的“搜索附近”的需求。 GEO 属于 Redis 提供的扩展数据类型。扩展数据类型有两种实现途径一种是基于现有的数据类型通过数据编码或是实现新的操作的方式来实现扩展数据类型例如基于 Sorted Set 和 GeoHash 编码实现 GEO以及基于 String 和位操作实现 Bitmap另一种就是开发自定义的数据类型具体的操作是增加新数据类型的定义实现创建和释放函数实现新数据类型支持的命令操作。