Redis(Remote Dictionary Server,远程字典服务)是一个开源的 使用 ANSI C语言 编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。
Redis 的主要用途如下:
扩展:Redis 和 传统的关系型数据库 的区别
存储方式:
1、Redis是一种基于键值对的NoSQL数据库,而键值对的值是由多种数据结构和算法组成的。
2、关系型数据库是基于二维数据表来存储数据的,它的数据格式更为严谨,并支持关系查询。
存储区域:
1、Redis的数据都存储于内存中,因此它的速度惊人,读写性能可达10万/秒,远超关系型数据库。
2、关系型数据库的数据存储于磁盘上,可以存放海量的数据,但性能远不如Redis。
2.1、Redis 数据库
Redis 有16个数据库(DB0 ~ DB15),默认使用第 0 个,可以使用 select n
切换到 DB n,dbsize
可以查看当前数据库的大小(与 key 数量相关)。
相关命令:
keys *
:查看当前数据库中所有的key。
flushdb
:清空当前数据库中的键值对。
flushall
:清空所有数据库的键值对
2.2、Redis 数据类型
1、Redis 支持5种核心的数据类型: 字符串、哈希、列表、集合、有序集合;
2、Redis 还提供了 Bitmap、HyperLogLog、Geo 类型,但这些类型都是基于上述核心数据类型实现的;
3、 Redis 在5.0新增加了 Streams 数据类型,它是一个功能强大的、支持多播的、可持久化的 消息队列。
2.3、Redis-key
在 Redis 中无论什么数据类型,在数据库中都是以 key-value 形式保存,通过对 Redis-key 的操作,来完成对数据库中数据的操作。
相关命令:
exists key
:判断键是否存在del key
:删除键值对move key db
:将键值对移动到指定数据库expire key second
:设置键值对的过期时间type key
:查看value的数据类型补充:TTL 命令(返回 key 的过期时间,语法为 ttl key
)
相关命令:
set [key] [value]
:添加元素get [key]
:获取元素# 语法
set [key] [value] # 添加元素
get [key] # 获取元素
127.0.0.1:6379> set name hong
OK
127.0.0.1:6379> get name
"hong"
List 是 线性有序 的数据结构,内部元素 可以重复 并 按照 插入顺序排序
List 实际上是一个 双向链表,可以向 List 中的任何位置 插入元素
一个 List 最多可以包含 2^32 - 1 个元素
相关命令:
lpushx/rpushx key value
: 添加元素lpush/rpush key value [value...]
:添加一个或多个元素lrange key start stop
:查询元素linsert key BEFORE|AFTER pivot value
:插入元素llen key
:获取列表长度lindex key index
:获取指定索引的值(从 0 开始)lset key index value
:改变列表某个位置的值lpop/rpop key
:弹出元素rpoplpush source destination
:从当前列表弹出 压入到新的列表ltrim key start stop
:截取列表lrem key count value
:移除元素blpop/brpop key [key ...] timeout
:弹出元素,若列表为空则进入阻塞状态注:命令无特殊说明的话,l 代表 List 。
# 添加 (l 代表从左边插入,r代表从右边插入)
lpushx/rpushx key value # 添加一个元素
lpush/rpush key value [value...] # 添加一个或多个元素
# 查询
lrange key start stop
127.0.0.1:6379> lpush myList 1 2 3
(integer) 3
127.0.0.1:6379> lrange myList 0 -1 # 0 -1 代表查询所有值
1) "3"
2) "2"
3) "1"
# 插入
linsert key BEFORE|AFTER pivot value
127.0.0.1:6379> linsert myList after 3 three
(integer) 4
127.0.0.1:6379> lrange myList 0 -1
1) "3"
2) "three"
3) "2"
4) "1"
# 获取列表长度
llen key
127.0.0.1:6379> llen myList
(integer) 4
# 获取指定索引的值(从 0 开始)
lindex key index
127.0.0.1:6379> lindex myList 1
"three"
# 改变列表某个位置的值
lset key index value
127.0.0.1:6379> lset myList 1 four
OK
127.0.0.1:6379> lrange myList 0 -1
1) "3"
2) "four"
3) "2"
4) "1"
# 弹出 (l 代表从左边插入,r代表从右边插入)
lpop/rpop key
127.0.0.1:6379> rpop myList
OK
127.0.0.1:6379> lrange myList 0 -1
1) "3"
2) "four"
3) "2"
# 从当前列表弹出 压入到新的列表
rpoplpush source destination
127.0.0.1:6379> rpoplpush myList newList
"2"
127.0.0.1:6379> lrange myList 0 -1
1) "3"
2) "four"
127.0.0.1:6379> lrange newList 0 -1
1) "2"
# 截取列表
ltrim key start stop # [start, stop],从 0 开始
127.0.0.1:6379> ltrim myList 0 0
OK
127.0.0.1:6379> lrange myList 0 -1
1) "3"
# 移除元素
lrem key count value # 当 count = -x,代表移除全部
127.0.0.1:6379> lrem myList -1 3
(integer) 1
127.0.0.1:6379> lrange myList 0 -1
(empty list or set)
# 弹出,若列表为空则进入阻塞状态 (l 代表从左边插入,r代表从右边插入)
blpop/brpop key [key ...] timeout # timeout 超时时间,单位为秒
127.0.0.1:6379> blpop myList 5
(nil)
(5.04s)
相关命令:
sadd key value
:添加元素smembers key
:查询元素scard key
:获取集合长度sismember key value
:查询元素是否存在srandmember key count
:随机返回 count 个元素spop key count
:随机移除 count 个元素smove key otherkey value
:移动元素srem key value [value...]
:移除元素sdiff key1 [key2...]
:查询集合的差集sinter key1 [key2...]
:查询集合的交集sunion key1 [key2...]
:查询集合的并集注:命令无特殊说明的话,s 代表 Set 。
# 添加
sadd key value
# 查询
smembers key
127.0.0.1:6379> sadd mySet 1 2 3 4 5
(integer) 5
127.0.0.1:6379> smembers mySet
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
# 获取集合长度
scard key
127.0.0.1:6379> scard mySet
(integer) 5
# 查询元素是否存在
sismember key value
127.0.0.1:6379> sismember mySet 5
(integer) 1
127.0.0.1:6379> sismember mySet 6
(integer) 0
# 随机返回 count 个元素
srandmember key count
127.0.0.1:6379> srandmember mySet 3
1) "2"
2) "4"
3) "1"
# 随机移除 count 个元素
spop key count
127.0.0.1:6379> spop mySet 2
1) "1"
2) "3"
127.0.0.1:6379> smembers mySet
1) "2"
2) "4"
3) "5"
# 移动元素
smove key otherkey value
127.0.0.1:6379> smove mySet newSet 2
(integer) 1
127.0.0.1:6379> smembers mySet
1) "4"
2) "5"
127.0.0.1:6379> smembers newSet
1) "2"
# 移除元素
srem key value [value...]
127.0.0.1:6379> srem mySet 4
(integer) 1
127.0.0.1:6379> smembers mySet
1) "5"
127.0.0.1:6379> sadd mySet 1 2 7 8
(integer) 4
127.0.0.1:6379> sadd newSet 7 8 0 9
(integer) 4
127.0.0.1:6379> smembers mySet
1) "1"
2) "2"
3) "5"
4) "7"
5) "8"
127.0.0.1:6379> smembers newSet
1) "0"
2) "2"
3) "7"
4) "8"
5) "9"
# 查询集合的差集
sdiff key1 [key2...]
127.0.0.1:6379> sdiff mySet newSet
1) "1"
2) "5"
# 查询集合的交集
sinter key1 [key2...]
127.0.0.1:6379> sinter mySet newSet
1) "2"
2) "7"
3) "8"
# 查询集合的并集
sunion key1 [key2...]
127.0.0.1:6379> sunion mySet newSet
1) "0"
2) "1"
3) "2"
4) "5"
5) "7"
6) "8"
7) "9"
相关命令:
hset key field value
:添加元素hget key field
:查询元素hgetall key
:获取全部的元素hdel key field1 [field2...]
:删除元素hlen key
:获取元素数量hexists key field
:判断 hash 中 指定元素 是否存在hincrby key field increment
:增加元素字段的值(字段值为数字)hsetnx key field value
:判断元素是否存在,如果不存在就新增该元素,存在就不作改变命令无特殊说明的话,h 代表 Hash 。
# 添加
hset key field value
# 查询
hget key field
127.0.0.1:6379> hset myHash name yu
(integer) 1
127.0.0.1:6379> hget myHash name
"yu"
127.0.0.1:6379> hset myHash count 100
(integer) 1
127.0.0.1:6379> hget myHash count
"100"
# 获取全部的元素
hgetall key
127.0.0.1:6379> hgetall myHash
1) "name"
2) "yu"
3) "count"
4) "100"
# 删除元素
hdel key field1 [field2...]
127.0.0.1:6379> hdel myHash count
(integer) 1
127.0.0.1:6379> hgetall myHash
1) "name"
2) "yu"
# 获取 hash 的元素数量
hlen key
127.0.0.1:6379> hlen myHash
(integer) 1
# 判断 hash 中指定元素是否存在
hexists key field
127.0.0.1:6379> hexists myHash name
(integer) 1
127.0.0.1:6379> hexists myHash count
(integer) 0
127.0.0.1:6379> hset myHash count 100
(integer) 1
127.0.0.1:6379> hget myHash count
"100"
# 增加元素字段的值(字段值为数字)
hincrby key field increment
127.0.0.1:6379> hincrby myHash count 100
(integer) 200
127.0.0.1:6379> hget myHash count
"200"
# 判断元素是否存在,如果不存在就新增该元素,存在就不作改变
hsetnx key field value
127.0.0.1:6379> hsetnx myHash color blue
(integer) 1
127.0.0.1:6379> hget myHash color
"blue"
127.0.0.1:6379> hsetnx myHash color green
(integer) 0
127.0.0.1:6379> hget myHash color
"blue"
相关命令:
zadd key score value [score value ...]
:添加元素zrange key start end
:查询元素zrangebyscore key min max [withscores]
:元素升序zrevrange key start end
:元素降序zcard key
:获取元素数量zcount key min max
:获取指定区间的元素数量zrem key member
:移除元素命令无特殊说明的话,Z 代表 Zset 。
# 添加
zadd key score value [score value ...]
# 查询
zrange key start end
127.0.0.1:6379> zadd myZset 1 first
(integer) 1
127.0.0.1:6379> zrange myZset 0 -1
1) "first"
127.0.0.1:6379> zadd myZset 2 secord
(integer) 1
127.0.0.1:6379> zadd myZset 3 third
(integer) 1
127.0.0.1:6379> zadd myZset 0 four
(integer) 1
127.0.0.1:6379> zrange myZset 0 -1
1) "four"
2) "first"
3) "secord"
4) "third"
# 排序
## 升序
zrangebyscore key min max [withscores]
127.0.0.1:6379> zrangebyscore myZset 0 3
1) "four"
2) "first"
3) "secord"
4) "third"
127.0.0.1:6379> zrangebyscore myZset 0 3 withscores
1) "four"
2) "0"
3) "first"
4) "1"
5) "secord"
6) "2"
7) "third"
8) "3
## 降序
zrevrange key start end
127.0.0.1:6379> zrevrange myZset 0 -1
1) "third"
2) "secord"
3) "first"
4) "four"
# 获取 Zset 中元素的数量
zcard key
127.0.0.1:6379> zcard myZset
(integer) 4
# 获取指定区间的成员数量
zcount key min max
127.0.0.1:6379> zcount myZset 0 2
(integer) 3
# 移除Zset中的元素
zrem key member
127.0.0.1:6379> zrem myZset first
(integer) 1
127.0.0.1:6379> zrange myZset 0 -1
1) "four"
2) "secord"
3) "third"
相关命令:
geoadd key 经度 纬度 value
:添加地理位置geodist key value1 value2 [m/km/mi/ft]
:获取指定城市的经度和纬度georadius key 经度 纬度 半径 [m/km/mi/ft] [withcoord] [withdist] [WITHHASH] [count number](限定数量)
:通过半径来查询附近的城市geohash key member
:将二维的经纬度转换为一维的字符串# 添加地理位置
# 规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!
# 有效经纬度:
# 有效的经度从 -180度 到 180度
# 有效的纬度从 -85.05112878度 到 85.05112878度
geoadd key 经度 纬度 value
# 获取指定城市的经度和纬度
geopos key value
# 获取两座城市的直线距离
# mi 英里
# ft 英尺
geodist key value1 value2 [m/km/mi/ft]
# 通过半径来查询附近的城市
georadius key 经度 纬度 半径 [m/km/mi/ft] [withcoord] [withdist] [WITHHASH] [count number](限定数量)
georadiusbymember key member radius
# 将二维的经纬度转换为一维的字符串
geohash key member
注:geo 底层实现原理 是 Zset
127.0.0.1:6379> zrange china:city 0 -1 # 查看地图中全部元素
1) "chongqi"
2) "xian"
3) "shenzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"
127.0.0.1:6379> zrem china:city chongqi # 移除指定元素!
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "xian"
2) "shenzhen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
127.0.0.1:6379>
基数统计算法
占用的内存是固定的,存放 2^64 不同的元素,只需要12KB的内存
存在 0.81% 的错误率
相关命令:
pfadd key value
:添加元素pfcount key
:计数pfmerge destkey sourcekey [sourceky...]
:合并# 添加元素
pfadd key value
# 计数
pfcount key
# 合并 key
pfmerge destkey sourcekey [sourceky...]
相关命令:
setbit key offset value
:添加元素
bitcount key
:位统计
# 添加
setbit key offset value ( value => [0,1] )
应用:使用 Bitmaps 来记录 周一 到 周日 的打卡
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(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 1
(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) 4