手记

Redis入门教程(二)— 基本数据类型

阅读以下内容时,手边打开一个redis-cli一起输入,输入命令敲击回车键前在心中想好你的答案,如果结果不合你的预期,请分析原因,使极大地提高学习效率。如果没有条件,每个数据类型后有代码运行结果,供你参考。

Reids作为一个key-value型存储系统,下面我们就分别从key和value说起:

key

key支持非二进制安全的字符类型(not binary-safe strings)。它不支持空格和换行等,key的命名一般建议使用object-type:id:field,即对象类型 :对象ID:对象属性方式。

对于key的命名,不要太长,占内存,导致查询慢;不要太短,显然car:1:color比c:1:c的可读性高太多

key的相关操作

  • KEYS pattern 返回匹配指定模式的所有key列表( ? :匹配一个字符 : 匹配任意个字符 [a-z] : 匹配括号中的任一字符 \x : 转义字符 ) 如:`keys `
  • EXISTS key 判断键是否存在,存在返回1,否则返回0 如:exists car
  • DEL key [key2 ...] 删除键,可以删除一个或者多个,返回值是删除的键的个数 如:del car
  • TYPE key 获取键值的数据类型 如:type car
  • RANDOMKEY 随机返回当前数据库中的一个key,如果数据库为空,返回空串 如:randomkey
  • RENAME oldkey newkey 重新命名一个key,如果newkey存在,将会被覆盖,成功返回1,否则返回0。失败可能是oldkey不存在或者与newkey相同 如:rename car train
  • RENAMENX oldkey newkey 功能同上,如果newkey存在,返回失败 如:renamenx car train
  • DBSIZE 返回当前数据库的key数量 如:dbsize
  • EXPIRE key seconds 为key指定过期时间,单位秒。成功返回1,否则返回0。0表示key已经设置过期或者不存在 如:expire train 60
  • TTL key 返回key剩余过期时间,单位秒。返回-1表示key不存在或者没有设置过期时间 如:ttl train
  • MOVE key db_index 将key从当前数据库移动到指定数据库。成功返回1,否则返回0。0表示key不存在或者已经在指定数据库中 如:move key 1
  • FLUSHDB 删除当前数据库中的所有key,此方法不会失败,慎用 如:flushdb
  • FLUSHALL 删除所有数据库中的所有key,此方法不会失败,慎用 如:flushall

Value

Redis有这丰富的数据类型,包括Strings,Hashes,Lists,Sets和Ordered Sets

1. 字符串 Strings

字符串类型是Redis中最基本的数据类型,它可以存储任何形式的字符串,包括二进制数据。可以用它存储用户的邮箱、JSON话的对象甚至是一张图片。一个字符串类型键允许存储的数据最大容量是512MB。

字符串类型是其他4中数据类型的基础,其他数据类型和字符串类型的差别从某种角度来说只是组织字符串的形式不同。

  • SET key value 设置指定key的值 如:set age 101
  • SETNX key value 设置指定key的值(只在可key不存在时) 如:setnx price 101
  • GET key 获取指定key的值 如:get age
  • GETRANGE key start end 返回key中字符串值得子字符(与java不同,包含end) 如:getrange age 0 1
  • GETSET key value 将给定key的值设为value并返回key的旧值 如:getset age 12
  • MSET key value [key value...] 同时设置一个或多个key-value对 如:mset age1 1 age2 2
  • MGET key [key2 ...] 获取所有给定key的值 如:mget age1 age2
  • SETEX key seconds value 将值value关联到key,并将key的过期时间设为seconds秒 如:setex age3 60 3
  • STRLEN key 返回key所储存的字符串值的长度 如:strlen age
  • INCR key 将key中储存的数字值增一 如:incr age
  • INCRBY key increment 将key所储存的值加上给定的增量值 如:incrby age 12
  • INCRBYFLOAT key increment 将key所储存的值加上给定的浮点值 如:incrbyfloat price 12.4
  • DECR key 将key中储存的数字值减一,等同于incrby key -1 如:decr age
  • DECRBY key decrement 将key所储存的值减去指定的值 如:decrby age 12
  • APPEND key value 如果key存在,在其末尾追加value 如:append age years
127.0.0.1:6379> set age 101
OK
127.0.0.1:6379> setnx price 101
(integer) 1
127.0.0.1:6379> get age
"101"
127.0.0.1:6379> getrange age 0 1
"10"
127.0.0.1:6379> getset age 12
"101"
127.0.0.1:6379> mset age1 1 age2 2
OK
127.0.0.1:6379> mget age1 age2
1) "1"
2) "2"
127.0.0.1:6379> setex age3 60 3
OK
127.0.0.1:6379> strlen age
(integer) 2
127.0.0.1:6379> incr age
(integer) 13
127.0.0.1:6379> incrby age 12
(integer) 25
127.0.0.1:6379> incrbyfloat price 12.4
"113.4"
127.0.0.1:6379> decr age
(integer) 24
127.0.0.1:6379> decrby age 12
(integer) 12
127.0.0.1:6379> append age years
(integer) 7

2. 哈希 Hashes

哈希类型是一个String类型的字段(field)和字段值(value)的映射表,字段值只能是字符串,换句话说,散列类型不能嵌套其他的数据类型,每个hash可以存储2^32-1键值对(40多亿)。

提示:除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套。比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等。

散列类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。例如要存储ID为2的汽车对象,可以分别使用名为color、name和price的3个字段存储该汽车的颜色、名称和价格:

hset car price 500
hset car name BMW
hset car color red
  • HSET key field value 将哈希表key中的字段field的值设为value 如:hset student name zhangsan
  • HSETNX key field value 只有在字段field不存在时,设置哈希表字段的值 如:hsetnx student age 12
  • HMSET key field1 value1 [field2 value2 ...] 同时将多个 field-value (域-值)对设置到哈希表 key 中 如:hmset student sex boy address beijing
  • HGET key field 获取存储在哈希表中指定字段的值 如:hget student name
  • HMGET key filed1 [field2...] 获取所有给定字段的值 如:hmget student name age
  • HGETALL key 获取在哈希表中指定 key 的所有字段和值 如:hgetall student
  • HEXISTS key field 查看哈希表 key 中,指定的字段是否存在 如:hexists student name
  • HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 如:hincrby student age 1
  • HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 如:hincrbyfloat student age 1.2
  • HDEL key field1 [field2...] 删除一个或多个哈希表字段 如:hdel student age address
  • HVALS key 获取哈希表中所有值 如:hvals student
  • HKEYS key 获取所有哈希表中的字段 如:hkeys student
  • HLEN key 获取哈希表中字段的数量 如:hlen student
127.0.0.1:6379> hset student name zhangsan
(integer) 1
127.0.0.1:6379> hsetnx student age 12
(integer) 1
127.0.0.1:6379> hmset student sex boy address beijing
OK
127.0.0.1:6379> hget student name
"zhangsan"
127.0.0.1:6379> hmget student name age
1) "zhangsan"
2) "12"
127.0.0.1:6379> hgetall student
1) "name"
2) "zhangsan"
3) "age"
4) "12"
5) "sex"
6) "boy"
7) "address"
8) "beijing"
127.0.0.1:6379> hexists student name
(integer) 1
127.0.0.1:6379> hincrby student age 1
(integer) 13
127.0.0.1:6379> hincrbyfloat student age 1.2
"14.2"
127.0.0.1:6379> hdel student age address
(integer) 2
127.0.0.1:6379> hvals student
1) "zhangsan"
2) "boy"
127.0.0.1:6379> hkeys student
1) "name"
2) "sex"
127.0.0.1:6379> hlen student
(integer) 2

3. 列表 List

列表类型(List)可以存储一个有序的字符串列表,常见的操作有向列表两端添加元素,或者获取列表的某一个片段。

其内部使用双向链表实现,所以向列表两端添加元素、取元素的时间复杂度为O(1),获取越接近两端的元素速度越快;使用链表的代价是通过索引访问元素比较慢,设想在IPhone发售当天有1000个人在排队,苹果公司打算给第486位顾客免费赠送一部,工作人员不得不一个一个数到第486个人。如果是新来的人想加入队伍,直接排到队尾就可以。

  • LPUSH key value1 [value2...] 将一个或多个值插入到列表头部 如:lpush student xiaoli xiaowang xiaoliu xiaozhang
  • RPUSH key value1 [value2...] 在列表尾部中添加一个或多个值 如:rpush student zhangsan lisi wangwu
  • LPUSHX key value 将一个值插入到已存在的列表头部 如:lpushx student xiaoming
  • RPUSHX key value 将一个值插入到已存在的列表尾部 如:rpushx student maliu
  • LPOP key 移出并获取列表的第一个元素 如:lpop student
  • RPOP key 移出并获取列表的最后一个元素 如:rpop student
  • LINDEX key index 通过索引获取列表中的元素(从0开始) 如:lindex student 0
  • LINSERT key before|after pivot value 在列表的元素前或者后插入元素 如:linsert student before xiaozhang zhangsan
  • LLEN key 获取列表长度 如:llen student
  • LRANGE key start stop 获取列表指定范围内的元素 如:lrange student 0 4
  • LREM key count value 从key对应list中删除count个和value相同的元素,count为0时候删除全部 如:lrem student 2 zhangsan
  • LSET key index value 设置list中指定下标的元素值 如:lset student 2 xiaolei
  • LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除 如:ltrim student 0 3
  • BLPOP key1 [key2...] timeout 从头部非空list进行lpop操作并返回,就是说,blpop list1 list2 list3,如果list1不存在,list2、list3都是非空则对list2进行lpop操作并返回。如果所有的list都是空或不存在,则会阻塞timeout秒,timeout为0表示一直阻塞;当阻塞时,如果有client对key1...keyN中的任意key进行push操作,则第一在这个key上被阻塞的client会立即返回。如果超时发生,则返回nil
  • BRPOP key1 [key2...] timeout 同blpop,brpop是从尾部开始执行
  • RPOPLPUSH source destination 从词面意思可以看出先做rpop,再做lpush。它的作用是从source对应list的尾部移除元素并添加到destination对应list的头部,最后返回被移除的元素值,整个操作是原子的。如果source 是空或者不存在则返回nil
  • BRPOPLPUSH source destination timeout 从列表尾部中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
127.0.0.1:6379> lpush student xiaoli xiaowang xiaoliu xiaozhang
(integer) 4
127.0.0.1:6379> rpush student zhangsan lisi wangwu
(integer) 7
127.0.0.1:6379> lpushx student xiaoming
(integer) 8
127.0.0.1:6379> rpushx student maliu
(integer) 9
127.0.0.1:6379> lpop student
"xiaoming"
127.0.0.1:6379> rpop student
"maliu"
127.0.0.1:6379> lindex student 0
"xiaozhang"
127.0.0.1:6379> linsert student before xiaozhang zhangsan
(integer) 8
127.0.0.1:6379> llen student
(integer) 8
127.0.0.1:6379> lrange student 0 4
1) "zhangsan"
2) "xiaozhang"
3) "xiaoliu"
4) "xiaowang"
5) "xiaoli"
127.0.0.1:6379> lrem student 2 zhangsan
(integer) 2
127.0.0.1:6379> lset student 2 xiaolei
OK
127.0.0.1:6379> ltrim student 0 3
OK
127.0.0.1:6379> lrange student 0 3
1) "xiaozhang"
2) "xiaoliu"
3) "xiaolei"
4) "xiaoli"

4. 集合 Set

集合的概念高中数学中就已经学过,集合中的每一个元素都是不同的,且没有顺序。一个集合类型(Set)键可以存储至多2^32-1个字符串。

集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都是O(1)。最方便的是多个集合类型键之间还可以进行交集、并集和差集运算。

  • SADD key member [member2...] 向集合添加一个或多个成员 如:sadd student zhangsan lisi ,sadd monitor wangwu zhangsan
  • SCARD key 获取集合的成员数 如:scard student
  • SMEMBERS key 返回集合中的所有成员 如:smembers student
  • SREM key member [member2...] 移除集合中一个或多个成员 如:srem student lisi
  • SISMEMBER key member 判断 member 元素是否是集合 key 的成员 如:sismember student zhangsan
  • SINTER key1 [key2...] 返回给定所有集合的交集 如:sinter student monitor
  • SINTERSTORE destination key1 [key2...] 返回给定所有集合的差集并存储在 destination 集合中 如:sinterstore sinter student monitor
  • SUNION key1 [key2...] 返回给定所有集合的并集 如:sunion student monitor
  • SUNIONSTORE destination key1 [key2...] 所有给定集合的并集存储在 destination 集合中 如:sunionstore sunion student monitor
  • SDIFF key1 [key2...] 返回给定所有集合的差集 如:sdiff monitor student
  • SDIFFSTORE destination key1 [key2...] 返回给定所有集合的差集并存储在 destination 集合中 如:sdiffstore sdiff monitor student
  • SRANDMEMBER key [count] 随机返回key集合中count个成员 如:srandmember sunion 2
  • SPOP key 移除并返回集合中的一个随机元素 如:spop sunion
  • SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合 如:smove monitor student wangwu
127.0.0.1:6379> sadd student zhangsan lisi
(integer) 2
127.0.0.1:6379> sadd monitor wangwu zhangsan
(integer) 2
127.0.0.1:6379> scard student
(integer) 2
127.0.0.1:6379> smembers student
1) "zhangsan"
2) "lisi"
127.0.0.1:6379> srem student lisi
(integer) 1
127.0.0.1:6379> sismember student zhangsan
(integer) 1
127.0.0.1:6379> sinter student monitor
1) "zhangsan"
127.0.0.1:6379> sinterstore sinter student monitor
(integer) 1
127.0.0.1:6379> sunion student monitor
1) "zhangsan"
2) "wangwu"
127.0.0.1:6379> sunionstore sunion student monitor
(integer) 2
127.0.0.1:6379> sdiff monitor student
1) "wangwu"
127.0.0.1:6379> sdiffstore sdiff monitor student
(integer) 1
127.0.0.1:6379> srandmember sunion 2
1) "zhangsan"
2) "wangwu"
127.0.0.1:6379> spop sunion
"zhangsan"
127.0.0.1:6379> smove monitor student wangwu
(integer) 1

5. 有序集合 Sorted Set

有序集合与集合的区别在于“有序”二字,不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,而且还能有序的获取前N个元素。

有序集合类型在某些方面和列表类型有些相似。

  • 二者都是有序的。
  • 二者都可以获得某一范围的元素。

但是二者有着很大的区别,这使得它们的应用场景也是不同的。

  • 列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会较慢,所以它更加适合实现如“新鲜事”或“日志”这样很少访问中间元素的应用。
  • 有序集合类型是使用散列表和跳跃表(Skip list)实现的,所以即使读取位于中间部分的数据速度也很快(时间复杂度是O(log(N))) 。
  • 有序集合要比列表类型更耗费内存

有序集合类型算得上是Redis的5种数据类型中最高级的类型了,在学习时可以与列表类型和集合类型对照理解。

  • ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数 如:添加成员 zadd score 50 zhangsan 60 lisi 70 wangwu 80 zhaoliu 90 yangqi 120 xiaoming 130 xiaozhang 140 xiaoli 150 xiaoliu 更新分数 zadd score 100 zhangsan
  • ZSCORE key member 返回有序集中,成员的分数值 如:zscore score zhangsan
  • ZRANGE key start stop [WITHSCORES] 按照成员分数从小到大的顺序返回索引从start到stop之间的所有成员值。索引从0开始,-1表示最后一个元素。如果需要同时返回分数,在后面加上WITHSCORES。 如:zrange score 0 -1 withscores
  • ZREVRANGE key start stop [WITHSCORES] 与ZRANGE唯一的不同是按照成员分数从大到小的顺序返回。 如:zrevrange score 0 -1 withscores
  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 按照成员分数从小到大的顺序返回分数值从min到max之间的所有成员值。如果不想包含端点值,可以在分数前加上(;min和max还支持无穷大,-inf和+inf分别代表负无穷和正无穷。LIMIT offset count中,offset表示从第一个元素开始偏移的位数,count表示输出的数量。 如:zrangebyscore score 50 (80 limit 1 2
  • ZREVRANGEBYSCORE key max min [WITHSCORES] 与ZRANGEBYSCORE唯一的不同是按照成员分数从大到小的顺序返回。 如:zrevrangebyscore score 80 50
  • ZRANGEBYLEX key min max [LIMIT offset count] 按照字典顺序区间返回有序集合的成员
  • ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment 如:zincrby score 5 lisi
  • ZCARD key 获取有序集合的成员数 如:zcard score
  • ZCOUNT key min max 计算在有序集合中指定区间分数的成员数 如:zcount score 50 100
  • ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量
  • ZREM key member [member...] 移除有序集合中的一个或多个成员 如:zrem score wangwu
  • ZREMRANGEBYRANK key start stop 按照元素分数从小到大的顺序(索引0表示最小的值)删除处在指定索引范围内的所有元素,并返回删除的元素数量 如:zremrangebyrank score 0 1
  • ZREMRANGEBYSCORE key min max 按照元素分数从小到大的顺序(索引0表示最小的值)删除处在指定分数范围内的所有元素,并返回删除的元素数量 如:zremrangebyscore score 90 100
  • ZREMRANGEBYLEX key min max 移除有序集合中给定的字典区间的所有成员
  • ZRANK key member 返回有序集合中指定成员的索引 如:zrank score xiaoliu
  • ZREVRANK key member 与ZRANK唯一的不同是按照成员分数从大到小的顺序返回指定的索引 如:zrevrank score xiaoliu
127.0.0.1:6379> zadd score 50 zhangsan 60 lisi 70 wangwu 80 zhaoliu 90 yangqi 120 xiaoming 130 xiaozhang 140 xiaoli 150 xiaoliu
(integer) 9
127.0.0.1:6379> zadd score 100 zhangsan
(integer) 0
127.0.0.1:6379> zscore score zhangsan
"100"
127.0.0.1:6379> zrange score 0 -1 withscores
 1) "lisi"
 2) "60"
 3) "wangwu"
 4) "70"
 5) "zhaoliu"
 6) "80"
 7) "yangqi"
 8) "90"
 9) "zhangsan"
10) "100"
11) "xiaoming"
12) "120"
13) "xiaozhang"
14) "130"
15) "xiaoli"
16) "140"
17) "xiaoliu"
18) "150"
127.0.0.1:6379> zrevrange score 0 -1 withscores
 1) "xiaoliu"
 2) "150"
 3) "xiaoli"
 4) "140"
 5) "xiaozhang"
 6) "130"
 7) "xiaoming"
 8) "120"
 9) "zhangsan"
10) "100"
11) "yangqi"
12) "90"
13) "zhaoliu"
14) "80"
15) "wangwu"
16) "70"
17) "lisi"
18) "60"
127.0.0.1:6379> zrangebyscore score 50 (80 limit 1 2
1) "wangwu"
127.0.0.1:6379> zrevrangebyscore score 80 50
1) "zhaoliu"
2) "wangwu"
3) "lisi"
127.0.0.1:6379> zincrby score 5 lisi
"65"
127.0.0.1:6379> zcard score
(integer) 9
127.0.0.1:6379> zcount score 50 100
(integer) 5
127.0.0.1:6379> zrem score wangwu
(integer) 1
127.0.0.1:6379> zremrangebyrank score 0 1
(integer) 2
127.0.0.1:6379> zremrangebyscore score 90 100
(integer) 2
127.0.0.1:6379> zrank score xiaoliu
(integer) 3
127.0.0.1:6379> zrevrank score xiaoliu
(integer) 0

文章除注明转载外,均为原创。欢迎任何形式的转载,但请务必注明出处:
文章转载自 慕课网
本文作者:dotleo
作者主页:http://www.imooc.com/u/2538812/articles

2人推荐
随时随地看视频
慕课网APP