七个原则
- Redis 是一个操作数据结构的语言工具,它提供基于 TCP 的协议以操作丰富的数据结构。在 Redis 中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身及这些操作的时间空间复杂度。
- Redis 定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis 能够有如此高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构, Redis 会尝试其它的存储方面的选择,但是永远不会改变它是一个内存数据库的角色。
- Redis 使用基础的 API 操作基础的数据结构, Redis 的 API 与数据结构一样,都是一些最基础的元素,你几乎可以将任何信息交互使用此 API 格式表示。作者调侃说,如果有其它非人类的智能生物存在,他们也能理解 Redis 的 API。因为它是如此的基础。
- Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》接上后四十回一样。
- Redis 始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
- Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操作。它们各有所长,但是我们不会推出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。
- 我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让 Redis 不好玩的开发模式。
hashes 类型及操作
Redis hash 是一个 String 类型的 field 和 value 的映射表。它的添加、删除操作都是 O(1) (平均)。hash 特别适合用于存储对象。相较于将对象的每个字段存成单个 string 类型。将一个对象存储在 hash 类型中会占用更少的内存,并且可以更方便的存取整个对象。省内存的原因是新建一个 hash 对象时开始是用 zipmap(又称为 small hash)来存储的。这个 zipmap 其实并不是 hash table,但是 zipmap 相比正常的 hash 实现可以节省不少 hash 本身需要的一些元数据存储开销。尽管 zipmap 的添加,删除,查找都是 O(n),但是由于一般对象的 field 数量都不太多。所以使用 zipmap 也是很快的,也就是说添加、删除平均还是 O(1)。如果 field 或者 value的大小超出一定限制后, Redis 会在内部自动将 zipmap 替换成正常的 hash 实现. 这个限制可以在配置文件中指定。
hash-max-zipmap-entries 64 #配置字段最多 64 个。
hash-max-zipmap-value 512 #配置 value 最大为 512 字节。
常用命令及操作
hset
设置 hash field 为指定值,如果 key 不存在,则先创建。
127.0.0.1:6379> hset myhash name Jacob
(integer) 1
hsetnx
设置 hash field 为指定值,如果 key 不存在,则先创建。 如果 field 已经存在,返回 0, nx 是not exist 的意思。
127.0.0.1:6379> hsetnx myhash age 18
(integer) 1
127.0.0.1:6379> hsetnx myhash age 18
(integer) 0
第一次执行是成功的,但第二次执行相同的命令失败,原因是 field 已经存在了。
hmset
同时设置 hash 的多个 field。
127.0.0.1:6379> hmset myhash name2 Jacob2 name3 Jacob3
OK
hget
获取指定的 hash field。
127.0.0.1:6379> hget myhash name
"Jacob"
127.0.0.1:6379> hget myhash name2
"Jacob2"
127.0.0.1:6379> hget myhash name3
"Jacob3"
127.0.0.1:6379> hget myhash name4
(nil)
由于数据库没有 field3,所以取到的是一个空值 nil
hmget
获取全部指定的 hash filed。
127.0.0.1:6379> hmget myhash name name2 name3
1) "Jacob"
2) "Jacob2"
3) "Jacob3"
hincrby
指定的 hash filed 加上给定值。
127.0.0.1:6379> hget myhash age
"18"
127.0.0.1:6379> hincrby myhash age 6
(integer) 24
127.0.0.1:6379> hget myhash age
"24"
hexists
测试指定 field 是否存在。 1表示存在,0表示不存在。
127.0.0.1:6379> hexists myhash name3
(integer) 1
127.0.0.1:6379> hexists myhash name4
(integer) 0
hlen
返回指定 hash 的 field 数量。
127.0.0.1:6379> hlen myhash
(integer) 4
myhash 中有 4 个 field(name,name2,name3,age)。
hkeys
返回 hash 的所有 field。
127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "nane2"
4) "name3"
hdel
返回指定 hash 的 field 数量。
127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "nane2"
4) "name3"
127.0.0.1:6379> hdel myhash name3
(integer) 1
127.0.0.1:6379> hkeys myhash
1) "name"
2) "age"
3) "nane2"
hvals
返回 hash 的所有 value。
127.0.0.1:6379> hvals myhash
1) "Jacob"
2) "24"
3) "Jacob2"
hgetall
获取某个 hash 中全部的 filed 及 value。
127.0.0.1:6379> hgetall myhash
1) "name"
2) "Jacob"
3) "age"
4) "24"
5) "nane2"
6) "Jacob2"
可见,一下子将 myhash 中所有的 field 及对应的 value 都取出来了。