Redis五大基本数据类型和三大特殊数据类型
一、Redis简介
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
127.0.0.1:6379> set name wangyh #设置key OK 127.0.0.1:6379> set age 1 OK 127.0.0.1:6379> exists name #判断key是否存在 (integer) 1 127.0.0.1:6379> expire name 10 #设置过期时间 (integer) 1 127.0.0.1:6379> ttl name #查看剩余时间 (integer) 7 127.0.0.1:6379> ttl name (integer) 5 127.0.0.1:6379> ttl name (integer) 4 127.0.0.1:6379> ttl name (integer) 2 127.0.0.1:6379> ttl name (integer) 2 127.0.0.1:6379> ttl name (integer) -2 127.0.0.1:6379> get name #获取key的值 (nil) 127.0.0.1:6379> get age "1" 127.0.0.1:6379> type age #查看key的类型 string
三、Redis五大数据类型
1. String
127.0.0.1:6379> set name abcdefg #设置key OK 127.0.0.1:6379> get name #获取key "abcdefg" 127.0.0.1:6379> append name hijklmn #在key后追加字符串 (integer) 14 127.0.0.1:6379> get name "abcdefghijklmn" 127.0.0.1:6379> strlen name #获取key值的长度 (integer) 14 127.0.0.1:6379> set num 1 OK 127.0.0.1:6379> incr num #自增1 (integer) 2 127.0.0.1:6379> decr num #自减1 (integer) 1 127.0.0.1:6379> incrby num 2 #自增2 (integer) 3 127.0.0.1:6379> decrby num 3 #自减3 (integer) 0 127.0.0.1:6379> getrange name 0 3 #截取字符串 "abcd" 127.0.0.1:6379> setrange name 1 xxxx #替换字符串 (integer) 14 127.0.0.1:6379> get name "axxxxfghijklmn" 127.0.0.1:6379> setex k1 30 hello # 设置key并设置过期时间 OK 127.0.0.1:6379> ttl k1 (integer) 27 127.0.0.1:6379> setnx k2 v2 #如果key不存在,创建,key存在不创建 (integer) 1 127.0.0.1:6379> keys * 1) "k2" 2) "k1" 3) "name" 4) "num" 127.0.0.1:6379> mset k3 v3 k4 v4 k5 v5 #批量创建key OK 127.0.0.1:6379> keys * 1) "k2" 2) "name" 3) "k5" 4) "k4" 5) "num" 6) "k3" 127.0.0.1:6379> mget k1 k2 #批量获取key 1) (nil) 2) "v2" 127.0.0.1:6379> msetnx k1 v1 k2 sjdc #批量创建不存在的key,原子性操作 (integer) 0 127.0.0.1:6379> keys * 1) "k2" 2) "name" 3) "k5" 4) "k4" 5) "num" 6) "k3" 127.0.0.1:6379> msetnx k1 v1 k6 v6 (integer) 1 127.0.0.1:6379> keys * 1) "k1" 2) "k2" 3) "name" 4) "k5" 5) "k4" 6) "k6" 7) "num" 8) "k3" 127.0.0.1:6379> getset k7 v7 #现获取当前key值,再创建新值,key不存在则返回nil,然后创建 (nil) 127.0.0.1:6379> keys * 1) "k1" 2) "k4" 3) "k2" 4) "name" 5) "k7" 6) "k5" 7) "k6" 8) "k3" 9) "num" 127.0.0.1:6379> getset k7 value7 "v7" 127.0.0.1:6379> get k7 "value7" 127.0.0.1:6379> set user:1 {name:zhangsan,age:10} 创建对象 OK 127.0.0.1:6379> keys * 1) "k1" 2) "k4" 3) "k2" 4) "name" 5) "k7" 6) "k5" 7) "user:1" 8) "k6" 9) "k3" 10) "num" 127.0.0.1:6379> get user:1:name (nil) 127.0.0.1:6379> get user:1 "{name:zhangsan,age:10}"
127.0.0.1:6379> exists k2 # 判断key是否存在
(integer) 1
2. list
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> lpush mylist one two three # 从列表头部依次插入多个元素 (integer) 3 127.0.0.1:6379> lrange mylist 0 -1 # 获取指定长度的列表元素 1) "three" 2) "two" 3) "one" 127.0.0.1:6379> rpush mylist1 1 2 3 # 从列表尾部依次插入多个元素 (integer) 3 127.0.0.1:6379> lrange mylist1 0 -1 1) "1" 2) "2" 3) "3" 127.0.0.1:6379> LPOP mylist # 从列表头部取出一个元素 "three" 127.0.0.1:6379> LRANGE mylist 0 -1 1) "two" 2) "one" 127.0.0.1:6379> RPOP mylist1 # 从列表尾部取出一个元素 "3" 127.0.0.1:6379> LRANGE mylist1 0 -1 1) "1" 2) "2" 127.0.0.1:6379> lindex mylist 1 # 获取列表指定下标的元素 "one" 127.0.0.1:6379> lindex mylist 0 "two" 127.0.0.1:6379> LLEN mylist # 获取列表元素个数 (integer) 2 127.0.0.1:6379> ltrim mylist 0 1 # 截取列表指定长度的元素,此方法将改变原列表的元素 OK 127.0.0.1:6379> lrange mylist 0 -1 1) "two" 2) "one" 127.0.0.1:6379> ltrim mylist 0 0 OK 127.0.0.1:6379> lrange mylist 0 -1 1) "two" 127.0.0.1:6379> RPOPLPUSH mylist1 mylist2 # 从列表尾部取出一个元素,插入到另一个列表的头部 "2" 127.0.0.1:6379> LRANGE mylist1 0 -1 1) "1" 127.0.0.1:6379> lrange mylist2 0 -1 1) "2" 127.0.0.1:6379> lrange mylist 0 -1 1) "two" 127.0.0.1:6379> lset mylist 0 one # 修改列表指定下标的元素值,修改的列表不存在将报错 OK 127.0.0.1:6379> lrange mylist 0 -1 1) "one" 127.0.0.1:6379> linsert mylist after one two # 在列表指定元素之前或者之后插入新元素 (integer) 2 127.0.0.1:6379> lrange mylist 0 -1 1) "one" 2) "two" 127.0.0.1:6379> exists list # 判断列表是否存在 (integer) 0 127.0.0.1:6379> lset list 0 one (error) ERR no such key
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush mylist one two three three three
(integer) 5
127.0.0.1:6379> lrange mylist 0 5
1) "one"
2) "two"
3) "three"
4) "three"
5) "three"
127.0.0.1:6379> lrem mylist 2 three # 删除列表中指定个数指定元素
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379>
3. set(集合)
set中的值是不能重复的。
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> sadd myset 1 2 3 4 5 6 7 8 9 10 # 向集合中添加多个成员 (integer) 10 127.0.0.1:6379> SMEMBERS myset # 查看集合中的所有成员 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6" 7) "7" 8) "8" 9) "9" 10) "10" 127.0.0.1:6379> sismember myset 1 #判断某元素是否是指定集合的成员 (integer) 1 127.0.0.1:6379> sismember myset 11 (integer) 0 127.0.0.1:6379> scard myset #获取集合中成员个数 (integer) 10 127.0.0.1:6379> srem myset 1 #删除指定集合中的指定成员 (integer) 1 127.0.0.1:6379> smembers myset 1) "2" 2) "3" 3) "4" 4) "5" 5) "6" 6) "7" 7) "8" 8) "9" 9) "10" 127.0.0.1:6379> srandmember myset 2 #随机获取指定集合中指定个数的成员 1) "6" 2) "2" 127.0.0.1:6379> srandmember myset 2 1) "6" 2) "5" 127.0.0.1:6379> srandmember myset 2 1) "7" 2) "4" 127.0.0.1:6379> srandmember myset 2 1) "9" 2) "5" 127.0.0.1:6379> spop myset 2 #随机取出指定集合中指定个数的成员 1) "6" 2) "10" 127.0.0.1:6379> spop myset 2 1) "3" 2) "5" 127.0.0.1:6379> smembers myset 1) "2" 2) "4" 3) "7" 4) "8" 5) "9" 127.0.0.1:6379> smove myset myset1 4 #将指定集合中的指定成员移动到另一个集合中 (integer) 1 127.0.0.1:6379> smembers myset 1) "2" 2) "7" 3) "8" 4) "9" 127.0.0.1:6379> smembers myset1 1) "4" 127.0.0.1:6379> sadd myset2 1 2 3 4 5 6 7 8 9 10 (integer) 10 127.0.0.1:6379> sdiff myset myset1 myset2 # 获取多个集合的差集 (empty array) 127.0.0.1:6379> sdiff myset myset2 (empty array) 127.0.0.1:6379> sdiff myset2 myset 1) "1" 2) "3" 3) "4" 4) "5" 5) "6" 6) "10" 127.0.0.1:6379> sinter myset2 myset #获取多个集合的交集 1) "2" 2) "7" 3) "8" 4) "9" 127.0.0.1:6379> sinter myset myset2 1) "2" 2) "7" 3) "8" 4) "9" 127.0.0.1:6379> sunion myset myset2 #获取多个集合的并集 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6" 7) "7" 8) "8" 9) "9" 10) "10"
4. hash(哈希)
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> hset myhash field1 value1 field2 value2 # 设置hash值 (integer) 2 127.0.0.1:6379> hget myhash field1 # 获取指定hash的字段值 "value1" 127.0.0.1:6379> hget myhash field2 "value2" 127.0.0.1:6379> HMSET myhash field1 hello field2 world # 批量设置hash值 OK 127.0.0.1:6379> HMGET myhash field1 field2 #批量获取hash字段值 1) "hello" 2) "world" 127.0.0.1:6379> HGETALL myhash #获取指定hash的所有字段和值 1) "field1" 2) "hello" 3) "field2" 4) "world" 127.0.0.1:6379> hdel myhash field1 #删除指定hash的指定字段 (integer) 1 127.0.0.1:6379> HGETALL myhash 1) "field2" 2) "world" 127.0.0.1:6379> hlen myhash #获取指定hash的字段个数 (integer) 1 127.0.0.1:6379> hexists myhash field1 #判断指定的hash是否存在 (integer) 0 127.0.0.1:6379> hexists myhash field2 (integer) 1 127.0.0.1:6379> hkeys myhash #获取指定hash的所有字段 1) "field2" 127.0.0.1:6379> hvals myhash #获取指定hash的所有值 1) "world" 127.0.0.1:6379> hset myhash field1 2 (integer) 1 127.0.0.1:6379> hincrby myhash field1 5 #将hash的某个字段自增5 (integer) 7 127.0.0.1:6379> HSETNX myhash field1 hello #hash字段存在不创建,不存在创建(hset if not exists) (integer) 0 127.0.0.1:6379> HSETNX myhash field3 hello (integer) 1
5. zset(有序集合)
127.0.0.1:6379> zadd salary 2500 tony 73873 zhangsan 6738 lily 78328 tom 72834 lisi 83293 wangwu #将成员加入到有序集合中 (integer) 6 127.0.0.1:6379> zrange salary 0 -1 #获取指定长度的集合成员 1) "tony" 2) "lily" 3) "lisi" 4) "zhangsan" 5) "tom" 6) "wangwu" 127.0.0.1:6379> zrange salary 0 -1 withscores #获取指定长度的集合成员及分数 1) "tony" 2) "2500" 3) "lily" 4) "6738" 5) "lisi" 6) "72834" 7) "zhangsan" 8) "73873" 9) "tom" 10) "78328" 11) "wangwu" 12) "83293" 127.0.0.1:6379> zrangebyscore salary -inf +inf #按照从小到大的顺序获取指定长度的集合成员 1) "tony" 2) "lily" 3) "lisi" 4) "zhangsan" 5) "tom" 6) "wangwu" 127.0.0.1:6379> zrangebyscore salary -inf +inf withscores #按照从小到大的顺序获取指定长度的集合成员及分数 1) "tony" 2) "2500" 3) "lily" 4) "6738" 5) "lisi" 6) "72834" 7) "zhangsan" 8) "73873" 9) "tom" 10) "78328" 11) "wangwu" 12) "83293" 127.0.0.1:6379> zrangebyscore salary -inf +inf withscores limit 0 3 #按照从小到大的顺序分页获取集合成员及分数 1) "tony" 2) "2500" 3) "lily" 4) "6738" 5) "lisi" 6) "72834" 127.0.0.1:6379> zrangebyscore salary -inf +inf withscores limit 3 3 1) "zhangsan" 2) "73873" 3) "tom" 4) "78328" 5) "wangwu" 6) "83293" 127.0.0.1:6379> zrevrange salary 0 -1 # 按照从大到小的顺序获取指定长度的集合成员 1) "wangwu" 2) "tom" 3) "zhangsan" 4) "lisi" 5) "lily" 6) "tony" 127.0.0.1:6379> zrevrange salary 0 -1 withscores # 按照从大到小的顺序获取指定长度的集合成员及分数 1) "wangwu" 2) "83293" 3) "tom" 4) "78328" 5) "zhangsan" 6) "73873" 7) "lisi" 8) "72834" 9) "lily" 10) "6738" 11) "tony" 12) "2500" 127.0.0.1:6379> zrevrangebyscore salary +inf -inf # 按照分数倒序排列集合成员 1) "wangwu" 2) "tom" 3) "zhangsan" 4) "lisi" 5) "lily" 6) "tony" 127.0.0.1:6379> zrevrangebyscore salary +inf -inf withscores 1) "wangwu" 2) "83293" 3) "tom" 4) "78328" 5) "zhangsan" 6) "73873" 7) "lisi" 8) "72834" 9) "lily" 10) "6738" 11) "tony" 12) "2500" 127.0.0.1:6379> zrevrangebyscore salary +inf -inf withscores limit 0 3 #分页倒序 1) "wangwu" 2) "83293" 3) "tom" 4) "78328" 5) "zhangsan" 6) "73873" 127.0.0.1:6379> zrevrangebyscore salary +inf -inf withscores limit 3 3 1) "lisi" 2) "72834" 3) "lily" 4) "6738" 5) "tony" 6) "2500" 127.0.0.1:6379> zrank salary tom #根据成员获取成员正序排名(下标0开始) (integer) 4 127.0.0.1:6379> zrevrank salary tom #根据成员获取成员倒序排名(下标0开始) (integer) 1 127.0.0.1:6379> zrem salary lisi #删除成员 (integer) 1 127.0.0.1:6379> zrevrange salary 0 -1 1) "wangwu" 2) "tom" 3) "zhangsan" 4) "lily" 5) "tony" 127.0.0.1:6379> zremrangebyrank salary 0 1 # 移除集合中指定排名区间内的所有成员 (integer) 2 127.0.0.1:6379> zrevrange salary 0 -1 withscores 1) "wangwu" 2) "83293" 3) "tom" 4) "78328" 5) "zhangsan" 6) "73873" 127.0.0.1:6379> zremrangebyscore salary 0 73873 #移除集合中score值介于min 和max之间的所有集合 (integer) 1 127.0.0.1:6379> zrevrange salary 0 -1 withscores 1) "wangwu" 2) "83293" 3) "tom" 4) "78328" 127.0.0.1:6379> zcard salary #获取集合中成员个数 (integer) 2 127.0.0.1:6379> zcount salary -inf +inf #获取score值在min和max之间(包含)的成员个数 (integer) 2 127.0.0.1:6379> zincrby salary 6737 tom # 给指定集合中的指定成员增加score的值 "85065" 127.0.0.1:6379> zpopmax salary 1 #弹出集合中指定个数的最大值 1) "tom" 2) "85065" 127.0.0.1:6379> zpopmin salary 1 # 弹出集合中指定个数的最小值 1) "wangwu" 2) "83293" 127.0.0.1:6379> zrange salary 0 -1 withscores (empty array) 127.0.0.1:6379>
四、三大特殊数据类型
1. geospatial地理空间
127.0.0.1:6379> geoadd china:city 116.23128 40.22077 beijing #添加成员经纬度 (integer) 1 127.0.0.1:6379> geoadd china:city 121.48941 31.40527 shanghai (integer) 1 127.0.0.1:6379> geoadd china:city 106.54041 29.40268 chongqin (integer) 1 127.0.0.1:6379> geoadd china:city 113.27324 23.15792 guangzhou (integer) 1 127.0.0.1:6379> geoadd china:city 113.88308 22.55329 shenzhen (integer) 1 127.0.0.1:6379> geoadd china:city 113.6401 34.72468 zhengzhou (integer) 1 127.0.0.1:6379> geoadd china:city 114.65048 33.64738 zhoukou (integer) 1 127.0.0.1:6379> geopos china:city beijing #查看成员经纬度 1) 1) "116.23128265142440796" 2) "40.22076905438526495" 127.0.0.1:6379> geopos china:city shanghai 1) 1) "121.48941010236740112" 2) "31.40526993848380499" 127.0.0.1:6379> geodist china:city beijing shanghai m #获取两个成员之间的距离 "1088644.3544" 127.0.0.1:6379> geodist china:city beijing shanghai km "1088.6444"127.0.0.1:6379> geodist china:city beijing zhoukou km "744.4797" 127.0.0.1:6379> geoadd china:city 115.09856 33.4094 shenqiu (integer) 1 127.0.0.1:6379> GEODIST china:city shenqiu beijing "764266.9183" 127.0.0.1:6379> GEODIST china:city shenqiu beijing km "764.2669" 127.0.0.1:6379> GEODIST china:city shenqiu zhoukou km "49.2613" 127.0.0.1:6379> GEODIST china:city shenqiu zhengzhou km "198.6389" 127.0.0.1:6379> GEORADIUS china:city 115.09856 33.4094 50 km # 获取指定经纬度方圆指定距离的成员 1) "shenqiu" 2) "zhoukou" 127.0.0.1:6379> GEORADIUS china:city 115.09856 33.4094 50 km withdist count 1 1) 1) "shenqiu" 2) "0.0001" 127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 500 km #获取指定成员附近的成员 1) "beijing" 127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 800 km 1) "shenqiu" 2) "zhoukou" 3) "zhengzhou" 4) "beijing" 127.0.0.1:6379> geohash china:city beijing shanghai #获取成员经纬度的hash值 1) "wx4sucvncn0" 2) "wtw6st1uuq0" 127.0.0.1:6379> geohash china:city shenqiu zhoukou 1) "wtcy51upyg0" 2) "wtcx2vmfjy0"
GEO底层原理是通过zset(有序集合)实现的,故可以使用zset的方法操作GEO
127.0.0.1:6379> zrange china:city 0 -1 1) "chongqin" 2) "shenzhen" 3) "guangzhou" 4) "shanghai" 5) "shenqiu" 6) "zhoukou" 7) "zhengzhou" 8) "beijing" 127.0.0.1:6379> zrange china:city 0 -1 withscores 1) "chongqin" 2) "4026046519194590" 3) "shenzhen" 4) "4046340107163728" 5) "guangzhou" 6) "4046534010880445" 7) "shanghai" 8) "4054807796443227" 9) "shenqiu" 10) "4064255233297272" 11) "zhoukou" 12) "4064259956013560" 13) "zhengzhou" 14) "4064941915769625" 15) "beijing" 16) "4069896088584598" 127.0.0.1:6379>
2. Hyperloglog
Hyperloglog 基数统计的算法
127.0.0.1:6379> pfadd mykey1 a b c d e f g h i j k l m n #添加第一组元素 (integer) 1 127.0.0.1:6379> pfcount mykey1 # 统计元素个数 (integer) 14 127.0.0.1:6379> pfadd mykey2 k w a d n e c l o p n e j a d x #创建第二组元素 (integer) 1 127.0.0.1:6379> pfcount mykey2 (integer) 12 127.0.0.1:6379> pfmerge mykey mykey1 mykey2 #合并两组元素到mykey中 OK 127.0.0.1:6379> pfcount mykey #统计合并后的元素个数 (integer) 18
3. Bitmaps
127.0.0.1:6379> SETBIT sign 0 1 # 设置值 (integer) 0 127.0.0.1:6379> SETBIT sign 1 1 (integer) 0 127.0.0.1:6379> SETBIT sign 2 1 (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 0 (integer) 0 127.0.0.1:6379> getbit sign 2 # 获取值 (integer) 1 127.0.0.1:6379> getbit sign 5 (integer) 0 127.0.0.1:6379> BITCOUNT sign #统计值为1的个数 (integer) 5
#按照从小到大的顺序获取指定长度的集合成员