Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。一段来自百度的介绍,最重要的是,Redis很流行。
安装过程就不写了,Ubuntu版的就一句话,其它版本请自行Google。
# 启动Redis:
reidis -cli
# 设置数据: set key value
127.0.0.1:6379> set name Tom
OK
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> set garde boy
OK
# 获取所有键值:
127.0.0.1:6379> keys *
1) "garde"
2) "age"
3) "name"
127.0.0.1:6379> type name
string
127.0.0.1:6379> rename name Jack
OK
127.0.0.1:6379> keys *
1) "garde"
2) "Jack"
3) "age"
127.0.0.1:6379> del name age garde
(integer) 2
127.0.0.1:6379> keys *
1) "Jack"
Redis支持多种数据类型,如String、List、Set、Sorted Set、Hash等。
1.String类型
# set key value** : 设置 key 对应 String 类型的值,返回 1 表示成功,返回 0 表示失败;
127.0.0.1:6379> set key1 value1
OK
# get key : 获取 key 对应的 string 值,如果 key 不存在返回 nli;
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get key2
(nil)
# mset key1 value1 ... keyN valueN : 一次设置多个 key 的值,成功返回 1,表示所有的值都设置,失败返回 0, 表示没有任何值被设置;
127.0.0.1:6379> mset key2 value2 key3 value3 key4 value4
OK
# mget key1 keyN** : 一次获取多个 key 的值,如果对应 key 不存在,则对应 key 返回 nli;
127.0.0.1:6379> mget key3 key4 key5
1) "value3"
2) "value4"
3) (nil)
# incr key : 向 key 对应的值 加1, 并返回新的值。如果 key 对应的值不是 int 类型,则会返回错误,如果 key 对应的值不存在,则设置 key 的值为1;
127.0.0.1:6379> incr key1
(error) ERR value is not an integer or out of range
127.0.0.1:6379> set key1 100
OK
127.0.0.1:6379> incr key1
(integer) 101
127.0.0.1:6379> incr key5
(integer) 1
# decr key : 向 key 对应的 减1, 并返回新的值。如果 key 对应的值不是 int类型,则会返回错误,如果 key 对应的值不存在,则设置 key 的值为 -1;
127.0.0.1:6379> decr key1
(integer) 100
127.0.0.1:6379> decr key2
(error) ERR value is not an integer or out of range
127.0.0.1:6379> decr key6
(integer) -1
优秀实践:String类型支持 incr 操作,可以用作统计计算,比如统计网站访问次数、博客访问次数等。
2.List类型
# lpush : 向 key 对应的 List 头部添加一个字符串元素,成功返回 1,失败返回 0;
127.0.0.1:6379> lpush list1 3
(integer) 1
127.0.0.1:6379> lpush list1 2
(integer) 2
127.0.0.1:6379> lpush list1 1
(integer) 3
127.0.0.1:6379> lpush list1 1
(integer) 4
# rpush : 向 key 对应的 List 尾部添加一个字符串元素,成功返回 1,失败返回 0;
127.0.0.1:6379> rpush list1 4
(integer) 5
127.0.0.1:6379> rpush list1 5
(integer) 6
127.0.0.1:6379> rpush list1 6
(integer) 7
# llen key : 返回 key 对应 List 长度,如果 key 不存在返回 0, 如果 Key 对应类型不是 List 返回错误;
127.0.0.1:6379> llen list1
(integer) 7
127.0.0.1:6379> llen nothing
(integer) 0
# lrange key start end : 返回指定区间内(start - end)的元素,下标从0开始,负值表示从链表尾部开始计算,-1表示倒数第一个元素,key 不存在返回空列表;
127.0.0.1:6379> lrange list1 2 4
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> lrange list1 -3 -1
1) "4"
2) "5"
3) "6"
127.0.0.1:6379> lrange list1 100 200
(empty list or set)
# lpop : 从 List 头部删除并返回删除元素。如果 key 对应 List 不存在或者为空返回 nil,如果 key 对应值不是 List 返回错误;
127.0.0.1:6379> lpop list1
"1"
127.0.0.1:6379> lpop list1
"1"
127.0.0.1:6379> lpop list1
"2"
127.0.0.1:6379> lpop nothing
(nil)
127.0.0.1:6379> lpop key1
(error) WRONGTYPE Operation against a key holding the wrong kind of value
# rpop : 从 List 尾部删除并返回删除元素。其他规则同 lpop;
127.0.0.1:6379> rpop list1
"6"
127.0.0.1:6379> rpop list1
"5"
127.0.0.1:6379> rpop list1
"4"
127.0.0.1:6379> rpop list1
"3"
127.0.0.1:6379> rpop list1
(nil)
优秀实践:采用 List 可以实现定时计划任务队列功能,减轻数据库压力。新的计划任务使用 rpush 放入队列尾部,然后使用 lpop 将队列头部任务取出执行。
3.Set 类型
# sadd key member : 添加一个 String 元素到 key 对应的 Set 集合中,成功返回1,如果元素已经存在集合中,返回0, key 对应的 Set 不存在返回错误;
127.0.0.1:6379> sadd set1 Tom
(integer) 1
127.0.0.1:6379> sadd set1 Jack
(integer) 1
127.0.0.1:6379> sadd set1 Marry
(integer) 1
127.0.0.1:6379> sadd set1 Lcy
(integer) 1
127.0.0.1:6379> sadd set1 Lcy
(integer) 0
# srem key member : 从 key 对应的 Set 中移除给定元素,成功返回1,如果 member 在集合中不存在或者 key 不存在返回0,如果 key 对应的不是 Set 类型返回错误;
127.0.0.1:6379> srem set1 Lcy
(integer) 1
127.0.0.1:6379> srem set1 nothing
(integer) 0
# spop key : 删除并返回 key 对应 Set 中的一个随机元素,如果 Set 为空或者 key 对应的 Set 不存在返回 cli
127.0.0.1:6379> spop set1
"Jack"
127.0.0.1:6379> spop set1
"Tom"
127.0.0.1:6379> spop set2
(nil)
#scard key : 返回 Set 的元素个数,如果 Set 为空或者 key 不存在返回0;
127.0.0.1:6379> scard set1
(integer) 1
127.0.0.1:6379> scard nothing
(integer) 0
# sismember key member : 判断 member 是否存在于 key 中,存在返回1,不存在或者 key 对应的 Set 集合不存在返回0;
127.0.0.1:6379> sismember set1 Jack
(integer) 0
127.0.0.1:6379> sismember set1 Marry
(integer) 1
127.0.0.1:6379> sismember set1 Tom
(integer) 0
# sinter key1 key2 keyN : 返回所有给定 key 的交集;
# 集合1
127.0.0.1:6379> sadd set1 C
(integer) 1
127.0.0.1:6379> sadd set1 Java
(integer) 1
127.0.0.1:6379> sadd set1 PHP
(integer) 1
# 集合2
127.0.0.1:6379> sadd set2 PHP
(integer) 1
127.0.0.1:6379> sadd set2 Java
(integer) 1
127.0.0.1:6379> sadd set2 C++
(integer) 1
# 集合3
127.0.0.1:6379> sadd set3 Python
(integer) 1
127.0.0.1:6379> sadd set3 PHP
(integer) 1
127.0.0.1:6379> sadd set3 Java
(integer) 1
127.0.0.1:6379> sinter set1 set2 set3
1) "PHP"
2) "Java"
# smembers key : 返回 key 对应 Set 的所有元素,结果是无序的;
127.0.0.1:6379> smembers set1
1) "PHP"
2) "C"
3) "Java"
127.0.0.1:6379> smembers set2
1) "PHP"
2) "C++"
3) "Java"
127.0.0.1:6379> smembers set3
1) "PHP"
2) "Python"
3) "Java"
优秀实践:Set 数据类型的有点是快速查找元素是否存在,用于记录一些不能重复的数据。例如在某些投票系统中,每个用户一天只能投票一次,那么可以使用 Set 来记录某个用户的投票情况,只需要以日期作为 Set 的 key,将用户ID作为 member,以日期作为 key 去查询用户ID是否存在即可。
4.Sorted Set类型
# zadd key score member : 添加元素 member 到集合,元素在集合中存在则更新对应 score;
127.0.0.1:6379> zadd sort_set1 1 one
(integer) 1
127.0.0.1:6379> zadd sort_set1 2 two
(integer) 1
127.0.0.1:6379> zadd sort_set1 100 one
(integer) 0
127.0.0.1:6379> zadd sort_set1 3 three
(integer) 1
# zrem key member : 删除指定元素,1表示成功,如果元素不存在返回0;
127.0.0.1:6379> zrem sort_set1 three
(integer) 1
127.0.0.1:6379> zrem sort_set1 nothing
(integer) 0
# zincrby key incr member : 增加对应 member 的 score 值,并且重新排序,返回更新后的 score 值;
127.0.0.1:6379> zincrby sort_set1 101 one
"201"
# zcard key : 返回集合中元素个数;
127.0.0.1:6379> zcard sort_set1
(integer) 2
# zscore key element : 返回给定元素对应的 score;
127.0.0.1:6379> zscore sort_set1 one
"201"
127.0.0.1:6379> zscore sort_set1 two
"2"
优秀实践:Sorted Set 类型在 Web 应用中非常有用。例如问答系统中按 “赞同数” 排序,将 “赞同字段” 设置为 Sorted Set 的 member 值,将具体的赞同数量数据设置为对应的 score,用户每次按 “赞同” 时,只需要执行 zincrby 命令增加赞同数量即可;
5.Hash类型
# hset key field value : 设置 key 对应的 Hash 对象中指定域的值。如果 key 对应的 Hash 对象不存在,将创建此 Hash 对象。如果指定的域已经存在,其值将被重写;
127.0.0.1:6379> hset hash_person name 游梦惊园
(integer) 1
127.0.0.1:6379> hset hash_person blog www.codean.net
(integer) 1
# hget key field : 返回与 field 域关联的值,如果该域不存在或者 key 对应的 Hash 对象不存在,返回值为 cli;
127.0.0.1:6379> hget hash_person blog
"http://www.cnblogs.com/duanbiaowu"
127.0.0.1:6379> hget hash_person age
(nil)
127.0.0.1:6379> hget hash_nothing blog
(nil)
# hmset key field1 value1 fieldN valueN : 设置存储在 key 对应的 Hash 对象中指定域的值。该命令会复写 Hash 中已经存在的域。如果 key 对应的 Hash 对象不存在,将创建此 Hash 对象;
127.0.0.1:6379> hmset hash_person name 游梦惊园2 gender man
OK
# hmget key field1 field2 fieldN : 返回存储在 key 对应的 Hash 对象中各个指定域相关联的值。对应在 Hash 对象中不存在的域,返回值为 cli;
127.0.0.1:6379> hmset hash_person name 游梦惊园2 gender man
OK
127.0.0.1:6379> hmget hash_person name blog age gender
1) "xe6xb8xb8xe6xa2xa6xe6x83x8axe5x9bxad2"
2) "www.codean.net"
3) (nil)
4) "man"
# hexists key field : 查看指定 field 域是否已经存在;
127.0.0.1:6379> hexists hash_person name
(integer) 1
127.0.0.1:6379> hexists hash_person age
(integer) 0
# hlen key : 返回 key 对应的 Hash 对象中 field 数,如果 key 不存在,返回值为0;
127.0.0.1:6379> hlen hash_person
(integer) 3
127.0.0.1:6379> hlen hash_person2
(integer) 0
# hkeys key : 返回 key 对应的 Hash 对象中所有 field 名称;
127.0.0.1:6379> hkeys hash_person
1) "name"
2) "blog"
3) "gender"
# hvals key : 返回 key 对应的 Hash 对象中所有值;
127.0.0.1:6379> hvals hash_person
1) "xe6xb8xb8xe6xa2xa6xe6x83x8axe5x9bxad2"
2) "www.codean.net"
3) "man"
优秀实践:Hash类型适合存储对象,例如用户信息,将用户ID作为 key,用户信息保存到 Hash 类型中。
参考书籍:PHP核心技术与最佳实践