前言
通常而言目前的数据库分类有几种,包括 SQL/NSQL,关系数据库,键值数据库等等,Redis本质上也是一种键值数据库的,但它在保持键值数据库简单快捷特点的同时,又吸收了部分关系数据库的优点。从而使它的位置处于关系数据库和键值数据库之间。
Redis的应用场景有哪些?
Redis 的应用场景包括:缓存系统(“热点”数据:高频读、低频写)、计数器、消息队列系统、排行榜、社交网络和实时系统。
Redis的数据类型及主要特性
Redis提供的数据类型主要分为5种自有类型和一种自定义类型,这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和顺序集合类型。
一、Key
set key value 设置key
get key 获取key
127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> get test
"123"
keys * 获取所有的key
127.0.0.1:6379> keys *
1) "mylist"
2) "11563211234"
select n 选择数据库切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值。默认使用 0 号数据库
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]>
move key n 将当前的数据库key移动到某个数据库,目标库有,则不能移动
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> move test 2
(integer) 1
127.0.0.1:6379>
flush db 清除指定库 randomkey 随机key
127.0.0.1:6379> randomkey
"1236636"
127.0.0.1:6379> randomkey
"49"
127.0.0.1:6379> randomkey
"1892588"
127.0.0.1:6379> randomkey
"18365985"
127.0.0.1:6379>
type key 获取key类型
127.0.0.1:6379> set a 123
OK
127.0.0.1:6379> type a
string
mset key1 value1 key2 value2 key3 value3
mget key1 key2 key3 批量新建,查询
127.0.0.1:6379> mset test1 123 test2 234 test3 456
OK
127.0.0.1:6379> mget test1 test2 test3
1) "123"
2) "234"
3) "456"
del key 删除key
127.0.0.1:6379> del test1
(integer) 1
127.0.0.1:6379> get test1
(nil)
exists key 判断是否存在key
127.0.0.1:6379> exists test
(integer) 1
127.0.0.1:6379> exists test66
(integer) 0
expire key 10 10秒过期,为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
127.0.0.1:6379> expire test2 0
(integer) 1
127.0.0.1:6379> get test2
(nil)
pexpire key 1000 此命令与 EXPIRE 完全相同,但密钥的生存时间以毫秒而不是秒为单位指定
127.0.0.1:6379> pexpire test3 1000
(integer) 1
persist key 删除过期时间
127.0.0.1:6379> set test 111
OK
127.0.0.1:6379> persist test
(integer) 0
127.0.0.1:6379> expire test 100000
(integer) 1
127.0.0.1:6379> persist test
(integer) 1
二、字符串(String)类型
getrange key 0 -1 字符串分段
127.0.0.1:6379> set test jfasfgf
OK
127.0.0.1:6379> getrange test 1 3
"fas"
getset key new_cxx 设置值,返回旧值
127.0.0.1:6379> getset test 123
"jfasfgf"
127.0.0.1:6379> get test
"123"
setnx key value 不存在就插入(not exists)
127.0.0.1:6379> get test6
(nil)
127.0.0.1:6379> setnx test6 123456
(integer) 1
127.0.0.1:6379> get test6
"123456"
setex key time value setex 命令为指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值
127.0.0.1:6379> setex test6 10000 fadsf
OK
127.0.0.1:6379> get test6
"fadsf"
setrange key index value 从index开始替换value
127.0.0.1:6379> setrange test6 1 569ddd
(integer) 7
127.0.0.1:6379> get test6
"f569ddd"
incr key 递增1
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> incr age
(integer) 11
127.0.0.1:6379> get age
"11"
incrby key 10 递增10
127.0.0.1:6379> get age
"11"
127.0.0.1:6379> incrby age 10
(integer) 21
127.0.0.1:6379> get age
"21"
decr key 递减
127.0.0.1:6379> get age
"21"
127.0.0.1:6379> decr age
(integer) 20
decrby key 10 递减
127.0.0.1:6379> get age
"20"
127.0.0.1:6379> decrby age 10
(integer) 10
127.0.0.1:6379> get age
"10"
incrbyfloat 增减浮点数
127.0.0.1:6379> set test2 10.23
OK
127.0.0.1:6379> incrbyfloat test2 0.1
"10.33"
append key value 追加
127.0.0.1:6379> append test2 ashj
(integer) 9
127.0.0.1:6379> get test2
"10.33ashj"
strlen key 长度
127.0.0.1:6379> strlen test2
(integer) 9
getbit/setbit/bitcount/bitop 位操作对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
三、散列(Hset)类型
散列类型与Java中的HashMap相似,是一组键值对的集合,且支持单独对其中一个键进行增删改查操作。
hset key field value将哈希表 key 中的域 field 的值设为 value 。如果 key 不存在,一个新的哈希表被创建并进行hset操作。如果域 field 已经存在于哈希表中,旧值将被覆盖。
127.0.0.1:6379> hset htest fileld 123
(integer) 1
127.0.0.1:6379> hset htest fileld1 123aa
(integer) 1
hget key fileld
127.0.0.1:6379> hget htest fileld1
"123aa"
127.0.0.1:6379> hget htest fileld
"123"
hmset myhash name cxx age 25 note "i am notes"
hmget myhash name age note
127.0.0.1:6379> hmset myhash name cxx age 25 note "i am notes"
OK
127.0.0.1:6379> hmget myhash name age note
1) "cxx"
2) "25"
3) "i am notes"
hgetall myhash 获取所有的
127.0.0.1:6379> hgetall htest
1) "fileld"
2) "123"
3) "fileld1"
4) "123aa"
hexists myhash name 是否存在
127.0.0.1:6379> hexists htest fileld
(integer) 1
127.0.0.1:6379> hexists htest fileld66
(integer) 0
hsetnx myhash score 100 命令用于为哈希表中不存在的的字段赋值
127.0.0.1:6379> hsetnx myhash sex nan
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "name"
2) "cxx"
3) "age"
4) "25"
5) "note"
6) "i am notes"
7) "sex"
8) "nan"
hincrby myhash id 1 递增
127.0.0.1:6379> hincrby myhash age 1
(integer) 26
hdel myhash name 删除
127.0.0.1:6379> hgetall myhash
1) "name"
2) "cxx"
3) "age"
4) "26"
5) "note"
6) "i am notes"
7) "sex"
8) "nan"
127.0.0.1:6379> hdel myhash note
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "name"
2) "cxx"
3) "age"
4) "26"
5) "sex"
6) "nan"
127.0.0.1:6379>
hkeys myhash 只取key
127.0.0.1:6379> hgetall myhash
1) "name"
2) "cxx"
3) "age"
4) "26"
5) "sex"
6) "nan"
127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "sex"
hvals myhash 只取value
127.0.0.1:6379> hgetall myhash
1) "name"
2) "cxx"
3) "age"
4) "26"
5) "sex"
6) "nan"
127.0.0.1:6379> hvals myhash
1) "cxx"
2) "26"
3) "nan"
hlen myhash 长度
127.0.0.1:6379> hgetall myhash
1) "name"
2) "cxx"
3) "age"
4) "26"
5) "sex"
6) "nan"
127.0.0.1:6379> hlen myhash
(integer) 3
四、Set类型
redis集合(set)类型和list列表类型类似,都可以用来存储多个字符串元素的集合。但是和list不同的是set集合当中不允许重复的元素。而且set集合当中元素是没有顺序的,不存在元素下标。
sadd myset redis
smembers myset 数据集合
127.0.0.1:6379> smembers myset
1) "a"
2) "b"
3) "g"
4) "c"
5) "e"
6) "value"
7) "f"
8) "efg"
127.0.0.1:6379> sadd myset 123
(integer) 1
127.0.0.1:6379> smembers myset
1) "g"
2) "c"
3) "e"
4) "value"
5) "f"
6) "efg"
7) "b"
8) "123"
9) "a"
127.0.0.1:6379>
srem myset set1 删除
127.0.0.1:6379> srem myset value
(integer) 1
127.0.0.1:6379> smembers myset
1) "e"
2) "f"
3) "efg"
4) "b"
5) "g"
6) "123"
7) "a"
8) "c"
sismember myset set1 判断元素是否在集合中
127.0.0.1:6379> smembers myset
1) "e"
2) "f"
3) "efg"
4) "b"
5) "g"
6) "123"
7) "a"
8) "c"
127.0.0.1:6379> sismember myset value
(integer) 0
127.0.0.1:6379> sismember myset e
(integer) 1
scard key_name 个数
127.0.0.1:6379> smembers myset
1) "b"
2) "g"
3) "e"
4) "123"
5) "efg"
6) "f"
7) "a"
8) "c"
127.0.0.1:6379> scard myset
(integer) 8
sdiff | sinter | sunion 操作:集合间运算:差集 | 交集 | 并集
127.0.0.1:6379> smembers myset
1) "g"
2) "p"
3) "e"
4) "123"
5) "efg"
6) "f"
7) "paaa"
8) "a"
9) "c"
127.0.0.1:6379> smembers myset2
1) "c"
2) "paa"
3) "pp"
4) "a"
127.0.0.1:6379> sdiff myset myset2
1) "paaa"
2) "g"
3) "p"
4) "e"
5) "123"
6) "f"
7) "efg"
127.0.0.1:6379> sinter myset myset2
1) "c"
2) "a"
127.0.0.1:6379> sunion myset myset2
1) "paa"
2) "g"
3) "123"
4) "e"
5) "p"
6) "efg"
7) "f"
8) "pp"
9) "paaa"
10) "a"
11) "c"
127.0.0.1:6379>
srandmember 随机获取集合中的元素
127.0.0.1:6379> srandmember myset
"b"
127.0.0.1:6379> srandmember myset
"f"
127.0.0.1:6379> srandmember myset
"g"
127.0.0.1:6379> srandmember myset
"f"
spop 从集合中弹出一个元素
127.0.0.1:6379> spop myset
"a"
127.0.0.1:6379> spop myset
"g"
127.0.0.1:6379> spop myset
"b"
127.0.0.1:6379>
五、List类型
lpush mylist a b c 左插入
rpush mylist x y z 右插入
127.0.0.1:6379> lpush mylist1 a b c
(integer) 3
127.0.0.1:6379> rpush mylist2 e d f
(integer) 3
lrange mylist 0 -1 数据集合
127.0.0.1:6379> lrange mylist1 0 2
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> lrange mylist2 0 2
1) "e"
2) "d"
3) "f"
lpop mylist 左弹出元素 rpop mylist 右弹出元素
127.0.0.1:6379> lrange mylist1 0 2
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> lpop mylist1
"c"
127.0.0.1:6379> rpop mylist1
"a"
127.0.0.1:6379>
llen mylist 长度
127.0.0.1:6379> llen mylist2
(integer) 3
127.0.0.1:6379> lrange mylist2 0 -1
1) "e"
2) "d"
3) "f"
lrem mylist count value 删除(Redis Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的数据)
127.0.0.1:6379> lrange mylist2 0 -1
1) "e"
2) "d"
3) "f"
127.0.0.1:6379> lrem mylist2 1 "f"
(integer) 1
127.0.0.1:6379> lrange mylist2 0 -1
1) "e"
2) "d"
lindex mylist 2 指定索引的值
127.0.0.1:6379> lindex mylist2 0
"e"
127.0.0.1:6379> lindex mylist2 9
(nil)
lset mylist 2 n 索引设值
127.0.0.1:6379> lset mylist2 1 p
OK
127.0.0.1:6379> lset mylist2 3 l
(error) ERR index out of range
127.0.0.1:6379> lindex mylist2 1
"p"
ltrim mylist 0 4 删除key(redis ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。)
127.0.0.1:6379> lrange mylist2 0 -1
1) "e"
2) "p"
127.0.0.1:6379> ltrim mylist2 0 0
OK
127.0.0.1:6379> lrange mylist2 0 -1
1) "e"
linsert mylist before a 插入
linsert mylist after a 插入
127.0.0.1:6379> lrange mylist2 0 -1
1) "e"
127.0.0.1:6379> linsert mylist2 before e a
(integer) 2
127.0.0.1:6379> linsert mylist2 after e x
(integer) 3
127.0.0.1:6379> lrange mylist2 0 -1
1) "a"
2) "e"
3) "x"
rpoplpush list list2 转移列表的数据
127.0.0.1:6379> rpoplpush mylist2 mylist1
"x"
127.0.0.1:6379> rpoplpush mylist2 mylist1
"e"
127.0.0.1:6379> lrange mylist1 0 -1
1) "e"
2) "x"
3) "b"
六、排序
sort mylist 排序
127.0.0.1:6379> lpush mylist3 1 6 9 3 4 5
(integer) 6
127.0.0.1:6379> sort mylist3
1) "1"
2) "3"
3) "4"
4) "5"
5) "6"
6) "9"
sort mylist alpha desc limit 0 2 字母排序
127.0.0.1:6379> lpush mylist4 a k l m n c r
(integer) 7
127.0.0.1:6379> sort mylist4 alpha desc limit 0 6
1) "r"
2) "n"
3) "m"
4) "l"
5) "k"
6) "c"
127.0.0.1:6379> sort mylist4 alpha asc limit 0 6
1) "a"
2) "c"
3) "k"
4) "l"
5) "m"
6) "n"
sort list by it:* desc by命令
sort list by it:* desc get it:* get参数。sort对list列表进行排序,使用了by参数,那么就不是使用list中的值来排序了,而是将list中的值[5,6,9]替换到[it:*]这个*
127.0.0.1:6379[1]> lrange mylist 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379[1]> set it:3 50
OK
127.0.0.1:6379[1]> set it:2 5
OK
127.0.0.1:6379[1]> set it:1 15
OK
127.0.0.1:6379[1]> sort mylist by it:* desc
1) "3"
2) "1"
3) "2"
127.0.0.1:6379[1]> sort mylist by it:* desc get it:*
1) "50"
2) "15"
3) "5"
sort list by it:* desc get it:* store sorc:result sort命令之store参数,不带 store 参数时,返回排序后的元素列表。带 store 参数时,返回存储在目的列表中元素个数。
127.0.0.1:6379[1]> sort mylist by it:* desc get it:* store sorc:result
(integer) 3
127.0.0.1:6379[1]> sort mylist by it:* desc get it:*
1) "50"
2) "15"
3) "5"
七、redis事务
数据库相关理论中,一个逻辑工作单元想要成为事务,就必须满足ACID,即原子性、一致性、隔离性和持久性。
- (1)原子性:一个事务内的所有SQL操作都是一个整体,因此只有所有的SQL操作都完全执行成功,该事务方可以认为提交成功。如果在提交事务过程中某一条SQL语句执行失败,则整个事务必须回滚到事务提交前的状态。
- (2)一致性:而一致性这个概念则是指,事务在完成的时候,必须要保证所有的数据都保持一致的状态,而落实到数据库的各个组成部分上,则要求开发人员能够保证数据、索引、约束、日志等在事务前后具备一致性。
- (3)隔离性:隔离性这个概念主要针对并发,其核心思想就是不同的并发事务对数据产生的修改必须是相互隔离的,假设有两个不同的事务A和B并发执行,那么对A来讲,它在执行前的状态只有两种,即B执行前和B执行后。同理,对B来讲同样是如此,这样的特性我们就称为隔离性。
- (4)持久性:是指事务完成以后它对数据的影响是永久性的。
redis事务提供了一种“将多个命令打包, 然后一次性、按顺序地执行”的机制, 并且事务在执行的期间不会主动中断 —— 服务器在执行完事务中的所有命令之后, 才会继续处理其他客户端的其他命令。
Redis中的事务是可以视为一个队列,即我们可以通过MULTI开始一个事务,这相当于我们声明了一个命令队列。接下来,我们向Redis中提交的每条命令,都会被排入这个命令队列。当我们输入EXEC命令时,将触发当前事务,这相当于我们从命令队列中取出命令并执行,所以Redis中一个事务从开始到执行会经历 开始事务 、 命令入队 和 执行事务 三个阶段。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> sadd myset a b c
QUEUED
127.0.0.1:6379> sadd myset e f g
QUEUED
127.0.0.1:6379> lpush mylist aa bb cc
QUEUED
127.0.0.1:6379> lpush mylist dd ff gg
QUEUED
127.0.0.1:6379> exec
1) (integer) 0
2) (integer) 3
3) (integer) 9
4) (integer) 12