redis 数据类型

redis 数据类型

redis并不是单纯的key-value 存储的服务器,事实上它支持多种值类型的数据结构服务器。下面就是redis 支持的数据结构.

redis的key

redis的key是安全的二进制安全的。支持使用二进制序列作为一个key, 例如:既可以将字符串‘foo’作为一个key, 同样也支持将JPEG文件内容当作key. redis 认为空字符是一个合法的key.

其他约束
- redis 的key的长度不宜太长

例如:一个具有1024个字节的key不是一个好注意,这个不仅是从内存上考虑,从一个数据集中查找这个字符时候,需要花费多次key的比较。事实上匹配一个比较大的值的, 从内存和带宽考虑hashing 它的键是更好的选择。

  • redis 的键也同样不宜太短

例如: 将一个很短的指针“u1000flw”当做一个key, 不如将它写成“user:1000:followers”. 第二种写法具有更高的可读性,虽然增加了少许的空间,当对于key和它的valu的使用空间都是微不足道的, 短小的key很显然少使用一点内存,我们需要找到两者之间的平衡。

  • 坚持一个命名规范

    对于redis的key按一定规则命名是很好的习惯。 例如:“object-type:id”
    将冒号,扩折号用在不同的字段之间

    • key允许的最大长度是512Mb

string

redis 字符类型是redis key值的最基本类型。在memcached中字符类型是它的唯一类型,对于后来者的redis 使用字符类型也是很自然的事情。既然redis的key 是字符类型,我们也可以将value设为字符类型,就这样我们就将字符类型key映射到了字符类型的value. 字符类型的value对于具有“大量用例”情况是很实用的,例如:换成html的表签或者直接缓存整个页面。

示例

> set jzq jiazq
OK
> get jzq
"jiazq"

赋值与获取

如我们看到的:使用set 和 get 命令redis对字符串类型进行赋值和取值的方式。

SET

set 是赋值操作;如果已经存在的key ,将会直接替换已经存在的value,即使赋值的是空字符串;所有说set是执行的赋值操作。字符类型value 可以是任意类型的字符形式,最大支持512MB。
set 命令有一个附加选项nx ; 当key 存在的时候,就赋值成功;
xx: 当key不存在的时候才赋值成功。
返回值:OK或者nil

> set mykey newval nx
(nil)
> set mykey newval xx
OK
INCR

格式:incr key

incr命令可以将string value解析成integer,然后将它的值加1,最终将新值覆盖旧值. 如果key 不存在,就先将key赋值为0然后在操作
返回值:操作后的值

INCRBY

格式: incrby key increment

将key存储的值增加指定的数字.如果key不存在,就会在执行这个操作之前,先设置key 的值为0,然后在继续操作。如果这个key的值不能转换成integer类型就会报错
返回值:操作后的值;

> incrby dd 34
(integer) 34
> get dd
"34"
DECR

格式:decr key

将存储的key值数字减一;如果key 不存在,就先赋值为0,然后在继续下面操作,同样,如果key值不是integer类型将有错误提示。
返回值: 操作后的值

> decr la
(integer) 0
> get la
"0"
> decr ld
(integer) -1
> get ld
"-1"
DECRBY

格式: decrby key decrement

将存储的key的数值减去指定的数值

FAQ

incr 是原子操作吗?尽管redis多个客户端在对同一个key执行incr操作命令会进入不同的奴属队列,不过出现client1 ,client2读取都是10,都执行加1,最终设置为11的情况。最终值将会是12,其他client也会在同一时间读取到最新的值。

MSET 和 MGE

redis 支持key批量赋值和获取

格式:
mset key1 value1 key2 value2 …

mget key1 key2 ..

示例

 mset l1 sfs l2 353 l3 12.23
OK
> mget l1 l2 l3
1) "sfs"
2) "353"
3) "12.23"
EXISTS

格式: exists key

返回值: 1或0

判断redis db 中是否具有一个这么一个key;

del

格式:del key

返回值:1 或者 0

如果redis db中具有一个key;无论它的值是什么,都将删除.

type

格式: type key

返回值: type of key or none

返回key 的类型,如果key不存在了返回none

redis expires

在继续介绍更多的数据结构之前,我们需要讨论redis数据类型另外的一个特性,是所有数据结构的具备的,它叫Redis expires . 最基本的功能是设置一个key的存活时间. 当时间超过设置时间,这个key就会自动销毁,事实上好像用户调用了del命令一样。

  • 既可以使用秒也可以使用毫秒来设置有效时间
  • 当redis 服务器停止时候,会将expires 的key 带时间参数持久化到硬盘上;

hash

hash 可以很方便的描绘一个对象,事实上,hash的里的元素字段同样可以嵌套hash,所以在你的应用程序里,你可以自定义hash的结构.

HMSET

同时对多个字段赋值;

格式: HMSET KEY field1 value1 filed2 value2 ..

返回值: 字符OK

> HMSET hash:1 name zhangsan sex boy phone 12345
OK
HSET

对hash 单个字段赋值,无论filed 是否存在;

格式: HSET key filed value

返回值: 1

> hset hash1 height 174
(integer) 1
HMGET

格式: HMGET key field1 field2 ..

返回值: array 或者nil

> hmget hash:1 name phone
1) "zhangsan"
2) "12345"
HGEALL

获取hash key中有字段内容

格式: HGETALL key

返回值: array 或者nil

> hgetall hash:1
1) "name"
2) "zhangsan"
3) "sex"
4) "boy"
5) "phone"
6) "12345"

list

以少许理论开始,来解释list数据类型,应该更好理解,list 经常会被技术人员以不正确的方式使用.
一般来说,list就是一个有序元素列表. 但是使用数组实现的list和与使用链表实现的List确有很到的不同.

redis的list内部是通过链表实现. 尽管你有百万数据在list里面, 将一个元素添加到list的头部或者是尾部花费的时间是一样的. 通过LPUSH命令,将一个元素添加到大小是10的list中,跟将一个元素插入到具有千万的list中花费的时间是相差无几的.

redis list的弊端:

通过索引index访问元素在数组实现的list中是很快的,但对于通过链表实现的List,需要从头依次查找.
redis list 是通过linked list实现,因为对于一个数据库系统来说,以非常快的方式将元素添加到一个非常大的list中是很重要的. 另外在添加完元素的同时,可以立即看到list的长度.

如果访问到list中间的元素很重要,这时候需要使用另外一种数据结构:sorted Sets

第一步

LPUSH

在list的头部添加指定的元素,当key 不存在时候,在执行命令之前,会先创建一个内容为空list ; 如果key的类型不是list ,将有错误报出,LPUSH 支持多个值.

格式: LPUSH key value1 value2 ..

返回值: SIZE OF LIST

> lpush ele:1 21 34 abc de3
(integer) 4
RPUSH

在list的尾部添加指定的元素,当key 不存在时候,在执行命令之前,会先创建一个内容为空list ; 如果key的类型不是list ,将有错误报出,RPUSH 支持多个值.

格式: RPUSH key value1 value2 ..

返回值: SIZE OF LIST

> lpush ele:1 21 34 abc de3
(integer) 4
lrange

读取list 中指定索引之间的元素集

格式:lrange key startIndex endIndex

返回值: startIndex 到 endIndex 之间的元素(包括startIndex元素和endIndex元素)

注意:
- 如果endIndex 超过了list的最大长度,不会报错,会将startIndex到末尾的元素全部返回.
- 如果startIndex 比endIndex 大,会返回空.
- index 支持负值,-1 代表最后一个,-2 代表倒数第二个,依次类推.

获取所有元素

> lrange ele:1 0 -1
1) "de3"
2) "abc"
3) "34"
4) "21"
5) "cc1"
6) "cc2"

获取前N个元素

> lrange ele:1 0 3
1) "de3"
2) "abc"
3) "34"
4) "21"

获取最后N个元素

> lrange ele:1 -3 -1
1) "21"
2) "cc1"
3) "cc2"
LPOP RPOP

在redis list中还有个很重要的操作命令,将数据取出, 即将数据读取出来,并且将它从list移除.
Pop 像push命令一样,既可以从头部取出一个元素:LPop 又可以从尾部取出一个元素RPOP

格式: LPOP key 或者RPOP key

返回值: 元素或者nil

Capped list

在很多时候,我们使用list 希望它能够存储最新的元素,像:社交网站的更新,日志等待..; redis 运行我们使用list 当做有界集合,通过LTRIM 命令 只记录最近N条元素,并且删除素有的过时的元素项.

LTRIM

ltrim 语法结构类似与lrange,但ltrim 是删除操作,lrange 是读操作;
ltrim 只保留startIndex 到endIndex 之间的元素,其他的全部删除.

格式: ltrim key startIndex endIndex

返回值: Ok

> lrange ele:1 0 -1
1) "a2"
2) "a3"
3) "a4"
4) "a3"
5) "a2"
6) "a1"
7) "de3"
8) "abc"
9) "34"
> ltrim ele:1 0 4
OK
> lrange ele:1 0 -1
1) "a2"
2) "a3"
3) "a4"
4) "a3"
5) "a2"
> ltrim ele:1 -2 -1
OK
> lrange ele:1 0 -1
1) "a3"
2) "a2"

阻塞list

list 具有一个特性可以让lists 称为队列,通常作为构建进间的通信的阻塞操作.

BLPOP

BLPOP 是一个阻塞list pop 操作. 它是LPOP的阻塞版本, 当list 的元素为空时,去pop元素时候就会阻塞, 直到获取到元素时候.

格式: BRPOP key1 key2 .. timeout(秒)

返回值: array 或nil

当 timeout 是0 时候,将一直阻塞
非零时,阻塞指定时间等待获取数据, 时间到是如果还没有数据,就返回null

自动创建与删除

当对一个list 进行添加元素时,如果指定key的list 不存在,redis就会自动创建,当从指定的list 获取元素后,list 为空,redis自动将list 删除.

set

Redis Sets 是无序的字符集合.

SADD

向集合中添加一个或者多个元素

格式: key member1 member2 ..

返回值: int 成功加入的元素数量.

> sadd s1 a b c
(integer) 3
> sadd s1 b c d e
(integer) 2

SREM

向集合中删除一个或者多个元素

格式: SREM key member1 member2

返回值: int 成功删除的元素个数

> srem s1 d e f
2

smembers

获取集合中所有元素

格式: smembers key

返回值: array

sismember

判断元素是否就在 集合中

格式: sismember key element

返回值: 1 或者 0

> sismember s1 a
(integer) 1

> sismember s1 d
(integer) 0

排序的set

sorted sets 是一种能够将set和hash结合的数据结构. sorted sets 由元素唯一,不可重复的字符元素组成,所以给人的感觉更新set. 然而,在setz中元素都并不是排序的, 当在sorted sets 中每一个元素都关联有一个float类型的指针值-score . 这就是为什么说sorted sets 有点像一个hash, 正是因为每个元素都对应一个值.

而且所有元素被取出都是按一定顺序的(它们不是在请求时候排序的, 排序是一种特别的数据结构). 元素的排序需要遵循下面的规则:

  • 如果A和B 是两个不同score的元素,如果A.score > B.score 那么 A > B
  • 如果A和B 具有相同的score元素, 如果字符A存储的字典顺序向量 优于 字符B. A和B字符串就不相等,因为sorted sets 只能具有元素唯一性.
zadd

格式: zadd key [NX | XX] [CH] [INCR] score member …

添加所有带有指定scores的member 到 sorted set 中, 支持同时指定多组score-member; 如果指定元素已经存在, score值就会被更新并且元素根据选项是否重插.

Option

-XX: 只更新已存在的元素, 不会插入操作.
-NX: 不会更新已经存在的元素, 总会做插入操作.
-CH: 存在就更新score,不存在就插入.

127.0.0.1:6379> zadd a1 12 abc1
(integer) 1
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> zadd a1 23 abc2
(integer) 1
127.0.0.1:6379> zadd a1 34 abc3
(integer) 1
127.0.0.1:6379> zrange a1 0 -1
1) "abc1"
2) "abc2"
3) "abc3"
zrange

获取顺序获取sets列表, 语法类似lrange

127.0.0.1:6379> zrange a1 0 -1
1) "abc2"
2) "abc1"
3) "abc3"
4) "abc5"
127.0.0.1:6379> zrange a1 -2 -1
1) "abc3"
2) "abc5"
发布了49 篇原创文章 · 获赞 13 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章