redis相关基础知识

基础知识

redis默认有16个数据库,默认使用第0个数据库
可以使用select进行数据库的切换

用显示数据库的大小

dbsize

查看数据库所有的key,通过get方法可以得到所有的值

keys *

清除当前数据库

flushdb

清除数据库所有的内容

flushall

redis是单线程的!
redis是基于内存操作的,CPU不是redis的性能瓶颈,redis的瓶颈是根据机器的内存和网络带宽

redis单线程还这么快?
1、redis是使用C语言书写的,官方的数据是100000+QPS,这不比key-value 的Memecache差!
2、多线程进行CPU的上下文切换,不一定比单线程的效率高!redis将所有的数据都放在内存中,读写的速度很快,所以说使用单线程操作效率最高。对于内存系统来说,没有cpu上下文切换效率最高,多次读写都是在一个CPU上,在内存里面,是最佳的实践方案。

Redis-Key

127.0.0.1:6379> set name tuker 设置当前key的值为tuker
OK
127.0.0.1:6379> keys * 展示所有的key的值
1) "name"
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists age
(integer) 1
127.0.0.1:6379> exists anme
(integer) 0
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> set name tucker
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> get name
"tucker"
127.0.0.1:6379> expire name 10 设置key的过期时间
(integer) 1
127.0.0.1:6379> ttl
(error) ERR wrong number of arguments for 'ttl' command
127.0.0.1:6379> ttl name 查看当前key的剩余时间
(integer) -2
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> type name 查看当前key的类型
string
127.0.0.1:6379> type age
string

String(字符串)

set key value #设置某个key的值为value
setnx key value #如果某个key不存在,则设置某个key的值为value

List

所有的list命令都是用l开头的,

############################################
127.0.0.1:6379> lpush list one #将一个值或者多个值插入到列表的头部 (左)
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1
1) "three"
2) "two"
127.0.0.1:6379> rpush list right #将一个值或者多个值放在列表的头部(右)
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"


############################################
127.0.0.1:6379> lpop list # 移除list的第一个元素(左)
"three"
127.0.0.1:6379> rpop list # 移除list的第一个元素(右)
"right"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"

############################################
127.0.0.1:6379> lindex list 1 #通过下表获得list中的某一个值
"one"
127.0.0.1:6379> lindex list 0
"two"

############################################
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list # 返回列表的长度
(integer) 3

############################################
移除指定的值:
取关 uid
127.0.0.1:6379> lrange list 0 -1 
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 1 one # 移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> lrange list 0 -1 # 
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 1 three 
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrem list 2 three 
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"

############################################
trim 修剪: 
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> ltrim mylist 1 2 # 通过下标截取指定长度,这个list已经被改变了,只剩下截取的元素了
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"
############################################
rpoplpush # 移除列表的最后一个元素,并将其添加到一个新的元素

127.0.0.1:6379> rpush mylist "hello"
(integer) 1 
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpoplpush mylist myotherlist # 移除列表的最后一个元素,将器移动到一个新的列表中
"hello2"
127.0.0.1:6379> lrange mylist 0 -1 # 查看原来的列表
1) "hello"
2) "hello1"
127.0.0.1:6379> lrange myotherlist 0 -1 # 查看新的列表中确实有该值
1) "hello2"
############################################
lset 将列表中指定下标的值替换为另外一个值,更新操作
127.0.0.1:6379> exists list   # 检查这个列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 item # 如果不存在,我们更新会报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item # 如果存在,我们会更新下标的值
OK
127.0.0.1:6379> lrange list 0 0
1) "item"
127.0.0.1:6379> lrange list 0 0
1) "item"
127.0.0.1:6379> lset list 1 other # 如果不存在,会报错
(error) ERR index out of range
############################################
linsert 将某个值插入到某个元素的前面或者后面

127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpush mylist world
(integer) 2
127.0.0.1:6379> linsert mylist before world other
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> linsert mylist after world new
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "other"
3) "world"
4) "new"

小结

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

Set

set中的值不能重复

############################################
127.0.0.1:6379> sadd myset "hello" # set 集合中添加元素
(integer) 1
127.0.0.1:6379> sadd myset "tucker"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> smembers myset # 查看指定set的所有值
1) "world"
2) "hello"
3) "tucker"
127.0.0.1:6379> SISMEMBER myset hello  # 判断set中的某一个值是否存在
(integer) 1
127.0.0.1:6379> SISMEMBER myset kuki
(integer) 0
127.0.0.1:6379> 
############################################
127.0.0.1:6379> scard myset # 获取set集合总的内容元素个数
(integer) 3
127.0.0.1:6379> sadd myset "world"
(integer) 0
127.0.0.1:6379> sadd myset "world2"
(integer) 1
127.0.0.1:6379> scard myset
(integer) 4
127.0.0.1:6379> srem myset hello # 移除set集合中的指定元素
(integer) 1
127.0.0.1:6379> scard myset
(integer) 3
127.0.0.1:6379> SISMEMBER myset hello
(integer) 0
############################################
127.0.0.1:6379> SRANDMEMBER myset  # 随机抽选出一个元素
"world2"
127.0.0.1:6379> SRANDMEMBER myset 2 # 随机抽选指定个数的元素
1) "world2"
2) "tucker"
127.0.0.1:6379> SRANDMEMBER myset 2
1) "world2"
2) "tucker"
127.0.0.1:6379> SRANDMEMBER myset 
"world"
############################################
随机删除key
127.0.0.1:6379> spop myset # 随机移除元素
"world"
127.0.0.1:6379> spop myset
"tucker"
127.0.0.1:6379> SMEMBERS myset
1) "world2"

############################################
将一个指定的值移动到另外一个set集合中
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> sadd myset "tucker"
(integer) 1
127.0.0.1:6379> sadd myset2 "set2"
(integer) 1
127.0.0.1:6379> smove myset myset2 tucker #将一个指定的值从一个集合移动到另一个集合中
(integer) 1
127.0.0.1:6379> smembers myset
1) "world"
2) "hello"
127.0.0.1:6379> smembers myset2
1) "tucker"
2) "set2"

############################################
微博中的共同关注(并集)
数字集合类:
- 差集
- 交集
- 并集
127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
127.0.0.1:6379> sdiff key1 key2 #差集
1) "b"
2) "a"
127.0.0.1:6379> sinter key1 key2 #交集 共同好友
1) "c"
127.0.0.1:6379> sunion key1 key2 #并集 
1) "b"
2) "c"
3) "e"
4) "a"
5) "d"

Hash(哈希)

hash就是一个map集合, key-map, 本质和string没有什么区别,就是一个简单的key-value

#####################################################
127.0.0.1:6379> hset myhash field1 tucker # set 一个具体的key-value
(integer) 1
127.0.0.1:6379> hget myhash field1 #获取一个key-value
"tucker"
127.0.0.1:6379> hmset myhash field1 hello field2 world #set 多个具体的值
OK
127.0.0.1:6379> hmget myhash field1 field2 # 获取多个具体的值
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash #获取所有的值
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hdel myhash field1 #删除指定的字段
(integer) 1
127.0.0.1:6379> hgetall myhash #获取所有的字段
1) "field2"
2) "world"
##########################################################
127.0.0.1:6379> hmset myhash field2 hello 
OK
127.0.0.1:6379> hmset myhash field3 tucker
OK
127.0.0.1:6379> hlen myhash #计算myhash的长度
(integer) 2
127.0.0.1:6379> hgetall myhash # 获取myhash中所有的元素
1) "field2"
2) "hello"
3) "field3"
4) "tucker"
127.0.0.1:6379> hlen myhash
(integer) 2
127.0.0.1:6379> HEXISTS myhash field1 # 判断myhash中的元素是否存在
(integer) 0
127.0.0.1:6379> HEXISTS myhash field2
(integer) 1
127.0.0.1:6379> HEXISTS myhash field3
(integer) 1
127.0.0.1:6379> hkeys myhash # myhash中所有的key
1) "field2"
2) "field3"
127.0.0.1:6379> hvals myhash #获取所有的值
1) "hello"
2) "tucker"
127.0.0.1:6379> hset myhash field3 5
(integer) 0
127.0.0.1:6379> HINCRBY myhash field3 1 #将值减1
(integer) 6
##########################################################
127.0.0.1:6379> hset myhash field3 5 # 指定增量
(integer) 1
127.0.0.1:6379> HINCRBY myhash field3 1 # 
(integer) 6
127.0.0.1:6379> HINCRBY myhash field3 -1
(integer) 5
127.0.0.1:6379> hsetnx myhash field4 hello # 如果不存在则可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash field4 world # 如果存在则不能设置
(integer) 0

hash变更的数据例如 user name age, 哈希结构更适用于存储用户信息或者经常变动信息!
hash更适合于对象的存储,String更适合字符串存储

三种特殊数据类型

Geospatial 地理位置

朋友的定位,附近的人,打车距离计算?
Redis的Geo在Redis3.2版本中就推出了,这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人

GEOADD
GEODIST
GEOHASH
GEOPOS
GEORADIUS
GEORADIUSBYMEMBER

getadd
// 添加地理位置

将指定的地理空间位置(纬度、经度、名称)添加到指定的key中
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 114.08 22.54 shenzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 120.15 30.28 hangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 108.84 34.26 xian
(integer) 1

getpos
获取指定城市的经度和纬度
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> geopos china:city beijing chongqing
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2) 1) "106.49999767541885376"
   2) "29.52999957900659211"

计算两个位置之间的距离:GEODIST
返回两个给定位置之间的距离。

如果两个位置之间的其中一个不存在, 那么命令返回空值。

指定单位的参数 unit 必须是以下单位的其中一个:

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

127.0.0.1:6379> geodist china:city shenzhen chongqing
"1084873.5830"
127.0.0.1:6379> geodist china:city beijing shanghai km
"1067.3788"
127.0.0.1:6379> geodist china:city beijing chongqing
"1464070.8051"

找附近的人: GEORADIUS
以给定的经纬度为中心,找出某一半径来查询
获得指定数量的人

127.0.0.1:6379> georadius china:city 110 30 500 km
# 以 110 30 这个经纬度为中心寻找方圆500km内的城市
1) "chongqing"
2) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist
# 显示到城市的中心距离
1) 1) "chongqing"
   2) "341.9374"
2) 1) "xian"
   2) "486.2460"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord
1) 1) "chongqing"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.8399997353553772"
      2) "34.25999964418929977"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord
1) 1) "chongqing"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.8399997353553772"
      2) "34.25999964418929977"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord count 1
# 筛选城市数量为1
1) 1) "chongqing"
   2) "341.9374"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"

GEORADIUSBYMEMBER
使用输入的经度和纬度来决定中心点指定成员的位置被用作查询的中心。

# 找出指定元素旁边的其他元素!
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
2) "xian"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 400 km
1) "hangzhou"
2) "shanghai"

GEOHASH
返回一个或多个位置元素的 Geohash 表示。

# 把城市的两个城市的经纬度转换成一维的base64字符串
127.0.0.1:6379> GEOHASH china:city beijing chongqing
1) "wx4fbxxfke0"
2) "wm5xzrybty0"

GEO 的底层实现原理其实是Zset!我们可以使用Zset命令来操作GEO

# 查看地图中的全部元素
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"

Hyperloglog

什么是基数

指的是一个集合中不重复的元素

简介
网页的UV(一个人访问网站多次,还是算作一个人)
传统的方式,保存用户的id,然后就可以统计set中的元素数量作为标准判断。
这个方式入宫保存大量的用户id,就会比较麻烦!我们的目的就是为了基数而不是保存用户id。

Redis Hyperloglog
优点: 占用的内存是固定的,2^64不同的元素的基数,只需要12kB的内存,Hyperloglog是首选。

127.0.0.1:6379> PFADD mykey a b c d e f g h i j k
(integer) 1
127.0.0.1:6379> PFCOUNT mykey # 统计第一组中的元素数量
(integer) 11
127.0.0.1:6379> pfadd mykey i j z kv l
(integer) 1
127.0.0.1:6379> PFCOUNT mykey
(integer) 14
127.0.0.1:6379> pfadd mykey2 a b c d 
(integer) 1
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 # 合并两组数据
OK
127.0.0.1:6379> PFCOUNT mykey3
(integer) 14

如果允许容错,一定可以使用Hyperloglog


Bitmaps

位存储
统计疫情感染人数: 0 1 0 1 0
统计用户的信息,活跃,不活跃! 登录、 未登录!打卡,365打卡!
使用bitmap来记录周一到周日的打卡

127.0.0.1:6379> setbit sigin 0 1
(integer) 0
127.0.0.1:6379> setbit sigin 1 0
(integer) 0
127.0.0.1:6379> setbit sigin 2 0
(integer) 0
127.0.0.1:6379> setbit sigin 3 1
(integer) 0
127.0.0.1:6379> setbit sigin 4 1
(integer) 0
127.0.0.1:6379> setbit sigin 5 1
(integer) 0
127.0.0.1:6379> setbit sigin 6 0
(integer) 0
# 查看某一个天是否有打卡
127.0.0.1:6379> getbit sigin 6
(integer) 0
127.0.0.1:6379> getbit sigin 1
(integer) 0
#统计操作, 统计打卡天数
127.0.0.1:6379> bitcount sigin
(integer) 4

猜你喜欢

转载自blog.csdn.net/sinat_28199083/article/details/130716734