http://redis.readthedocs.org/en/latest/
http://huangz.iteye.com/blog/1005601
进度
Redis的官方命令参考共10个部分(Keys, Strings, Hashes, Lists ...)。
计划每3-5天更新一部分,但不保证。
欢迎任何积极性意见和反馈@huangz1990
2011.4.17 Keys部分完成
2011.4.21 Strings部分完成
2011.4.29 Hash部分完成,Redis升级到2.2.5。
KEYS部分
DEL key [key2, ...]
删除指定的key
复杂度:
单个字符串O(1), 多个字符串(数量N)为O(N)。
列表、集合、有序集合和哈希表(list,set,zset,hash)为O(M),M为以上数据结构内的key数量。
返回值:
被移除key的数量。
- redis> mset name "huangz" age 20 # 一次set多个key-value
- OK
- redis> del name
- (integer) 1
- redis> del age fake_key # fake_key不存在,只有age被删除
- (integer) 1
KEYS pattern
查找符合给定模式的key
h?llo命中hello, hallo and hxllo,等。
h*llo命中hllo和heeeeello等。
h[ae]llo命中hello和hallo,但不命中hillo。
特殊符号用"\"隔开
复杂度:
O(N),N为数据库中key的数量。
KEYS的速度非常快,使用一般的手提电脑可以在40毫秒内扫描100万个key。
但在一个大的数据库中频繁使用KEYS命令仍然可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用集合(set)结构。
返回值:
符合给定模式的key列表。
- redis> mset one 1 two 2 three 3 four 4
- OK
- redis> keys *o*
- 1) "four"
- 2) "two"
- 3) "one"
- redis> keys t??
- 1) "two"
- redis> keys t[w]*
- 1) "two"
- redis> keys * # 匹配数据库内所有key
- 1) "four"
- 2) "three"
- 3) "two"
- 4) "one"
RANDOMKEY
从当前数据库中随机返回一个key
复杂度:
O(1)
返回值:
一个key。
当数据库为空时,返回nil。
- redis> mset fruit "apple" drink "beer" food "cookies"
- OK
- redis> randomkey
- "fruit"
- redis> randomkey
- "food"
- redis> flushdb # 删除当前数据库所有key
- OK
- redis> randomkey
- (nil)
TTL key
返回给定key的剩余生存时间。
复杂度:
O(1)
返回值:
剩余生存时间(以秒为单位)。
当key不存在或过期时,返回-1 。
- redis> set name "huangz"
- OK
- redis> expire name 30 # 设置过期时间为30秒
- (integer) 1
- redis> get name
- "huangz"
- redis> ttl name
- (integer) 25
- redis> get name
- "huangz"
- redis> ttl name
- (integer) 15
- redis> ttl name # 30秒过去,name过期
- (integer) -1
- redis> get name
- (nil)
EXISTS key
检查给定key是否存在。
复杂度:
O(1)
返回值:
若key存在,返回1。
不存在则返回0 。
- redis> set db "redis"
- OK
- redis> exists db # key存在
- (integer) 1
- redis> del db
- (integer) 1
- redis> exists db # key不存在
- (integer) 0
MOVE key db
将当前数据库(默认为0)的key移动到指定的数据库db。
如果当前数据库(源数据库)和指定数据库(目标数据库)有相同名字的指定key,或者key不存在于当前数据库,那么MOVE没有任何效果。因此,也可以利用这一特性,将MOVE当作锁(locking)。
复杂度:
O(1)
返回值:
移动成功返回1。
失败则返回0 。
- redis> SELECT 0 # redis默认使用数据库0,为了清晰起见,这里再显式指定一次。
- OK
- redis> SET song "secret base - Zone"
- OK
- redis> MOVE song 1 # 将song移动到数据库1
- (integer) 1
- redis> EXISTS song # song已经被移走
- (integer) 0
- redis> SELECT 1 # 使用数据库1
- OK
- redis:1> EXISTS song # 证实song被移到了数据库1(注意命令操作符变成了"redis:1",表明正在使用数据库1)
- (integer) 1
- # 当key不存在的时候
- redis:1> EXISTS fake_key
- (integer) 0
- redis:1> MOVE fake_key 0 # 试图从数据库1移动一个不存在的key到数据库0,失败
- (integer) 0
- redis:1> select 0 # 使用数据库0
- OK
- redis> EXISTS fake_key # 证实fake_key不存在
- (integer) 0
- # 当源数据库和目标数据库有相同的key时
- redis> SELECT 0 # 使用数据库0
- OK
- redis> SET favorite_fruit "banana"
- OK
- redis> SELECT 1 # 使用数据库1
- OK
- redis:1> SET favorite_fruit "apple"
- OK
- redis:1> SELECT 0 # 使用数据库0,并试图将favorite_fruit移动到数据库1
- OK
- redis> MOVE favorite_fruit 1 # 因为两个数据库有相同的key,MOVE失败
- (integer) 0
- redis> GET favorite_fruit # 数据库0的favorite_fruit没变
- "banana"
- redis> SELECT 1
- OK
- redis:1> GET favorite_fruit # 数据库1的favorite_fruit也是
- "apple"
- redis:1> SET message "hello world"
- OK
- redis:1> RENAME message greeting
- OK
- redis:1> EXISTS message # message不复存在
- (integer) 0
- redis:1> EXISTS greeting # greeting取而代之
- (integer) 1
- # 当key不存在时,返回错误
- redis:1> RENAME fake_key never_exists
- (error) ERR no such key
- # 当newkey已存在时,RENAME会覆盖旧newkey
- redis:1> SET pc "lenovo"
- OK
- redis:1> SET personal_computer "dell"
- OK
- redis:1> RENAME pc personal_computer
- OK
- redis:1> GET pc
- (nil)
- redis:1> GET personal_computer # dell“没有”了
- "lenovo"
- redis:1> SET weather "sunny" # 构建一个字符串
- OK
- redis:1> TYPE weather
- string
- redis:1> LPUSH book_list "programming in scala" # 构建一个列表
- (integer) 1
- redis:1> LPUSH book_list "algorithms in C"
- (integer) 2
- redis:1> TYPE book_list
- list
- redis:1> SADD pat "dog" # 构建一个集合
- (integer) 1
- redis:1> TYPE pat
- set
- redis> SET cache_page "www.twitter.com/huangz1990"
- OK
- redis> EXPIRE cache_page 30 # 设置30秒后过期
- (integer) 1
- redis> TTL cache_page
- (integer) 24
- redis> EXPIRE cache_page 30000 # 更新过期时间,30000秒
- (integer) 1
- redis> TTL cache_page
- (integer) 29996
- redis> SET game "COD" # 一个字符串
- OK
- redis> OBJECT REFCOUNT game # 只有一个引用
- (integer) 1
- redis> OBJECT IDLETIME game # 空转时间
- (integer) 90
- redis> GET game # 提取game, 让它处于活跃(active)状态
- "COD"
- redis> OBJECT IDLETIME game # 不再处于空转
- (integer) 0
- redis> OBJECT ENCODING game # 字符串的编码方式
- "raw"
- redis> SET phone 15820123123 # 长的数字被编码为字符串
- OK
- redis> OBJECT ENCODING phone
- "raw"
- redis> SET age 20 # 短数字被编码为int
- OK
- redis> OBJECT ENCODING age
- "int"
- # newkey不存在,成功
- redis> SET player "MPlyaer"
- OK
- redis> EXISTS best_player
- (integer) 0
- redis> RENAMENX player best_player
- (integer) 1
- # newkey存在时,失败
- redis> SET animal "bear"
- OK
- redis> SET favorite_animal "butterfly"
- OK
- redis> RENAMENX animal favorite_animal
- (integer) 0
- redis> get animal
- "bear"
- redis> get favorite_animal
- "butterfly"
- redis> SET live_man "fake person"
- OK
- redis> EXPIREAT live_man 2000000000 # unix steamp DATE: 05 / 17 / 33 @ 10:33:20pm EST
- (integer) 1
- redis> TTL live_man
- (integer) 697061482
- redis> SET time_to_say_goodbye "oh, please no delete me"
- OK
- redis> EXPIRE time_to_say_goodbye 300
- (integer) 1
- redis> TTL time_to_say_goodbye
- (integer) 293
- redis> PERSIST time_to_say_goodbye
- (integer) 1
- redis> TTL time_to_say_goodbye # 移除成功
- (integer) -1
- redis> LPUSH today_cost 30
- (integer) 1
- redis> LPUSH today_cost 1.5
- (integer) 2
- redis> LPUSH today_cost 10
- (integer) 3
- redis> LPUSH today_cost 8
- (integer) 4
- redis> SORT today_cost
- 1) "1.5"
- 2) "8"
- 3) "10"
- 4) "30"
- redis> LPUSH website "www.reddit.com"
- (integer) 1
- redis> LPUSH website "www.slashdot.com"
- (integer) 2
- redis> LPUSH website "www.infoq.com"
- (integer) 3
- # 默认排序
- redis> SORT website
- 1) "www.infoq.com"
- 2) "www.slashdot.com"
- 3) "www.reddit.com"
- # 按字符排序
- redis> SORT website ALPHA
- 1) "www.infoq.com"
- 2) "www.reddit.com"
- 3) "www.slashdot.com"
- redis> LPUSH rank 30
- (integer) 1
- redis> LPUSH rank 56
- (integer) 2
- redis> LPUSH rank 42
- (integer) 3
- redis> LPUSH rank 22
- (integer) 4
- redis> LPUSH rank 0
- (integer) 5
- redis> LPUSH rank 11
- (integer) 6
- redis> LPUSH rank 32
- (integer) 7
- redis> LPUSH rank 67
- (integer) 8
- redis> LPUSH rank 50
- (integer) 9
- redis> LPUSH rank 44
- (integer) 10
- redis> LPUSH rank 55
- (integer) 11
- redis> SORT rank LIMIT 0 5
- 1) "0"
- 2) "11"
- 3) "22"
- 4) "30"
- 5) "32"
- redis> SORT rank LIMIT 0 5 DESC
- 1) "78"
- 2) "67"
- 3) "56"
- 4) "55"
- 5) "50"
- # admin
- redis> LPUSH user_id 1
- (integer) 1
- redis> SET user_name_1 admin
- OK
- redis> SET user_level_1 9999
- OK
- # huangz
- redis> LPUSH user_id 2
- (integer) 2
- redis> SET user_name_2 huangz
- OK
- redis> SET user_level_2 10
- OK
- # jack
- redis> LPUSH user_id 59230
- (integer) 3
- redis> SET user_name_59230 jack
- OK
- redis> SET user_level_59230 3
- OK
- # hacker
- redis> LPUSH user_id 222
- (integer) 4
- redis> SET user_name_222 hacker
- OK
- redis> SET user_level_222 9999
- OK
- redis> SORT user_id BY user_level_* DESC
- 1) "222"
- 2) "1"
- 3) "2"
- 4) "59230"
- redis> SORT user_id BY user_level_* DESC GET user_name_*
- 1) "hacker"
- 2) "admin"
- 3) "huangz"
- 4) "jack"
- # 先添加一些测试数据
- redis> SET user_password_222 "hey,im in"
- OK
- redis> SET user_password_1 "a_long_long_password"
- OK
- redis> SET user_password_2 "nobodyknows"
- OK
- redis> SET user_password_59230 "jack201022"
- OK
- # 获取name和password
- redis> SORT user_id BY user_level_# DESC GET user_name_* GET user_password_*
- 1) "hacker" # 用户名
- 2) "hey,im in" # 密码
- 3) "jack"
- 4) "jack201022"
- 5) "huangz"
- 6) "nobodyknows"
- 7) "admin"
- 8) "a_long_long_password"
- # 注意GET操作是有序的,GET user_name_* GET user_password_* 和 GET user_password_* GET user_name_*返回的结果位置不同
- redis> SORT user_id BY user_level_# DESC GET user_password_* GET user_name_*
- 1) "hey,im in" # 密码
- 2) "hacker" # 用户名
- 3) "jack201022"
- 4) "jack"
- 5) "nobodyknows"
- 6) "huangz"
- 7) "a_long_long_password"
- 8) "admin"
- redis> SORT user_id BY user_level_* DESC GET # GET user_name_* GET user_password_*
- 1) "222" # id
- 2) "hacker" # name
- 3) "hey,im in" # password
- 4) "1"
- 5) "admin"
- 6) "a_long_long_password"
- 7) "2"
- 8) "huangz"
- 9) "nobodyknows"
- 10) "59230"
- 11) "jack"
- 12) "jack201022"
- # 确保fake_key不存在
- redis> EXISTS fake_key
- (integer) 0
- # 以fake_key作BY参数,不排序,只GET name 和 GET password
- redis> SORT user_id BY fake_key GET # GET user_name_* GET user_password_*
- 1) "222"
- 2) "hacker"
- 3) "hey,im in"
- 4) "59230"
- 5) "jack"
- 6) "jack201022"
- 7) "2"
- 8) "huangz"
- 9) "nobodyknows"
- 10) "1"
- 11) "admin"
- 12) "a_long_long_password"
- redis> EXISTS user_info_sorted_by_level # 确保指定key不存在
- (integer) 0
- redis> SORT user_id BY user_level_* GET # GET user_name_* GET user_password_* STORE user_info_sorted_by_level # 排序
- (integer) 12 # 显示有12条结果被保存了
- redis> LRANGE user_info_sorted_by_level 0 11 # 查看排序结果
- 1) "59230"
- 2) "jack"
- 3) "jack201022"
- 4) "2"
- 5) "huangz"
- 6) "nobodyknows"
- 7) "222"
- 8) "hacker"
- 9) "hey,im in"
- 10) "1"
- 11) "admin"
- 12) "a_long_long_password"
- # 假设现在我们的用户表新增了一个serial项来为作为每个用户的序列号
- # 序列号以哈希表的形式保存在serial哈希域内。
- redis> HMSET serial 1 23131283 2 23810573 222 502342349 59230 2435829758
- OK
- # 我们希望以比较serial中的大小来作为排序user_id的方式
- redis> SORT user_id BY *->serial
- 1) "222"
- 2) "59230"
- 3) "2"
- 4) "1"