问题:redis
相对于关系数据库表结构优势是什么??
- 数据可设置过期时间
- 内存读写速度快
- 数据类型多样化
- 缓存,队列的功能
一、redis的特性
1、多种数据类型存储
- 字符串类型
- 散列类型
- 列表类型
- 集合类型
- 有序集合类型
2、内存存储与持久化
- 内存的读写速度远快于硬盘
- 自身提供了持久化功能(RDB、AOF两种方式)
3、功能丰富
- 可用作缓存、队列、消息订阅/发布
- 支持键的生存时间
- 按照一定规则删除相应的键
4、简单稳定
- 相比SQL而言更加简单
- 不同语言的客户端丰富
- 基于C语言开发,代码量只有3万多行
##常用命令
1、ttl key
作用:
返回key剩余时间
返回 -1:key 不存在
返回 -2:key没有生存时间
2、expire key seconds:设置过期时间秒
3、pexpire key milliseconds:设置过期时间为多少这毫秒
注意:redis3.0之后,设置key值时可以加上过期时间
语法格式 set key value nx (ex seconds | px milliseconds)
4、exists key:判断key是否存在
- 返回0:不存在
- 返回1:存在
5、persist key
作用:清除key的生存时间
6、字符串类型 k,v的其它命令
- set key value:给key赋值,并返回ok
- get key:获取key的值
- del key:删除key
- incr key: 递增key对应的value值,
- 若value不是数据型的字符,报错 (error) ERR value is not an integer or out of range
- 若value是数值型的字符,则递增成功,返回递增后的值
- incrby key increment:按increment递增key对应的value
- decr key:递减value值
- decrby key decrement:按decrement递减
- append key value:在key对应的值中追加value
- 返回值:追加后的字符串总长度
127.0.0.1:6379> get a
"abb"
127.0.0.1:6379> append a bb
(integer) 5
- strlen key
- 返回键值(value)的长度
- 若键(key)不存在,则返回0
- mset key value key2 value2 ...keyN valueN:一次设置多个键值对
- mget key key2:一次获取多个键的值
二、散列类型(hash)
1、说明:
一个散列,最多存储 2^32-1个field,且value只能存String类型的数据
2、相关命令
- hset key<string> field<string> value<string>
- 特别说明:此命令通过返回值可区分是修改还是插入新的field字段
- 返回值为1:表示插入新字段
- 返回值为0:表示更新已有字段
127.0.0.1:6379> hset hashkey 006 json6
(integer) 1 插入field
127.0.0.1:6379> hset hashkey 001 jsonNew
(integer) 0 修改filed
- hget key field
- hmset key field1 value1 field2 value2......fieldN valueN
- hmget key field1 filed2
127.0.0.1:6379> hmget hashkey 001 002 003
1) "json1"
2) "json2"
3) "json3"
127.0.0.1:6379> hmset hashkey 004 json4 005 json5
OK
- hgetall key:获取键对应的所有字段及字段值
127.0.0.1:6379> hgetall hashkey
1) "001"
2) "jsonNew"
3) "002"
4) "json2"
5) "003"
- hexists key field:判断字段是否存在
- 返回0:不存在
- 返回1:存在
- hsetnx key filed value:当字段不存在时赋值,存在则不做任何操作
- 返回0:字段已存在,不做更新
- 返回1:字段不存在,已设置成功
127.0.0.1:6379> hsetnx hashkey f01 v01
(integer) 1
127.0.0.1:6379> hsetnx hashkey f01 v02
(integer) 0
127.0.0.1:6379> hget hashkey f01
"v01"
- hdel key filed1 filed2...:删除字段
- 一次可删除多个字段
- 返回值为删除字段个数
- hincrby key filed increment:递增(没有hincr)
- 当filed不存在时,直接新增字段为filed,字段值为increment的数值。并返回新增字段值
127.0.0.1:6379> hincrby hashkey newfiled 2
(integer) 2
- 当字段存在时,按increment新增
- hkeys key:获取key对应的所有字段
- hvals key:获取key所有字段值
- hlen key :获取key的字段个数
127.0.0.1:6379> hkeys hashkey
1) "002"
2) "003"
3) "004"
4) "005"
5) "006"
6) "001"
7) "newfiled"
127.0.0.1:6379> hvals hashkey
1) "json2"
2) "json3"
3) "json4"
4) "json5"
5) "json6"
6) "2"
7) "2"
127.0.0.1:6379>
127.0.0.1:6379> hlen hashkey
(integer) 7
三、列表类型(list)
概念:redis的list内部是用双向链表实现,常用来向列表两端添加元素,或者获取列表片段。一个列表类型键最多存储2^32-1个value
## 思考:这种数据结构一般用于什么场景呢?》》》模拟队列
1、记录前N个最新登录的用户信息ID
基本操作:
- lpush key value1 value2...valueN:从队头添加
- rpush key value1 value2...valueN: 从队尾添加
- lpop key:从队头出队
- rpop key:从队尾出队
- lrange key start end :取[start,end]范围内的数值
- 注包含start,end索引的值
- 当end=-1时,表示最后一个元素
- lrem key count value:删除count个值为value的元素
- count>0,表示从左边开始删除
- count<0,表示从右边开始删除
- count=0,表示删除值为value的所有元素
- linsert key before|after pivot value:在列表key中查找pivot,并在pivot前面或后面插入value。插入失败则返回-1,插入成功返回列表长度
127.0.0.1:6379>
linsert testlist before 202 303
(integer) 8
127.0.0.1:6379> lrange testlist 0 -1
1) "7"
2) "6"
3) "5"
4) "4"
5) "3"
6) "2"
7) "303"
8) "202"
- rpoplpush source newlist :表示将source队列末位的元素出列,并加到newlist列队的队头中
127.0.0.1:6379> lrange testlist 0 -1
1) "test"
2) "7"
3) "6"
4) "5"
5) "4"
6) "3"
7) "2"
8) "303"
9) "202"
127.0.0.1:6379> rpop testlist
"202"
127.0.0.1:6379> rpoplpush testlist newlist
"303"
127.0.0.1:6379> lrange newlist 0 -1
1) "303"
127.0.0.1:6379> rpoplpush testlist newlist
"2"
127.0.0.1:6379> lrange newlist 0 -1
1) "2"
2) "303"
127.0.0.1:6379>
四、集合类型(set)
集合类型 | 列表类型 | |
存储内容 | 2^32-1 | 2^32-1 |
有序性 | 否 | 是 |
唯一性 | 是 | 否 |
常用命令:
- sadd key member1 member2...:添加元素到集合key中,不会将重复member添加到key中
- srem key member1 member2...:删除集合key中的元素
127.0.0.1:6379> sadd testset
101
1 2 3 5
101
(integer) 5
127.0.0.1:6379> smembers testset
1) "1"
2) "2"
3) "3"
4) "5"
5) "101"
127.0.0.1:6379> srem testset 5
(integer) 1
127.0.0.1:6379> smembers testset
1) "1"
2) "2"
3) "3"
4) "101"
127.0.0.1:6379>
- sismember key member :判断集合key中是否有member元素
127.0.0.1:6379> smembers testset
1) "1"
2) "2"
3) "3"
4) "101"
127.0.0.1:6379> sismember testset 101
(integer) 1
127.0.0.1:6379> sismember testset 202
(integer) 0
- sdiff keyA keyB :未集合A-B的差集 (A中有,但B中没有的元素)
127.0.0.1:6379> sadd testA 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd testB 3 4 5 6 7
(integer) 5
127.0.0.1:6379> sdiff testA testB
1) "1"
2) "2"
127.0.0.1:6379> sdiff testB testA
1) "6"
2) "7"
127.0.0.1:6379>
- sinter keyA keyB :未集合A∩B的交集
127.0.0.1:6379> sinter testA testB
1) "3"
2) "4"
3) "5"
- sunion keyA keyB:求集合A∪B的并集
127.0.0.1:6379> sunion testA testB
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
scard key :求集合中元素的个数
spop key:从集合中弹出一个元素
五、有序集合类型(zset)
1、概念:有序集合中元素都有一个分数,我们不仅可以在有序集合中插入、删除、查询元素,还可以获取分数最高,或者最低的前N个元素的信息
2、有序集合跟列表类型的区别??
- 列表类型内部是用双向链表实现的,有序集合内部是用散列实现
- 列表类型在读取两端的数据很快,但是当列表数据增多时,读取列表中间元素的速度会降低
- 有序集合因为是散列结构,所以读取中间部分的数据也无压力
- 列表中不能简单调整元素的位置,而有序集合可以通过修改分数来调整元素位置。
- 有序集合的散列结构比列表更消耗内存(是因为存了分数吗)
3、常用命令
- zadd key score member score2 member2...:添加元素,其中score是member的分数
- 返回0:当添加的元素已经存在集合中
- 返回N:成功添加的元素个数
- zscore key member :获取元素的分数
- zrange key start stop [WITHSCORES]:升序排序(从小到大),取从start到stop名次的元素(名次从0开始计算)
127.0.0.1:6379> zrange testzset 0 10 WITHSCORES
1) "b"
2) "0"
3) "f"
4) "0"
5) "c"
6) "1"
7) "a"
8) "2"
9) "e"
10) "2"
11) "d"
12) "5"
127.0.0.1:6379> zrange testzset
1 3
WITHSCORES
1) "f"
2) "0"
3) "c"
4) "1"
5) "a"
6) "2"
127.0.0.1:6379>
- zrevrange key start stop[WITHSCORES]:降序排序(从大到小)
127.0.0.1:6379> ZREVRANGE testzset 0 10 withscores
1) "d"
2) "5"
3) "e"
4) "2"
5) "a"
6) "2"
7) "c"
8) "1"
9) "f"
10) "0"
11) "b"
12) "0"
127.0.0.1:6379> zrevrange testzset 1 3
1) "e"
2) "a"
3) "c"
127.0.0.1:6379>