潘景

Redis快速入门
一.Redis简介1.非关系型数据库(Nosql)在了解Redis之前,我们需要先了解一下非关系型数据库。当前主流...
扫描右侧二维码阅读全文
01
2019/03

Redis快速入门

一.Redis简介

1.非关系型数据库(Nosql)

在了解Redis之前,我们需要先了解一下非关系型数据库。

当前主流的关系型数据库有Oracle、DB2、Microsoft SQL Server、MySQL等。
非关系型数据库有Cloudant、MongoDb、redis、HBase等。

那么,到底什么是非关系型数据库呢?
非关系型数据库:NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。表示在应用开发时,不是必须使用关系型数据库,可以使用NoSQL替代关系型数据库的部分功能。

对比关系型数据库,非关系型数据库有以下优点:
(1)无需经过sql层的解析,读写性能很高;
(2)基于键值对,数据没有耦合性,容易扩展;
(3)存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,而关系型数据库则只支持基础类型。

目前NoSQL还不能完全替代关系型数据库,一般使用关系型数据库结合NoSQL数据库进行完成项目。一般有以下几种应用场景:

(1)当数据比较复杂时不适用NoSQL数据库;

(2)关系型数据库依然作为数据存储的主要软件;

(3)NoSQL数据库当作缓存工具来使用(NoSQL读写性能远高于关系型数据库),把使用频率较高的内容不仅仅存储到关系型数据库中还存储到NoSQL中。

2.Redis

(1)Redis概念

Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

(2)Redis特点
  • Redis采用的是基于内存的单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,sortedset,hash等数据结构的存储。
  • 支持过期时间,支持事务,消息订阅。
  • Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • Redis支持数据的备份,即master-slave模式的数据备份。
  • 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
(3)Redis持久化策略

Redis的持久化方式有2种,持久化策略有4种。

  • RDB:数据快照模式

    • 默认的持久化策略,每隔一定时间后把内存中的数据持久化到dump.rdb文件中。
    • 缺点:数据过于集中,可能导致最后的数据没有持久化到dump.db中。解决办法:使用命令SAVE或BGSAVE手动持久化。
  • AOF:数据追加模式

    • 监听Redis的日志文件,监听如果发现执行了修改、删除、新增命令,立即根据这条命令把数据持久化。
    • 缺点:效率低
  • 如果只希望数据保存在内存中的话,俩种策略都可以关闭
  • 也可以同时开启俩种策略,当Redis重启时,AOF文件会用于重建原始数据

二.Redis常用命令

1.命令手册网址

http://doc.redisfans.com/

2.主要数据类型

  • String(字符串)
  • Hash(散列类型)
  • List(列表类型)
  • Set(集合类型)
  • SortedSet(有序集合类型)

3.常用基本命令

(1)Key(键)
  • KEYS pattern:查找所有符合给定模式 pattern 的 key 。(特殊符号用 隔开)

    • KEYS * 匹配数据库中所有 key 。
    • KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
    • KEYS h*llo 匹配 hllo 和 heeeeello 等。
    • KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
  • EXISTS key:检查给定 key 是否存在。

    • 若 key 存在,返回 1 ,否则返回 0 。
  • DEL key [key ...]:删除给定的一个或多个 key 。

    • 返回值:被删除 key 的数量。
  • TYPE key:返回 key 所储存的值的类型。

    • 返回值:none (key不存在),string (字符串),list (列表),set (集合),zset (有序集),hash (哈希表)
  • FLUSHALL:清空所有数据库
(2)String(键)
  • GET key:返回 key 所关联的字符串值。

    • 如果 key 不存在那么返回特殊值 nil 。
    • 假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。
  • SET key value [EX seconds] [PX milliseconds] [NX|XX]:将字符串值 value 关联到 key 。

    • 如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
    • 对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
    • EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
    • PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
    • NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
    • XX :只在键已经存在时,才对键进行设置操作。
  • INCR key:将 key 中储存的数字值增一。

    • 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
    • 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    • 本操作的值限制在 64 位(bit)有符号数字表示之内。
    • 返回值:执行 INCR 命令之后 key 的值。
  • INCRBY key increment:将 key 所储存的值加上增量 increment 。(操作流程及返回值类似)
  • DECR key:将 key 中储存的数字值减一。

    • 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
    • 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    • 本操作的值限制在 64 位(bit)有符号数字表示之内。
    • 返回值:执行 DECR 命令之后 key 的值。
  • DECRBY key decrement:将 key 所储存的值减去减量 decrement 。(操作流程及返回值类似)
  • INCRBYFLOAT key increment:为 key 中所储存的值加上浮点数增量 increment 。(操作流程及返回值类似)
  • APPEND key value

    • 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
    • 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
  • STRLEN key:返回 key 所储存的字符串值的长度。

    • 当 key 储存的不是字符串值时,返回一个错误。
    • 返回值:字符串值的长度。当 key 不存在时,返回 0 。
  • MGET key [key ...]:返回所有(一个或多个)给定 key 的值。

    • 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。
    • 返回值:一个包含所有给定 key 的值的列表。
  • MSET key value [key value ...]:同时设置一个或多个 key-value 对。

    • 如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。
    • MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。
    • 返回值:总是返回 OK (因为 MSET 不可能失败)
(3)Hash(键)
  • HSET key field value:将哈希表 key 中的域 field 的值设为 value 。

    • 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
    • 如果域 field 已经存在于哈希表中,旧值将被覆盖
    • 返回值:如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1 。如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0 。
  • HMSET key field value [field value ...]:同时将多个 field-value (域-值)对设置到哈希表 key 中。

    • 此命令会覆盖哈希表中已存在的域。
    • 如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。
    • 返回值:如果命令执行成功,返回 OK 。当 key 不是哈希表(hash)类型时,返回一个错误。
  • HGET key field:返回哈希表 key 中给定域 field 的值。

    • 给定域的值。
    • 返回值:当给定域不存在或是给定 key 不存在时,返回 nil 。
  • HMGET key field [field ...]:返回哈希表 key 中,一个或多个给定域的值。

    • 如果给定的域不存在于哈希表,那么返回一个 nil 值。
    • 因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。
    • 返回值:一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。
  • HGETALL key:返回哈希表 key 中,所有的域和值。

    • 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
    • 返回值:以列表形式返回哈希表的域和域的值。若 key 不存在,返回空列表。
  • HEXISTS key field:查看哈希表 key 中,给定域 field 是否存在。

    • 返回值:如果哈希表含有给定域,返回 1 。如果哈希表不含有给定域,或 key 不存在,返回 0 。
  • HSETNX key field value:将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。若域 field 已经存在,该操作无效。

    • 返回值:设置成功,返回 1 。如果给定域已经存在且没有操作被执行,返回 0 。
  • HINCRBY key field increment:为哈希表 key 中的域 field 的值加上增量 increment 。

    • 增量也可以为负数,相当于对给定域进行减法操作。
    • 如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。
    • 如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。
    • 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
    • 本操作的值被限制在 64 位(bit)有符号数字表示之内。
    • 执行 HINCRBY 命令之后,哈希表 key 中域 field 的值。
  • HDEL key field [field ...]:删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。

    • 返回值:被成功移除的域的数量,不包括被忽略的域。
  • HKEYS key:返回哈希表 key 中的所有域。

    • 返回值:一个包含哈希表中所有域的表。当 key 不存在时,返回一个空表。
  • HVALS key:返回哈希表 key 中所有域的值。

    • 返回值:一个包含哈希表中所有值的表。当 key 不存在时,返回一个空表。
  • HLEN key:返回哈希表 key 中域的数量。

    • 返回值:哈希表中域的数量。当 key 不存在时,返回 0 。
(4)List(键)

内部使用双向链表实现,所以获取越接近两端的元素速度越快,但通过索引访问时会比较慢。

  • LPUSH key value [value ...]:将一个或多个值 value 插入到列表 key 的表头

    • 如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a ,这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。
    • 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。
    • 当 key 存在但不是列表类型时,返回一个错误。
    • 返回值:执行 LPUSH 命令后,列表的长度。
  • RPUSH key value [value ...]:将一个或多个值 value 插入到列表 key 的表尾(最右边)。

    • 如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
    • 如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
    • 当 key 存在但不是列表类型时,返回一个错误。
    • 执行 RPUSH 操作后,表的长度。
  • LPOP key:移除并返回列表 key 的头元素。

    • 返回值:列表的头元素。当 key 不存在时,返回 nil 。
  • RPOP key:移除并返回列表 key 的尾元素。

    • 返回值:列表的尾元素。当 key 不存在时,返回 nil 。
  • LLEN key:返回列表 key 的长度。

    • 如果 key 不存在,则 key 被解释为一个空列表,返回 0 .
    • 如果 key 不是列表类型,返回一个错误。
  • LRANGE key start stop:返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

    • 下标(index)参数 start 和 stop 都以 0 为底,也可以使用负数下标。
    • 超出范围的下标值不会引起错误。

      • 如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,那么 LRANGE 返回一个空列表。
      • 如果 stop 下标比 end 下标还要大,Redis将 stop 的值设置为 end 。
    • 返回值:一个列表,包含指定区间内的元素。
  • LREM key count value:根据参数 count 的值,移除列表中与参数 value 相等的元素。

    • count 的值可以是以下几种:

      • count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
      • count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
      • count = 0 : 移除表中所有与 value 相等的值。
    • 返回值:被移除元素的数量。因为不存在的 key 被视作空表(empty list),所以当 key 不存在时, LREM 命令总是返回 0。
  • LINDEX key index:返回列表 key 中,下标为 index 的元素。

    • 下标(index)参数 start 和 stop 都以 0 为底,也可以使用负数下标。
    • 如果 key 不是列表类型,返回一个错误。
    • 返回值:列表中下标为 index 的元素。如果 index 参数的值不在列表的区间范围内(out of range),返回 nil 。
  • LSET key index value:将列表 key 下标为 index 的元素的值设置为 value 。

    • 当 index 参数超出范围,或对一个空列表( key 不存在)进行 LSET 时,返回一个错误。
    • 返回值:操作成功返回 ok ,否则返回错误信息。
  • LTRIM key start stop:对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

    • 超出范围的下标值不会引起错误。
    • 返回值:命令执行成功时,返回 ok 。
  • RPOPLPUSH source destination:命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:

    • 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
    • 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。
    • 举个例子,你有两个列表 source 和 destination , source 列表有元素 a, b, c , destination 列表有元素 x, y, z ,执行 RPOPLPUSH source destination 之后, source 列表包含元素 a, b , destination 列表包含元素 c, x, y, z ,并且元素 c 会被返回给客户端。
    • 如果 source 不存在,值 nil 被返回,并且不执行其他动作。
    • 如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。
    • 返回值:被弹出的元素。
(5)Set(键)

集合类型值具有唯一性,常用操作是向集合添加、删除、判断某个值是否存在,集合内部是使用值为空的散列表实现的。

  • SADD key member [member ...]:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。

    • 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
    • 当 key 不是集合类型时,返回一个错误。
    • 返回值:被添加到集合中的新元素的数量,不包括被忽略的元素。
  • SREM key member [member ...]:移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。

    • 当 key 不是集合类型,返回一个错误。
    • 返回值:被成功移除的元素的数量,不包括被忽略的元素。
  • SMEMBERS key:返回集合 key 中的所有成员。不存在的 key 被视为空集合。

    • 返回值:集合中的所有成员。
  • SISMEMBER key member:判断 member 元素是否集合 key 的成员。

    • 返回值:如果 member 元素是集合的成员,返回 1 。如果 member 元素不是集合的成员,或 key 不存在,返回 0 。
  • SDIFF key [key ...]:返回一个集合的全部成员,该集合是所有给定集合之间的差集。

    • 不存在的 key 被视为空集。
    • 返回值:交集成员的列表。
  • SINTER key [key ...]:返回一个集合的全部成员,该集合是所有给定集合的交集。

    • 不存在的 key 被视为空集。
    • 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
    • 返回值:交集成员的列表。
  • SUNION key [key ...]:返回一个集合的全部成员,该集合是所有给定集合的并集。

    • 不存在的 key 被视为空集。
    • 返回值:并集成员的列表。
  • SCARD key:返回集合 key 的基数(集合中元素的数量)。

    • 返回值:集合的基数。当 key 不存在时,返回 0 。
  • 集合运算后存储结果
  • 语法:

    • SDIFFSTROE destination key [key ...] ,差运算并存储到destination新集合中
    • SINTERSTROE destination key [key ...],交运算并存储到destination新集合中
    • SUNIONSTROE destination key [key ...],并运算并存储到destination新集合中
  • SRANDMEMBER key [count]:如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机元素。

    • 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
    • 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。
    • 返回值:只提供 key 参数时,返回一个元素;如果集合为空,返回 nil 。如果提供了 count 参数,那么返回一个数组;如果集合为空,返回空数组。
  • SPOP key:移除并返回集合中的一个随机元素。

    • 如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER 命令。
    • 返回值:被移除的随机元素。当 key 不存在或 key 是空集时,返回 nil 。
(6)SortedSet(键)
  • ZADD key score member [[score member] [score member] ...]:将一个或多个 member 元素及其 score 值加入到有序集 key 当中。

    • 如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。
    • score 值可以是整数值或双精度浮点数。
    • 如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
    • 当 key 存在但不是有序集类型时,返回一个错误。
    • 返回值:被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
  • ZSCORE key member:返回有序集 key 中,成员 member 的 score 值。

    • 如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
    • 返回值:member 成员的 score 值,以字符串形式表示。
  • ZRANGE key start stop [WITHSCORES]:返回有序集 key 中,指定区间内的成员。

    • 其中成员的位置按 score 值递增(从小到大)来排序。
    • 具有相同 score 值的成员按字典序(lexicographical order )来排列。
    • 下标参数 start 和 stop 都以 0 为底,超出范围的下标并不会引起错误。
    • 可以通过使用 WITHSCORES 选项,来让成员和它的 score 值一并返回,返回列表以 value1,score1, ..., valueN,scoreN 的格式表示。
    • 返回值:指定区间内,带有 score 值(可选)的有序集成员的列表。
  • ZREVRANGE key start stop [WITHSCORES]:返回有序集 key 中,指定区间内的成员。

    • 其中成员的位置按 score 值递减(从大到小)来排列。
    • 具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。
    • 除了成员按 score 值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。
  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]:返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。

    • 有序集成员按 score 值递增(从小到大)次序排列。
    • 具有相同 score 值的成员按字典序(lexicographical order)来排列(该属性是有序集提供的,不需要额外的计算)。
    • 可选的 LIMIT 参数指定返回结果的数量及区间(就像SQL中的 SELECT LIMIT offset, count ),注意当 offset 很大时,定位 offset 的操作可能需要遍历整个有序集,此过程最坏复杂度为 O(N) 时间。
    • 可选的 WITHSCORES 参数决定结果集是单单返回有序集的成员,还是将有序集成员及其 score 值一起返回。
    • 返回值:指定区间内,带有 score 值(可选)的有序集成员的列表。
  • ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]:返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。

    • 具有相同 score 值的成员按字典序的逆序(reverse lexicographical order )排列。
    • 除了成员按 score 值递减的次序排列这一点外, ZREVRANGEBYSCORE 命令的其他方面和 ZRANGEBYSCORE 命令一样。
    • 返回值:指定区间内,带有 score 值(可选)的有序集成员的列表。
  • ZINCRBY key increment member:为有序集 key 的成员 member 的 score 值加上增量 increment 。

    • 可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
    • 当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
    • key 不是有序集类型时,返回一个错误。
    • ore 值可以是整数值或双精度浮点数。
    • 返回值:member 成员的新 score 值,以字符串形式表示。

彩蛋

Redis默认不需要密码,如果想要给Redis设置密码,需要编辑Redis目录下的redis.conf文件,添加如下内容:

requirepass 将要设置的密码

如果给Redis设置了密码,需要通过以下方式访问:

./redis-cli -h ip地址 -p 端口号 -a 密码
Last modification:March 8th, 2019 at 04:00 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment