Redis系列二 | 数据类型和基础知识

1.4 Redis基础知识

1.4.1 默认数据库

Redis默认数据库数量有16个,redis.conf配置文件可查看,默认使用的数据库为0

image-20211110214633888

image-20211110214733336

1.4.2 切换数据库

# 使用select 命令进行切换
[root@yunmx bin]# redis-cli -p 6379
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> select 16
(error) ERR DB index is out of range
127.0.0.1:6379[2]> select 15
OK
127.0.0.1:6379[15]> 

1.4.3 查看数据库大小

# DBSIZE 查看数据库大小
127.0.0.1:6379> set name hejie
OK
127.0.0.1:6379> DBSIZE
(integer) 1
127.0.0.1:6379> SET AGE NAN
OK
127.0.0.1:6379> DBSIZE
(integer) 2
127.0.0.1:6379>

1.4.4 查看所有的key

# 使用keys *
127.0.0.1:6379> keys *
1) "AGE"
2) "name"
127.0.0.1:6379>

1.4.5 清空数据库

# 清空当前数据库flushdb
127.0.0.1:6379> keys *
1) "AGE"
2) "name"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
# 清空所有数据库flush
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> set name hejie
OK
127.0.0.1:6379> set key1 hejie1
OK
127.0.0.1:6379> set key2 hejie2
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key2"
3) "name"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> set name yunmx
OK
127.0.0.1:6379[1]> set key1 yunmx1
OK
127.0.0.1:6379[1]> set key2 yunmx2
OK
127.0.0.1:6379[1]> keys *
1) "key1"
2) "key2"
3) "name"
127.0.0.1:6379[1]> flushall
OK
127.0.0.1:6379[1]> keys *
(empty array)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>

1.4.6 判断key是否存在

# 使用exists 判断
127.0.0.1:6379> set name hejie
OK
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> exists age     
(integer) 1							# 存在
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists key1  
(integer) 0							# 不存在
127.0.0.1:6379>

1.4.7 移动一个key

# move移动一个key
127.0.0.1:6379> set key1 hejie
OK
127.0.0.1:6379> set key2 hejie1
OK
127.0.0.1:6379> set key3 hejie2
OK
127.0.0.1:6379> move key1 1      	# 将key1移动给数据库1
(integer) 1
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "key1"
127.0.0.1:6379[1]>

1.4.8 设置key的生效时间

# EXPIRE 设置一个key的过期时间,单位时间:s
# TTL 查看一个key的过期时间
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
127.0.0.1:6379> get key3
"hejie2"
127.0.0.1:6379> EXPIRE key3 10     # 设置key3 10秒后过期
(integer) 1
127.0.0.1:6379> ttl key3
(integer) -2					   # 表示已经过期
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> keys *
1) "key2"
127.0.0.1:6379>

1.4.9 Redis单线程

单线程为什么这么快?

C语言写的,官方表示每秒的QPS是100000+,基于内存操作,Redis的瓶颈和服务器的内存和网络带宽有关,既然可以用单线程实现,就用单线程喽。

误区:

高性能服务器一定是多线程的?

多线程一定比单线程效率高?

核心:Redis是将所有数据放在内存中的,所以说使用单线程去操作效率就是最高的,因为多线程会产生CPU上下文切换,消耗时间的操作,对于内存系统来说,没有上下文切换,效率就是最高的,多次读写都是在一个CPU上的

1.5 Redis数据类型

五大数据类型

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

image-20211116095814601

使用场景:value除了是字符串还可以是我们的数字

  • 计数器
  • 统计多单位的数量
  • 粉丝数
  • 对象缓存存储

1.5.1 String(字符串)

### 常见用法
127.0.0.1:6379> set kye1 yunmx								# 设置一个key
OK
127.0.0.1:6379> get key1									# 获取一个key的值
(nil)
127.0.0.1:6379> keys *										# 查看当前库的所有key,输出key名
1) "kye1"
127.0.0.1:6379> EXISTS kye1									# 判断key是否存在
(integer) 1
127.0.0.1:6379> EXISTS key1
(integer) 0
127.0.0.1:6379> APPEND kye1 "helloworld"					# 向key追加内容,如果key不存在,就设置一个key
(integer) 15
127.0.0.1:6379> get kye1
"yunmxhelloworld"
127.0.0.1:6379> STRLEN kye1 								# 获取一个key的长度
(integer) 15
127.0.0.1:6379> 

### 自增长用法
127.0.0.1:6379> set count 0
OK
127.0.0.1:6379> get count
"0"
127.0.0.1:6379> incr count									# 自增1
(integer) 1
127.0.0.1:6379> get count
"1"
127.0.0.1:6379> incr count									
(integer) 2
127.0.0.1:6379> get count
"2"
127.0.0.1:6379> decr count									# 自减1
(integer) 1
127.0.0.1:6379> get count
"1"
127.0.0.1:6379> decr count
(integer) 0
127.0.0.1:6379> get count
"0"
127.0.0.1:6379> incrby count 5								# 自增;步长5
(integer) 5
127.0.0.1:6379> get count
"5"
127.0.0.1:6379> decrby count 5								# 自减;步长5
(integer) 0
127.0.0.1:6379> get count
"0"

### 获取字符串范围
127.0.0.1:6379> set key1 yunmxhejie							# 设置一个key
OK
127.0.0.1:6379> getrange key1 0 4							# 获取从标0到4范围的字符串
"yunmx"
127.0.0.1:6379> getrange key1 0 -1							# 获取全部的字符串
"yunmxhejie"
127.0.0.1:6379> 

### 替换
127.0.0.1:6379> set key1 yunmx123456						# 设置一个key
OK
127.0.0.1:6379> SETRANGE key1 0 hejie						# 从下标为0的位置开始替换
(integer) 11
127.0.0.1:6379> get key1
"hejie123456"
127.0.0.1:6379> 

### 设置过期时间
127.0.0.1:6379> setex key1 10 yunmx							# 设置一个key,过期时间为10秒
OK
127.0.0.1:6379> ttl key1									# 查看key的过期时间
(integer) 7
127.0.0.1:6379> ttl key1									# 返回-2表示已经过期
(integer) -2
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> 

### 不存在设置(分布式锁中会经常用到)
127.0.0.1:6379> setnx key2 redis							# setnx:不存在key值则创建
(integer) 1
127.0.0.1:6379> setnx key2 mysql							# setnx:存在key值则创建失败
(integer) 0
127.0.0.1:6379> keys *
1) "key2"
127.0.0.1:6379> 

### 批量设置和获取
127.0.0.1:6379> mset key1 1 key2 2 key3 3 key4 4			# 同时设置多个值
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key4"
3) "key3"
4) "key2"
127.0.0.1:6379> mget key1 key2 key3 key4					# 同时获取多个值
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> msetnx key5 5 key4 4						# 原子性操作:要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get key5
(nil)
127.0.0.1:6379> 

### 对象
127.0.0.1:6379> set user:1 {name:yunmx,age:25}				# 普通设置对象:key加json字符串
OK
127.0.0.1:6379> get user:1
"{name:yunmx,age:25}"
127.0.0.1:6379> mset user:1:name yunmx user:1:age 25		# 巧妙设计对象;如此设计,是完全可以的
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "yunmx"
2) "25"

### 组合命令
127.0.0.1:6379> getset db mysql								# 如果不存在,则设置
(nil)
127.0.0.1:6379> get db
"mysql"
127.0.0.1:6379> getset db MongoDB							# 如果存在,返回当前值,再设置新的值
"mysql"
127.0.0.1:6379> get db
"MongoDB"
127.0.0.1:6379> 

1.5.2 List(列表)

基本的数据类型

image-20211201162836862

基本的数据类型,列表

在redis里面,list可以完成栈、队列、阻塞队列!

用法:

  • 他实际是一个链表,before node after ,left right都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有值,空链表,代表不存在
  • 两边插入或者改动值,效率最高;修改中间元素,相对来说,效率偏低一点

消息排队、消息队列(lpush Rpop) 栈(lpush lpop)

### 基础命令
127.0.0.1:6379> LPUSH key1 1								# 将一个值或者多个值添加到头部
(integer) 1
127.0.0.1:6379> LPUSH key1 2
(integer) 2
127.0.0.1:6379> LPUSH key1 3
(integer) 3
127.0.0.1:6379> LRANGE key1 0 -1							
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> LRANGE key1 0 1
1) "3"
2) "2"
127.0.0.1:6379> rpush key1 5								# 将一个值添加到尾部
(integer) 4
127.0.0.1:6379> LRANGE key1 0 -1
1) "3"
2) "2"
3) "1"
4) "5"

### 移除元素
127.0.0.1:6379> LRANGE key1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> LPOP key1									# 移除列表的第一个元素
"5"
127.0.0.1:6379> rPOP key1									# 移除列表的最后一个元素
"1"
127.0.0.1:6379> LRANGE key1 0 -1
1) "4"
2) "3"
3) "2"

### 获取元素、列表长度
127.0.0.1:6379> LRANGE key1 0 -1
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> LINDEX key1 0								# 获取列表中的第一个元素
"4"
127.0.0.1:6379> LINDEX key1 1
"3"
127.0.0.1:6379> LINDEX key1 2
"2"
127.0.0.1:6379> LINDEX key1 3
(nil)
127.0.0.1:6379> LLEN key1									# 获取列表长度
(integer) 3

### 移除指定的值
 127.0.0.1:6379> LRANGE key1 0 -1
1) "2"
2) "4"
3) "4"
4) "3"
5) "2"
127.0.0.1:6379> LREM key1 1 2								# 移除一个2
(integer) 1
127.0.0.1:6379> LRANGE key1 0 -1
1) "4"
2) "4"
3) "3"
4) "2"
127.0.0.1:6379> LREM key1 2 4								# 移除2个4
(integer) 2
127.0.0.1:6379> LRANGE key1 0 -1
1) "3"
2) "2"

### 截取
127.0.0.1:6379> LRANGE key1 0 -1
1) "15"
2) "14"
3) "13"
4) "12"
5) "11"
6) "10"
127.0.0.1:6379> LTRIM key1 0 3								# 通过下标截取指定的长度,list已经被改变了
OK
127.0.0.1:6379> LRANGE key1 0 -1
1) "15"
2) "14"
3) "13"
4) "12"

### 组合命令:rpoppush
127.0.0.1:6379> rpush list1 1 2 3 4 5 
(integer) 5
127.0.0.1:6379> LRANGE list1 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> rpoplpush list1 list2					# 移除列表中的最后一个元素,并加入到新的列表中
"5"
127.0.0.1:6379> LRANGE list1 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> LRANGE list2 0 -1
1) "5"
127.0.0.1:6379> 

### 元素更新
127.0.0.1:6379> EXISTS list1						# 判断列表是否存在
(integer) 0
127.0.0.1:6379> lset list1 0 yunmx					# 不存在报错
(error) ERR no such key
127.0.0.1:6379> lpush lista1 1 2 3 4
(integer) 4
127.0.0.1:6379> LRANGE list1 0 0
(empty array)
127.0.0.1:6379> LRANGE list1 0 -1
(empty array)
127.0.0.1:6379> LRANGE lista1 0 0
1) "4"
127.0.0.1:6379> lset lista1 0 yunmx						# 存在修改当前下标的值
OK
127.0.0.1:6379> LRANGE lista1 0 0
1) "yunmx"

### 元素插入
127.0.0.1:6379> LRANGE lista1 0 -1
1) "yunmx"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> LINSERT lista1 before yunmx hejie		# 插入当前元素的前面
(integer) 5
127.0.0.1:6379> LINSERT lista1 after yunmx hejie1		# 插入当前元素的后面
(integer) 6
127.0.0.1:6379> LRANGE lista1 0 -1
1) "hejie"
2) "yunmx"
3) "hejie1"
4) "3"
5) "2"
6) "1"

1.5.3 Set(集合)

set中的值不能重复d ,是无序的

### 基础用法
127.0.0.1:6379> sadd set1 yunmx													# 往集合里面存值
(integer) 1
127.0.0.1:6379> sadd set1 hejie1
(integer) 1
127.0.0.1:6379> sadd set1 hejie01
(integer) 1
127.0.0.1:6379> sadd set1 hejie02
(integer) 1
127.0.0.1:6379> sadd set1 hejie02
(integer) 0
127.0.0.1:6379> SMEMBERS set1													# 查询集合里面所有的元素
1) "yunmx"
2) "hejie02"
3) "hejie01"
4) "hejie1"
127.0.0.1:6379> SISMEMBER set1 hejie											# 判断元素是否存在
(integer) 0
127.0.0.1:6379> SISMEMBER set1 hejie5
(integer) 0
127.0.0.1:6379> SISMEMBER set1 hejie1											# 存在返回1
(integer) 1

### 获取集合中的元素的个数
127.0.0.1:6379> SCARD set1
(integer) 4
127.0.0.1:6379> sadd set1 hejie09
(integer) 1
127.0.0.1:6379> SCARD set1
(integer) 5

### 移除set集合中的指定元素
127.0.0.1:6379> SREM set1 yunmx													# 移除set集合中的:yunmx
(integer) 1
127.0.0.1:6379> SCARD set1							
(integer) 4
127.0.0.1:6379> SMEMBERS set1												
1) "hejie01"
2) "hejie09"
3) "hejie1"
4) "hejie02"

### 抽随机用法(无序不重复)
127.0.0.1:6379> SRANDMEMBER set1												# 随机抽选出一个元素
"hejie02"
127.0.0.1:6379> SRANDMEMBER set1
"hejie09"
127.0.0.1:6379> SRANDMEMBER set1
"hejie02"
127.0.0.1:6379> SRANDMEMBER set1
"hejie09"
127.0.0.1:6379> SRANDMEMBER set1
"hejie01"
127.0.0.1:6379> SRANDMEMBER set1 2												# 随机抽选出指定的数量元素
1) "hejie1"
2) "hejie01"
127.0.0.1:6379> SRANDMEMBER set1 2
1) "hejie09"
2) "hejie02"
127.0.0.1:6379> SRANDMEMBER set1 2
1) "hejie1"
2) "hejie01"

### 随机移除元素
127.0.0.1:6379> SMEMBERS set1
1) "hejie01"
2) "hejie09"
3) "hejie1"
4) "hejie02"
127.0.0.1:6379> spop set1														# 随机移除一个元素
"hejie02"
127.0.0.1:6379> spop set1
"hejie1"
127.0.0.1:6379> SMEMBERS set1
1) "hejie01"
2) "hejie09"

### 指定的值移动另一个集合中
127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SMEMBERS set2
1) "er"
2) "san"
3) "yi"
127.0.0.1:6379> smove set1 set2 1												# 将set1中的元素移动到set2,需要移动的值为set1中的1
(integer) 1
127.0.0.1:6379> SMEMBERS set1
1) "2"
2) "3"
127.0.0.1:6379> SMEMBERS set2
1) "1"
2) "er"
3) "san"
4) "yi"

### 共同关注:B站,微博(并集)
# 数字集合:差集、交集、并集
127.0.0.1:6379> sadd set1 1 2 3 4 5 6
(integer) 6
127.0.0.1:6379> sadd set2 4 5 6 7 8 9
(integer) 6
127.0.0.1:6379>
127.0.0.1:6379> SDIFF set1 set2												# 差集:set1中的元素不存在于set2
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SINTER set1 set2											# 交集
1) "4"
2) "5"
3) "6"
127.0.0.1:6379> SDIFF set2 set1
1) "7"
2) "8"
3) "9"
127.0.0.1:6379> SUNION set1 set2										  	# 并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
9) "9"

1.5.4 Hash(哈希)

Map集合,key-Map集合,本质和string没有太大区别,还是一个简单的key-vlaue

应用

  • 用户信息之类的
  • 经常变动的信息
  • 更适合存储对象,string更适合字符串存储
### 基础用法
127.0.0.1:6379> hset hash1 name yunmx										# 设置一个key-vlaue 
(integer) 1
127.0.0.1:6379> hget hash1 name												# 获取一个字段值
"yunmx"
127.0.0.1:6379> hmset hash1 name hejie age 28								# 设置多个
OK
127.0.0.1:6379> hgetall hash1												# 获取所有元素
1) "name"
2) "hejie"
3) "age"
4) "28"
127.0.0.1:6379> hget hash1 age												# 获取一个字段值
"28"

### 删除一个值
127.0.0.1:6379> HDEL hash1 name												# 删除指定的key字段
(integer) 1
127.0.0.1:6379> hgetall hash1
1) "age"
2) "28"

### 获取hash所有的长度(键值对)
127.0.0.1:6379> HLEN hash1													# 获取hash中的键值对数量
(integer) 1
127.0.0.1:6379> hset hash1 age 18
(integer) 0
127.0.0.1:6379> hset hash1 age1 19
(integer) 1
127.0.0.1:6379> hset hash1 name hejie
(integer) 1
127.0.0.1:6379> HLEN hash1
(integer) 3

### 判断hash中字段是否存在
127.0.0.1:6379> HGETALL hash1
1) "age"
2) "18"
3) "age1"
4) "19"
5) "name"
6) "hejie"
127.0.0.1:6379> HEXISTS hash1 age											# 判断哈希中是否存在age字段
(integer) 1
127.0.0.1:6379> HEXISTS hash1 yunmx
(integer) 0

### 只获取所有的字段或值
127.0.0.1:6379> hkeys hash1
1) "age"
2) "age1"
3) "name"
127.0.0.1:6379> HVALS hash1
1) "18"
2) "19"
3) "hejie"

### 指定自增
127.0.0.1:6379> HINCRBY hash1 age 1											# 自增1
(integer) 19
127.0.0.1:6379> HINCRBY hash1 age -1
(integer) 18
127.0.0.1:6379> hsetnx hash1 age 1											# 如果存在,不设置
(integer) 0
127.0.0.1:6379> hsetnx hash1 age2 1											# 不存在,则添加新的键值对
(integer) 1

1.5.5 Zset(有序集合)

在set的基础上增加了一个值,多了一个计数位

场景思路:

  • set能做的东西它都能做,存储班级成绩表、工资表排序
  • 普通消息1,重要消息2,带权重进行判断
  • 排行榜应用实现:TOP N
### 基础用法
127.0.0.1:6379> zadd myset 1 one											# 添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 two
(integer) 1
127.0.0.1:6379> zadd myset 3 three
(integer) 1
127.0.0.1:6379> zadd myset 4 four 5 five									# 添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1											# 查看所有的值
1) "one"
2) "two"
3) "three"
4) "four"
5) "five"

### 排序如何实现
# 用法:从最小到最大
# ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
127.0.0.1:6379> zadd salary 12000 yunmx										# 添加4个用户
(integer) 1
127.0.0.1:6379> zadd salary 11000 hejie
(integer) 1
127.0.0.1:6379> zadd salary 10000 hejie01
(integer) 1
127.0.0.1:6379> zadd salary 9000 yunmx01
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf								# -inf +inf  负无穷到正无穷 从小到大
1) "yunmx01"
2) "hejie01"
3) "hejie"
4) "yunmx"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores					# withscores表示带一些其他参数说明
1) "yunmx01"
2) "9000"
3) "hejie01"
4) "10000"
5) "hejie"
6) "11000"
7) "yunmx"
8) "12000"

### 移除元素
127.0.0.1:6379> ZRANGE salary 0 -1											# 查看所有的元素
1) "yunmx01"
2) "hejie01"
3) "hejie"
4) "yunmx"
127.0.0.1:6379> zrem salary yunmx01											# 移除特定的元素
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "hejie01"
2) "hejie"
3) "yunmx"

### 获取有序集合中的个数
127.0.0.1:6379> ZRANGE salary 0 -1
1) "hejie01"
2) "hejie"
3) "yunmx"
127.0.0.1:6379> ZCARD salary
(integer) 3

### 按区间计算
127.0.0.1:6379> ZRANGE salary 0 -1
1) "hejie01"
2) "hejie"
3) "yunmx"
127.0.0.1:6379> zcount salary 1000 9000										# 查看1000到9000之间的数量
(integer) 0
127.0.0.1:6379> zcount salary 1000 10000									# 查看1000到1-000之间的数量值
(integer) 1

1.5.6 geospatial(地理空间)

城市经纬度查询:http://www.jsons.cn/lngcode/

  • 朋友圈的定位
  • 附近的人
  • 打车距离计算

GEO实现的底层原理其实就是Zset!可以使用Zset来操作GEO!

只有6个命令

  • GEOADD
  • GEODIST
  • GEOHASH
  • GEOPOS
  • GEORADIUS
  • GEORADIUSBYMEMBER
### 添加位置
# geoadd key longitude(经度) latitude(维度) member [longitude latitude member ...]  可添加多个
# 参数:key 值(经度 维度 名称)
127.0.0.1:6379> geoadd china:city 104.065735 30.659462 chengdu
(integer) 1
127.0.0.1:6379> geoadd china:city 106.504962 29.533155 chongqing
(integer) 1

### 获取当前定位经纬度
127.0.0.1:6379> GEOPOS china:city chengdu									# 获取成都的经纬度
1) 1) "104.06573742628097534"
   2) "30.65946118872339099"
127.0.0.1:6379> GEOPOS china:city chongqing									# 获取重庆的经纬度
1) 1) "106.50495976209640503"
   2) "29.53315530684997015"

### 计算两个地方的距离
#单位:m/km/mi/ft
127.0.0.1:6379> geodist china:city chengdu chongqing m						# 计算出成都到重庆的直线距离  单位m 
"266056.2971"
127.0.0.1:6379> geodist china:city chengdu chongqing km						# 计算出成都到重庆的直线距离  单位km
"266.0563"

### 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
# GEORADIUS:
127.0.0.1:6379> GEORADIUS china:city 103 30 1 km							# 以103 30这个点为中心,以1km为半径
(empty array)
127.0.0.1:6379> GEORADIUS china:city 103 30 2 km
(empty array)
127.0.0.1:6379> GEORADIUS china:city 103 30 20 km
(empty array)
127.0.0.1:6379> GEORADIUS china:city 103 30 200 km
1) "chengdu-qingyangqu"
2) "chengdu"
3) "chengdu-jinjiangqu"
127.0.0.1:6379> GEORADIUS china:city 103 30 20000 km
1) "chengdu-qingyangqu"
2) "chongqing"
3) "chengdu"
4) "chengdu-jinjiangqu"					
127.0.0.1:6379> GEORADIUS china:city 103 30 20000 km withcoord				# 附带显示经纬度	
1) 1) "chengdu-qingyangqu"
   2) 1) "104.06151026487350464"
      2) "30.67387107851423167"
2) 1) "chongqing"
   2) 1) "106.50495976209640503"
      2) "29.53315530684997015"
3) 1) "chengdu"
   2) 1) "104.06573742628097534"
      2) "30.65946118872339099"
4) 1) "chengdu-jinjiangqu"
   2) 1) "104.06573742628097534"
      2) "30.65946118872339099"

### 找出位于指定范围内的元素,中心点是由给定的位置元素决定
# GEORADIUSBYMEMBER
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chengdu 10 km					# chengdu城市方圆10km的坐标
1) "chengdu"
2) "chengdu-jinjiangqu"
3) "chengdu-qingyangqu"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chengdu 100 km
1) "chengdu"
2) "chengdu-jinjiangqu"
3) "chengdu-qingyangqu"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chengdu 10 km
1) "chengdu"
2) "chengdu-jinjiangqu"
3) "chengdu-qingyangqu"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chengdu 1000 km
1) "chengdu-qingyangqu"
2) "chongqing"
3) "chengdu"
4) "chengdu-jinjiangqu"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chengdu 1000 km withcoord		# 附带坐标信息
1) 1) "chengdu-qingyangqu"
   2) 1) "104.06151026487350464"
      2) "30.67387107851423167"
2) 1) "chongqing"
   2) 1) "106.50495976209640503"
      2) "29.53315530684997015"
3) 1) "chengdu"
   2) 1) "104.06573742628097534"
      2) "30.65946118872339099"
4) 1) "chengdu-jinjiangqu"
   2) 1) "104.06573742628097534"
      2) "30.65946118872339099"

### Redis GEOHASH 命令 - 返回一个或多个位置元素的 Geohash 表示  不常用

1.5.7 HyperLogLog(基数统计)

基数:不重复的元素个数,可以接受误差

A(1 2 3 45 5 78)

B(3 4 6 7 8 9 0 9 78 )

基数统计的算法

  • 网页的UV(一个人访问一个网站,但是还是算做一个)

    传统的方式:set保存用户的ID,然后就可以统计set中的元素数量作为标准判断,如果保存大量的用户ID,就会比较麻烦,我们的目的是为了计数而不是保存ID

  • 占用内存是固定的,2^64不同的元素技术,只需要废12KB内存

0.81%的错误率!统计UV时候,可以忽略不计

127.0.0.1:6379> PFADD key1 a 1 2 3 4 b c 6 7 9								# 设置一个HyperLOGLOG		
(integer) 1
127.0.0.1:6379> PFCOUNT key1												# 查看里面不重复的数量个数			
(integer) 10
127.0.0.1:6379> PFADD key2 a a  1 2 3 4 b c 6 7 9 10 10 101 10 10 8 6
(integer) 1
127.0.0.1:6379> PFCOUNT key2
(integer) 13
127.0.0.1:6379> PFMERGE key3 key1 key2										# 合并两个key的元素数量
OK
127.0.0.1:6379> PFCOUNT key3												# 查看不重复的元素数量
(integer) 13

1.5.8 Bitmap(位图)

位存储0和1

2个状态的都可以使用此数据类型

  • 活跃、不活跃
  • 感染人数、未感染人数
127.0.0.1:6379> SETBIT key 0 1												# 使用Bitmaps记录一周的打卡
(integer) 0
127.0.0.1:6379> SETBIT key 1 0
(integer) 0
127.0.0.1:6379> SETBIT key 2 0
(integer) 0
127.0.0.1:6379> SETBIT key 3 1
(integer) 0
## 查看某一天是否有打卡
127.0.0.1:6379> getbit key 3
(integer) 1
127.0.0.1:6379> getbit key 2
(integer) 0

### 统计操作
# 统计打开天数
127.0.0.1:6379> BITCOUNT key
(integer) 2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值