五大数据类型 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)
Redis-Key 1 2 3 4 5 6 7 1. move name 1 # 移除数据库1 中的 key(name) 2. get name # 获取当前数据key的值 3. expire name 10 # 设置 key(name) 10s 过期,单位是秒 4. ttl name # 查看当前key(name)的剩余时间 5. set key value # 设置key-value 6. exists name # 判断当前的key(name)是否存在 7. type key # 查看当前key的类型
string 字符串 实现:整数值、embstr编码的简单动态字符串、简单动态字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 1. set key1 v1 # 设置值 2. get key1 # 获取值 3. keys * # 获取所有的key 4. exists key1 # 判断一个key 是否存在 5. append key1 "hello" # 将key1 所对应的value增加"hello",如果当前key不存在,相当于 set key 6. strlen key1 # 查看 key1 的长度 7. incr key1 # 当前 key1 加 1 8. decr key1 # 当前 key1 减 1 9. incrby key1 5 # 设置步长,设置 key1 增量为 5 10. decrby key1 5 # 设置步长,设置 key1 减量为 5 11. getrange key1 0 3 # 截取字符串 [0, 3] 闭区间 getrange key1 0 -1 # 获取全部字符串和 get key 是一样的 12. setrange key1 1 xx # 替换指定位置的字符串,从 1 位置开始 13. setex (set with expire) # 设置过期时间 setex key1 30 "hello" # 设置 key1 的值为 “hello”,30秒后过期 14. setnx (set if not exist) # 不存在设置,在分布式锁中会常常使用 setnx key1 "hello" # 如果 key1 存在,则设置失败;如果 key1 不存在,设置成功 15. mset k1 v1 k2 v2 k3 v3 # 同时设置多个值 16. mget k1 k2 k3 # 同时获取多个值 17. msetnx k1 v1 k4 v4 # msetnx 是一个原子性的操作,要么一起成功,要么一起失败 18. getset # 先 get 后 set getset key1 v1 如果不存在值,则返回nil, 并设置新值;如果存在值,获取原来的值,并设置新值
string的value: 除了字符串还可以是数字
List 实现:压缩列表、双端链表
列表,我们可以把list 做成栈、队列,可以存在重复值
所有的 list 命令都是以 L 开头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1. lpush list one # 当一个值或多个值,插入到列表的头部(左) 2. lrange list 0 -1 # 查看所有list 的值 3. lrange list 0 1 # 通过区间获取具体的值 [0, 1] 4. rpush list right # 将一个值或多个值插入到列表的尾部(右) 5. lpop list # 移除 list 头部元素 6. rpop list # 移除 list 尾部元素 7. lindex list 0 # 通过下标获取 list 中某一个值 8. llen list # 返回列表的长度 9. lrem list 1 one # 移除 list 集合中指定个数的 value,精确匹配 10. ltrim list 1 2 # 通过下表截取指定的长度,这个list 已经被改变了,只剩下截取的元素,[1, 2] 11. rpoplpush list1 list2 # 移除列表中最后一个元素并且添加到新的列表,list1 是源列表,list2 是新列表 12. lset list 0 item # 列表和下标必须存在,把 list 中的 0 下标位置元素更新为 item 13. linsert list before/after "hello" "other" # 往 list 中 "hello" 的前面/后边添加 "other"
list 实际上是一个链表,left、right 都可以插入值
如果 key 不存在,创建新的链表
如果 key 存在,新值内容
如果移除了所有值,空链表,也代表不存在
在两边插入或者改动值,效率最高。操作中间元素,效率会低
Set(集合) 实现:整数集合、字典
set 中值不能重复,所有set 的命令都是以 s 开头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1. sadd set "hello" # 向 set 中添加元素 2. smembers set # 查看 set 中所有值 3. sismembers myset hello # 判断某一个值是否在 myset 中 4. scard myset # 获取 set 集合中内容元素的个数 5. srem myset hello # 移除 myset 集合中某个元素 6. srandmember myset 2 # 随机选出指定个数的元素 7. srandmember myset # 随机抽选出一个元素 8. spop myset # 随机删除 myset 集合中元素 9. smove myset myset2 "hello" # 将一个指定的值,移动到另外一个 set 集合 10. sdiff key1 key2 # 求 key1 和 key2 的差集 11. sinter key1 key2 # 求 key1 和 key2 的交集 12. sunion key1 key2 # 求 key1 和 key2 的并集
Hash(哈希) 实现:压缩列表、字典
key-Map集合,value 值是一个 Map 集合。本质和 String 类型没有太大区别,是一个具体话的 key-value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1. hset myhash field hello # set 一个具体的 key-value 2. hget myhash field # 获取一个字段值 3. hmset myhash field1 hello field2 world # set 多个 key-value 4. hmget myhash field1 field2 # 获取多个字段值 5. hgetall myhash # 获取全部的数据 6. hdel myhash field1 # 删除 hash 指定的 key 字段,对应的 value 也就消失了 7. hlen myhash # 获取 hash 表的字段数量 8. hexists myhash field1 # 判断 hash 中指定字段是否存在 9. hkeys myhash # 只获取所有 field 10. kvals myhash # 只获取所有 value 11. hset myhash field 5 # 指定增量 12. hincrby myhash field 1 13. hsetnx myhash field hello # 如果不存在则设置,如果存在则失败
hash 变更的数据 user name age,尤其是用户信息之类的,经常变动的。hash 更适合对象存储
Zset(有序集合) 实现:跳跃表和字典、压缩列表
在 set 的基础上,增加了一个值
1 2 3 4 5 6 7 8 9 10 11 12 1. zadd myset 1 one # 添加一个值 2. zadd myset 2 two 3 three # 添加多个值 3. zrangebyscore myset -inf +inf # 显示全部的用户 从小到大 4. zrangebyscore myset -inf +inf withscores # 显示全部的用户并且附带序号 5. zrangebyscore myset -inf 2500 withscores # 显示序号小于2500 的用户 6. zrem myset xiaohong # 移除有序集合中指定元素 7. zcard myset # 获取有序集合中元素个数 8. zrevrange myset 0 -1 # 从大到小进行排序 9. zrange myset 0 -1 # 获取 myset 中所有的成员 9. zcount myset # 获取指定区间的成员数量 zcount myset 1 2 # 获取指定区间的成员数量
三种特殊类型 geospatial 地理位置。可以推算地理位置的信息,两地的距离,方圆几里的人
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1. 添加地理位置, 规则:两级无法直接添加 参数: key; 值:(纬度、经度、名称) geoadd china:city 116.40 39.90 beijin 2. 获取指定的城市的经度和纬度,一定是一个坐标值 geopos china:city beijin 3. 两地之间的距离 geolist china:city beijin chongqin km 4. 附近的人(获得附近的人的地址、定位),以给定的经纬度为中心,找出某一半径内的元素 georadius chain:city 110 30 1000 km # 以 110 30 这个经纬度为中心,寻找方圆1000km内的城市 georadius chain:city 110 30 1000 km withdist # 显示到中心距离的位置 georadius chain:city 110 30 1000 km withcoord # 显示他人的定位信息 georadius chain:city 110 30 1000 km withdist withcoord count 1 # 筛选出指定的结果个数 5. 找出位于指定元素周围的其他元素 geoGEORADIUSBYMEMBER china:city beijin 1000 km 6. 返回一个或多个位置元素的 geohash 表示,该命令将返回 11 个字符的 geohash 字符串 geohash china:city beijin chongqin # 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么距离越近
geo 底层的实现原理其实就是 zset,可以使用 zset 命令来操作 geo
1 2 zrange china:city 0 -1 # 查看地图中所有的城市 zrem china:city beijin # 移除指定元素
Hyperloglog 1 2 3 1. pfadd mykey a b c # 创建第一组元素 mykey 2. pfcount mykey # 统计 mykey 中元素的基数数量 3. pfmerge destkey sourcekey1 sourcekey2 # 合并两组元素到新组
0.81% 的错误率。如果不允许容错,那就使用 set 或者自己的数据类型即可
Bitmaps 位存储,两个状态的,都可以使用 bitMaps,值只能为 0/1
1 2 3 4 5 6 setbit sign 0 0 # 设置 setbit sign 3 1 getbit sign 3 # 查看 bitcount sign # 统计 sign 中值为 1 的个数