1.4 Redis基础知识
1.4.1 默认数据库
Redis默认数据库数量有16个,redis.conf配置文件可查看,默认使用的数据库为0
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)。
使用场景: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(列表)
基本的数据类型
基本的数据类型,列表
在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