redis 是一个开源的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件MQ。它支持多种类型的数据结构,如 字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径查询。redis内置了复制(replication),LUA脚本(lua scripting),LRU驱动事件(LRU eviction),事务(transcations),和不同级别的 磁盘持久化(persistence),并通过redis哨兵(sentinel)和自动分区(cluster)提供高可用性(high availbability)。
进入redis客户端
# redis-cli
127.0.0.1:6379>
清除数据库
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty list or set)
Redis-Key
keys * //查看所有的key
set name ray //set key
get name //获取key
EXISTS name //判断当前key是否存在
move name 1 //移动到数据库 1
del name //删除key
127.0.0.1:6379> expire name 10 //设置key的过期事件 单位是秒
(integer) 1
127.0.0.1:6379> ttl name //查看当前key的剩余时间
(integer) 7
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2 // -2表示不存在
127.0.0.1:6379> type name //查看当前key的类型
string
后面遇到不会的命令,可以去redis官网上查看http://redis.cn/commands.html
String(字符串)
set key1 v1 // 设置值
get key1 // 获得值
keys * // 获取所有key
exists key1 //判断key是否存在
append key1 "hello" //追加字符串,如果没有key,就相当于set key
strlen key1 // 获取自负床的长度
##########################################
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> incr views //i++ 自增1
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> decr views //i-- 自减1
(integer) 0
127.0.0.1:6379> get views
"0"
// 步长
127.0.0.1:6379> incrby views 10 //i+= 可以设置步长,指定增量
(integer) 10
127.0.0.1:6379> get views
"10"
127.0.0.1:6379> decrby views 5 //i-=
(integer) 5
127.0.0.1:6379> get views
"5"
##########################################
// 字符串范围
127.0.0.1:6379> set key1 "hello,zhangsan"
OK
127.0.0.1:6379> get key1
"hello,zhangsan"
127.0.0.1:6379> getrange key1 0 3 //截取字符串 [0,3] 全闭!!不是半闭看开
"hell"
127.0.0.1:6379> getrange key1 0 -1 //获取所有字符串 和get key一样
"hello,zhangsan"
##########################################
// 字符串替换
127.0.0.1:6379> setrange key1 0 xx //替换指定位置开始的字符串
(integer) 14
127.0.0.1:6379> get key1
"xxllo,zhangsan"
##########################################
// setex (set with expire) 设置过期时间
// setnx (set if not exist) 不存在再设置(分布式锁中常常使用)
127.0.0.1:6379> setex name 10 ray // 设置10秒过期时间
OK
127.0.0.1:6379> ttl name // 查看剩余时间
(integer) 7
127.0.0.1:6379> ttl name
(integer) -2 // -2表示已过期,key已经删除
127.0.0.1:6379> setnx name ray // 不存在name ,设置成功
(integer) 1
127.0.0.1:6379> get name
"ray"
127.0.0.1:6379> setnx name ray // 再次设置,存在name,设置不成功
(integer) 0
##########################################
// mset 批量插入
// mget 批量获取
127.0.0.1:6379> mset key1 v1 key2 v2 key3 v3
OK
127.0.0.1:6379> keys *
1) "key3"
2) "key1"
3) "key2"
127.0.0.1:6379> mget key1 key2 key3
1) "v1"
2) "v2"
3) "v3"
##########################################
msetnx // 如果不存在,则批量插入
127.0.0.1:6379> msetnx key1 value1 key4 v4// 已经存在key1,插入失败 是哥原子性的操作,要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> keys *
1) "key3"
2) "key1"
3) "key2"
##########################################
#对象
保存一个user1 {name:zhangsan,age:18},如何使用string去保存一个对象
# 这里的key是一个巧妙的设计:user:{id}:{filed},如此设计redis是完全可以的
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 18
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "18"
##########################################
getset 先get再set
127.0.0.1:6379> getset db redis #如果不存在,则返回nil
(nil)
127.0.0.1:6379> getset db mongodb # 如果存在值,获取原来的值。并设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"
String类型的使用场景:value除了是字符串还可以是数字
- 计数器
- 统计多单位的数量
- 粉丝数
- 对象缓存存储
List
在redis里面,我们可以把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
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> LRANGE list 0 -1 # 获取list中所有值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 0 # 通过区间获取具体的值
1) "three"
####################################################################################
127.0.0.1:6379> RPUSH list four #将一个值或者多个值,插入到列表尾部
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
127.0.0.1:6379>
####################################################################################
pop #弹出
rpop
lpop
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
127.0.0.1:6379> lpop list #移除list的第一个元素
"three"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
3) "four"
127.0.0.1:6379> rpop list #移除list的最后一个元素
"four"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
####################################################################################
lindex
127.0.0.1:6379> lindex list 0 # 通过下标获取list中的某个值
"two"
####################################################################################
llen #list长度
127.0.0.1:6379> LLEN list #返回列表的长度
(integer) 2
####################################################################################
移除指定的值
lrem
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lpush list three
(integer) 4
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 # 移除一个元素
(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"
127.0.0.1:6379>
####################################################################################
trim 修剪
127.0.0.1:6379> lpush mylist hello
(integer) 1
127.0.0.1:6379> lpush mylist hello1
(integer) 2
127.0.0.1:6379> lpush mylist hello2
(integer) 3
127.0.0.1:6379> lpush mylist hello3
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hello3"
2) "hello2"
3) "hello1"
4) "hello"
127.0.0.1:6379> ltrim mylist 1 2 # 移除1 2 之外的所有元素
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello2"
2) "hello1"
127.0.0.1:6379>
####################################################################################
rpoplpush #移除列表的最后一个元素,并且添加到第一个元素
127.0.0.1:6379> lpush mylist one
(integer) 1
127.0.0.1:6379> lpush mylist two
(integer) 2
127.0.0.1:6379> lpush mylist three
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> RPOPLPUSH mylist myotherlist
"one"
127.0.0.1:6379> lrange mylist 0 -1
1) "three"
2) "two"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "one"
127.0.0.1:6379>
127.0.0.1:6379> lrange mylist 0 -1
1) "three"
2) "two"
3) "one"
4) "one"
127.0.0.1:6379> RPOPLPUSH mylist mylist
"one"
127.0.0.1:6379> lrange mylist 0 -1
1) "one"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379>
####################################################################################
lset 更新指定下标的值
127.0.0.1:6379> exists list
(integer) 0
127.0.0.1:6379> lset list 0 one #必须存在这个list,否则报错
(error) ERR no such key
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lset list 3 three # 下标不能超过范围
(error) ERR index out of range
127.0.0.1:6379> lrange list 0 -1
1) "one"
127.0.0.1:6379> lset list 0 1 # 更新值
OK
127.0.0.1:6379> lrange list 0 -1
1) "1"
127.0.0.1:6379>
####################################################################################
linsert
127.0.0.1:6379> rpush list hello
(integer) 1
127.0.0.1:6379> rpush list world
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> LINSERT list before world go# 指定值前面插入一个值
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "go"
3) "world"
127.0.0.1:6379> LINSERT list after hello redis#指定值后面插入一个值
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "redis"
3) "go"
4) "world"
小结
- 实际上list是一个链表,before node after,left,right 都可以插入值
- 如果key不存在,创建新的链表
- 如果key存在,新增内容
- 如果移除了key,空链表,页代表不存在
- 在两边插入或者改动值,效率最高!中间元素,效率会低一点
消息队列 (lpush rpop),栈(lpush lpop)
set
set中的值是不能重复的
#############################################
127.0.0.1:6379> sadd myset hello #set 中添加元素
(integer) 1
127.0.0.1:6379> sadd mysset ray
(integer) 1
127.0.0.1:6379> SADD myset zhangsan
(integer) 1
127.0.0.1:6379> SMEMBERS myset #查看指定set的所有值
1) "zhangsan"
2) "hello"
127.0.0.1:6379> SMEMBERS mysset
1) "ray"
127.0.0.1:6379> SISMEMBER myset hello #判断某个值是不是set集合中
(integer) 1
127.0.0.1:6379> SISMEMBER myset world
(integer) 0
#############################################
127.0.0.1:6379> scard myset # 获取set集合中内容的个数
(integer) 2
#############################################
127.0.0.1:6379> scard myset
(integer) 2
127.0.0.1:6379> SREM myset hello # 移除某个元素
(integer) 1
127.0.0.1:6379> scard myset
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "zhangsan"
#############################################
set 无序不重复集合,随机抽取
127.0.0.1:6379> SMEMBERS myset
1) "zhangsan"
2) "ray"
3) "hello"
127.0.0.1:6379> SRANDMEMBER myset #随机获取一个元素
"zhangsan"
127.0.0.1:6379> SRANDMEMBER myset
"ray"
127.0.0.1:6379> SRANDMEMBER myset
"ray"
127.0.0.1:6379> SRANDMEMBER myset 2 # 随机获取指定个数的元素
1) "zhangsan"
2) "ray"
#############################################
删除指定的key,随机删除key
127.0.0.1:6379> SMEMBERS myset
1) "zhangsan"
2) "ray"
3) "hello"
127.0.0.1:6379> spop myset #随机删除一个元素
"zhangsan"
127.0.0.1:6379> SMEMBERS myset
1) "ray"
2) "hello"
127.0.0.1:6379>
#############################################
将指定的值,移动到另外一个set中
127.0.0.1:6379> SMEMBERS myset
1) "zhangsan"
2) "ray"
3) "hello"
127.0.0.1:6379> spop myset
"zhangsan"
127.0.0.1:6379> SMEMBERS myset
1) "ray"
2) "hello"
127.0.0.1:6379> sadd myset2 1
(integer) 1
127.0.0.1:6379> sadd myset2 2
(integer) 1
127.0.0.1:6379> SMEMBERS myset2
1) "1"
2) "2"
127.0.0.1:6379> SMOVE myset2 myset 1 #将指定的值,移动到另外一个set中
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "ray"
3) "hello"
127.0.0.1:6379> SMEMBERS myset2
1) "2"
127.0.0.1:6379>
#############################################
微博,b站,共同关注(并集)
数字集合类:
— 差集
- 交集
- 并集
127.0.0.1:6379> sadd myset1 1
(integer) 1
127.0.0.1:6379> sadd myset1 2
(integer) 1
127.0.0.1:6379> sadd myset1 3
(integer) 1
127.0.0.1:6379> sadd myset2 one
(integer) 1
127.0.0.1:6379> sadd myset2 two
(integer) 1
127.0.0.1:6379> sadd myset2 3
(integer) 1
127.0.0.1:6379> SMEMBERS myset1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SMEMBERS myset2
1) "3"
2) "two"
3) "one"
127.0.0.1:6379>
127.0.0.1:6379> SDIFF myset1 myset2 # 差集
1) "1"
2) "2"
127.0.0.1:6379> SDIFF myset2 myset1 # 差集
1) "one"
2) "two"
127.0.0.1:6379>
127.0.0.1:6379> SINTER myset1 myset2 #交集 共同好友
1) "3"
127.0.0.1:6379> SUNION myset1 myset2 # 并集
1) "two"
2) "3"
3) "1"
4) "2"
5) "one"
127.0.0.1:6379>
hash(哈希)
map集合,key-map集合,这时候这个值是一个map集合 本质和string类型没有太大区别,还是简单的k-v
set myhash field ray
127.0.0.1:6379> hset myhash name ray #set
(integer) 1
127.0.0.1:6379> hget myhash name #get
"ray"
127.0.0.1:6379> hmset myhash name zhangsan age 18 #批量set
OK
127.0.0.1:6379> hmget myhash name age #批量get
1) "zhangsan"
2) "18"
127.0.0.1:6379>
127.0.0.1:6379> HGETALL myhash #获取hash的整体情况
1) "name"
2) "zhangsan"
3) "age"
4) "18"
127.0.0.1:6379>
127.0.0.1:6379> HDEL myhash age #删除field
(integer) 1
127.0.0.1:6379> HGETALL myhash
1) "name"
2) "zhangsan"
127.0.0.1:6379>
#############################################
hlen
127.0.0.1:6379> hlen myhash
(integer) 1
#############################################
hexists 判断hash中的key是否存在
127.0.0.1:6379> HEXISTS myhash address
(integer) 0
127.0.0.1:6379> HEXISTS myhash name
(integer) 1
#############################################
只获取所有的field
只获取 所有的value
127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
127.0.0.1:6379> HVALS myhash
1) "zhangsan"
2) "18"
127.0.0.1:6379>
#############################################
incr decr
127.0.0.1:6379> HINCRBY myhash age 3
(integer) 21
127.0.0.1:6379> HVALS myhash
1) "zhangsan"
2) "21"
127.0.0.1:6379> HINCRBY myhash age -1
(integer) 20
127.0.0.1:6379> HVALS myhash
1) "zhangsan"
2) "20"
#############################################
hsetnx
127.0.0.1:6379> hsetnx myhash address "suzhou" 不存在才设置
(integer) 1
127.0.0.1:6379> hsetnx myhash address "suzhou"
(integer) 0
hash 变更的数据 user name age,尤其是用户信息之类的,经常变动的信息
hash更适合对象的存储,string更适合字符串存储
zset(有序集合)
在set基础上,增加了一个值,set k1 v1 ,zset k1 score1 v1
127.0.0.1:6379> zadd myzset 1 one #添加一个值
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
127.0.0.1:6379> zadd myzset 3 three 4 four #添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
#############################################
排序如何实现
127.0.0.1:6379> zadd salary 2500 xiaohong
(integer) 1
127.0.0.1:6379> zadd salary 5000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 500 ray
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf
1) "ray"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379>
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores
1) "ray"
2) "500"
3) "xiaohong"
4) "2500"
5) "zhangsan"
6) "5000"
127.0.0.1:6379>
#############################################
127.0.0.1:6379> ZREM salary xiaohong #移除
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "ray"
2) "zhangsan"
127.0.0.1:6379>
#############################################
127.0.0.1:6379> ZCARD salary # 获取集合的元素个数
(integer) 2
#############################################
127.0.0.1:6379> ZREVRANGEBYSCORE salary +inf -inf #倒叙
1) "zhangsan"
2) "ray"
#############################################
获取区间的数量
127.0.0.1:6379> ZCOUNT salary 0 6000
(integer) 2
set排序 存储班级成绩表,工资表排序
排行榜应用