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-cli127.0.0.1:6379>
清除数据库
127.0.0.1:6379> flushdbOK127.0.0.1:6379> keys *(empty list or set)
Redis-Key
keys * //查看所有的keyset name ray //set keyget name //获取keyEXISTS name //判断当前key是否存在move name 1 //移动到数据库 1del name //删除key127.0.0.1:6379> expire name 10 //设置key的过期事件 单位是秒(integer) 1127.0.0.1:6379> ttl name //查看当前key的剩余时间(integer) 7127.0.0.1:6379> ttl name(integer) 3127.0.0.1:6379> ttl name(integer) 1127.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 * // 获取所有keyexists key1 //判断key是否存在append key1 "hello" //追加字符串,如果没有key,就相当于set keystrlen key1 // 获取自负床的长度##########################################127.0.0.1:6379> set views 0OK127.0.0.1:6379> incr views //i++ 自增1(integer) 1127.0.0.1:6379> get views"1"127.0.0.1:6379> decr views //i-- 自减1(integer) 0127.0.0.1:6379> get views"0"// 步长127.0.0.1:6379> incrby views 10 //i+= 可以设置步长,指定增量(integer) 10127.0.0.1:6379> get views"10"127.0.0.1:6379> decrby views 5 //i-=(integer) 5127.0.0.1:6379> get views"5"##########################################// 字符串范围127.0.0.1:6379> set key1 "hello,zhangsan"OK127.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) 14127.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秒过期时间OK127.0.0.1:6379> ttl name // 查看剩余时间(integer) 7127.0.0.1:6379> ttl name(integer) -2 // -2表示已过期,key已经删除127.0.0.1:6379> setnx name ray // 不存在name ,设置成功(integer) 1127.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 v3OK127.0.0.1:6379> keys *1) "key3"2) "key1"3) "key2"127.0.0.1:6379> mget key1 key2 key31) "v1"2) "v2"3) "v3"##########################################msetnx // 如果不存在,则批量插入127.0.0.1:6379> msetnx key1 value1 key4 v4// 已经存在key1,插入失败 是哥原子性的操作,要么一起成功,要么一起失败(integer) 0127.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 18OK127.0.0.1:6379> mget user:1:name user:1:age1) "zhangsan"2) "18"##########################################getset 先get再set127.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) 1127.0.0.1:6379> lpush list two(integer) 2127.0.0.1:6379> lpush list three(integer) 3127.0.0.1:6379> LRANGE list(error) ERR wrong number of arguments for 'lrange' command127.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) 4127.0.0.1:6379> lrange list 0 -11) "three"2) "two"3) "one"4) "four"127.0.0.1:6379>####################################################################################pop #弹出rpoplpop127.0.0.1:6379> lrange list 0 -11) "three"2) "two"3) "one"4) "four"127.0.0.1:6379> lpop list #移除list的第一个元素"three"127.0.0.1:6379> lrange list 0 -11) "two"2) "one"3) "four"127.0.0.1:6379> rpop list #移除list的最后一个元素"four"127.0.0.1:6379> lrange list 0 -11) "two"2) "one"####################################################################################lindex127.0.0.1:6379> lindex list 0 # 通过下标获取list中的某个值"two"####################################################################################llen #list长度127.0.0.1:6379> LLEN list #返回列表的长度(integer) 2####################################################################################移除指定的值lrem127.0.0.1:6379> lpush list three(integer) 3127.0.0.1:6379> lpush list three(integer) 4127.0.0.1:6379> lrange list 0 -11) "three"2) "three"3) "two"4) "one"127.0.0.1:6379> lrem list 1 one # 移除一个元素(integer) 1127.0.0.1:6379> lrange list 0 -11) "three"2) "three"3) "two"127.0.0.1:6379> lrem list 1 three(integer) 1127.0.0.1:6379> lrange list 0 -11) "three"2) "two"127.0.0.1:6379> lpush list three(integer) 3127.0.0.1:6379> lrem list 2 three #同时移除多个元素(integer) 2127.0.0.1:6379> lrange list 0 -11) "two"127.0.0.1:6379>####################################################################################trim 修剪127.0.0.1:6379> lpush mylist hello(integer) 1127.0.0.1:6379> lpush mylist hello1(integer) 2127.0.0.1:6379> lpush mylist hello2(integer) 3127.0.0.1:6379> lpush mylist hello3(integer) 4127.0.0.1:6379> lrange mylist 0 -11) "hello3"2) "hello2"3) "hello1"4) "hello"127.0.0.1:6379> ltrim mylist 1 2 # 移除1 2 之外的所有元素OK127.0.0.1:6379> lrange mylist 0 -11) "hello2"2) "hello1"127.0.0.1:6379>####################################################################################rpoplpush #移除列表的最后一个元素,并且添加到第一个元素127.0.0.1:6379> lpush mylist one(integer) 1127.0.0.1:6379> lpush mylist two(integer) 2127.0.0.1:6379> lpush mylist three(integer) 3127.0.0.1:6379> lrange mylist 0 -11) "three"2) "two"3) "one"127.0.0.1:6379> RPOPLPUSH mylist myotherlist"one"127.0.0.1:6379> lrange mylist 0 -11) "three"2) "two"127.0.0.1:6379> lrange myotherlist 0 -11) "one"127.0.0.1:6379>127.0.0.1:6379> lrange mylist 0 -11) "three"2) "two"3) "one"4) "one"127.0.0.1:6379> RPOPLPUSH mylist mylist"one"127.0.0.1:6379> lrange mylist 0 -11) "one"2) "three"3) "two"4) "one"127.0.0.1:6379>####################################################################################lset 更新指定下标的值127.0.0.1:6379> exists list(integer) 0127.0.0.1:6379> lset list 0 one #必须存在这个list,否则报错(error) ERR no such key127.0.0.1:6379> lpush list one(integer) 1127.0.0.1:6379> lset list 3 three # 下标不能超过范围(error) ERR index out of range127.0.0.1:6379> lrange list 0 -11) "one"127.0.0.1:6379> lset list 0 1 # 更新值OK127.0.0.1:6379> lrange list 0 -11) "1"127.0.0.1:6379>####################################################################################linsert127.0.0.1:6379> rpush list hello(integer) 1127.0.0.1:6379> rpush list world(integer) 2127.0.0.1:6379> lrange list 0 -11) "hello"2) "world"127.0.0.1:6379> LINSERT list before world go# 指定值前面插入一个值(integer) 3127.0.0.1:6379> lrange list 0 -11) "hello"2) "go"3) "world"127.0.0.1:6379> LINSERT list after hello redis#指定值后面插入一个值(integer) 4127.0.0.1:6379> lrange list 0 -11) "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) 1127.0.0.1:6379> sadd mysset ray(integer) 1127.0.0.1:6379> SADD myset zhangsan(integer) 1127.0.0.1:6379> SMEMBERS myset #查看指定set的所有值1) "zhangsan"2) "hello"127.0.0.1:6379> SMEMBERS mysset1) "ray"127.0.0.1:6379> SISMEMBER myset hello #判断某个值是不是set集合中(integer) 1127.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) 2127.0.0.1:6379> SREM myset hello # 移除某个元素(integer) 1127.0.0.1:6379> scard myset(integer) 1127.0.0.1:6379> SMEMBERS myset1) "zhangsan"#############################################set 无序不重复集合,随机抽取127.0.0.1:6379> SMEMBERS myset1) "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,随机删除key127.0.0.1:6379> SMEMBERS myset1) "zhangsan"2) "ray"3) "hello"127.0.0.1:6379> spop myset #随机删除一个元素"zhangsan"127.0.0.1:6379> SMEMBERS myset1) "ray"2) "hello"127.0.0.1:6379>#############################################将指定的值,移动到另外一个set中127.0.0.1:6379> SMEMBERS myset1) "zhangsan"2) "ray"3) "hello"127.0.0.1:6379> spop myset"zhangsan"127.0.0.1:6379> SMEMBERS myset1) "ray"2) "hello"127.0.0.1:6379> sadd myset2 1(integer) 1127.0.0.1:6379> sadd myset2 2(integer) 1127.0.0.1:6379> SMEMBERS myset21) "1"2) "2"127.0.0.1:6379> SMOVE myset2 myset 1 #将指定的值,移动到另外一个set中(integer) 1127.0.0.1:6379> SMEMBERS myset1) "1"2) "ray"3) "hello"127.0.0.1:6379> SMEMBERS myset21) "2"127.0.0.1:6379>#############################################微博,b站,共同关注(并集)数字集合类:— 差集- 交集- 并集127.0.0.1:6379> sadd myset1 1(integer) 1127.0.0.1:6379> sadd myset1 2(integer) 1127.0.0.1:6379> sadd myset1 3(integer) 1127.0.0.1:6379> sadd myset2 one(integer) 1127.0.0.1:6379> sadd myset2 two(integer) 1127.0.0.1:6379> sadd myset2 3(integer) 1127.0.0.1:6379> SMEMBERS myset11) "1"2) "2"3) "3"127.0.0.1:6379> SMEMBERS myset21) "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) 1127.0.0.1:6379> hget myhash name #get"ray"127.0.0.1:6379> hmset myhash name zhangsan age 18 #批量setOK127.0.0.1:6379> hmget myhash name age #批量get1) "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) 1127.0.0.1:6379> HGETALL myhash1) "name"2) "zhangsan"127.0.0.1:6379>#############################################hlen127.0.0.1:6379> hlen myhash(integer) 1#############################################hexists 判断hash中的key是否存在127.0.0.1:6379> HEXISTS myhash address(integer) 0127.0.0.1:6379> HEXISTS myhash name(integer) 1#############################################只获取所有的field只获取 所有的value127.0.0.1:6379> hkeys myhash1) "name"2) "age"127.0.0.1:6379> HVALS myhash1) "zhangsan"2) "18"127.0.0.1:6379>#############################################incr decr127.0.0.1:6379> HINCRBY myhash age 3(integer) 21127.0.0.1:6379> HVALS myhash1) "zhangsan"2) "21"127.0.0.1:6379> HINCRBY myhash age -1(integer) 20127.0.0.1:6379> HVALS myhash1) "zhangsan"2) "20"#############################################hsetnx127.0.0.1:6379> hsetnx myhash address "suzhou" 不存在才设置(integer) 1127.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) 1127.0.0.1:6379> zadd myzset 2 two(integer) 1127.0.0.1:6379> zadd myzset 3 three 4 four #添加多个值(integer) 2127.0.0.1:6379> ZRANGE myzset 0 -11) "one"2) "two"3) "three"4) "four"#############################################排序如何实现127.0.0.1:6379> zadd salary 2500 xiaohong(integer) 1127.0.0.1:6379> zadd salary 5000 zhangsan(integer) 1127.0.0.1:6379> zadd salary 500 ray(integer) 1127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf1) "ray"2) "xiaohong"3) "zhangsan"127.0.0.1:6379>127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores1) "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) 1127.0.0.1:6379> zrange salary 0 -11) "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排序 存储班级成绩表,工资表排序
排行榜应用
