名称 | 类型 | 数据存储选项 | 查询类型 | 附加功能 |
---|---|---|---|---|
redis | 使用内存存储(in-memory)的非关系型数据库 | 字符串、列表、集合、散列表、有序集合 | 每种数据类型都有自己的专属命令,另外还有批量操作(bulk operation)和不完全(partial)的事务支持 | 发布与订阅,主从复制(master/slave replication),持久化,脚本(存储过程,stored procedure) |
memcached | 使用内存存储的键值缓存 | 键值之间的映射 | 创建命令、读取命令、更新命令、删除命令以及其他几个命令 | 为提升性能而设的多线程服务器 |
MySQL | 关系型数据库 | 每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图(view);支持空间(spatial)和第三方扩展 | select、insert、update、delete、函数、存储过程 | 支持ACID性质(需要使用InnoDB),主从复制和自主复制(master/master replication) |
PostgreSQL | 非关系型数据库 | 每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图;支持可定制类型 | select、insert、update、delete、内置函数、自定义的存储过程 | 支持ACID性质,主从复制,由第三方支持的主复制(multi-master replication) |
MongoDB | 使用硬盘存储(on-disk)的非关系型数据库 | 每个数据库可以包含多个表,每个表可以包含多个无 schema(schema-less)的BSON文档 | 创建命令、读取命令、更新命令、删除命令、条件查询命令等 | 支持 map-reduce 操作,主从复制,分片,空间索引(spatial index) |
redis 支持 5 种数据结构类型分别为 string(字符串)、list(列表)、set(集合)、hash(散列)和 zset(有序集合)
结构类型 | 结构存储的值 | 结构的读写能力 |
---|---|---|
string | 可以是字符串、整数或者浮点数 | 对整个字符串或者字符串的其中一部分执行操作;对整数和浮点数执行自增(increment)或者自减(decrement)操作 |
list | 一个链表,链表上的每个节点都包含了一个字符串 | 从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值查找或者移除元素 |
set | 包含字符串的无序收集器(unordered collection),并且被包含的每个字符串都是独一无二、各不相同的 | 添加、获取、移除单个元素;检查一个元素是否存在于集合中;计算交集、并集、差集;从集合里面随机获取元素 |
hash | 包含键值对的无序散列表 | 添加、获取、移除单个元素键值对;获取所有键值对 |
zset(有序集合) | 字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定 | 添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素 |
在 redis 中的字符串和其他编程语言或者其他键值存储提供的字符串非常相似,如存储一个 key 为 name,value 为 John
而字符串拥有一些和其它键值存储的相似的命令,比如 get(获取值)、set(设置值)和 del(删除值)
我们来实践一下,还没下载安装 redis 的朋友们可以看下这篇文章 redis 下载安装
安装之后我们启动一下 redis
set key value
get key
del key
删除键值对,只需删除 key(键)就可以了,会返回一个整型结果
当获取 del 之后的 key(键)时,会返回一个 nil
redis 对链表(linked-list)结构的支持使得它在键值存储的世界中独树一帜。一个列表结构可以有序地存储多个字符串,和表示字符串时使用的方法一样
redis 中的列表可执行的操作和很多编程语言里面的列表操作非常相似,如下表所示
命令 | 作用 |
---|---|
RPUSH | 将给定值推入列表的右端 |
LRANGE | 获取列表在给定范围上的所有值 |
LINDEX | 获取列表在给定位置上的单个元素 |
LPOP | 从列表的左端弹出一个值,并返回被弹出的值 |
rpush [key] [value]
lrange [key] index index
使用 0 是因为范围的起始索引为 0,-1 为范围的结束索引,可以取出列表包含的所有元素
lindex key index
lpop key
从列表里面弹出一个元素
当我们再次获取元素时,被弹出的元素将不再存在于列表中
即使 redis 的列表只支持以上提到的几个命令,但是已经可以用来解决很多问题了,但 redis 也并没有就此止步,除了以上的命令之外, redis 列表还拥有从列表里面移除元素的命令、将元素插入列表中间的命令、将列表修剪至指定长度(相当于从列表的其中一端或者两端移除元素)的命令,以及其它的一些命令
redis 的集合和列表都可以存储多个字符串,它们之间的不同在于列表可以存储多个相同的字符串,而集合则通过使用散列表来保证自己存储的每个字符串都是各不相同的(这些散列表只有键,但没有与键相关联的值)
因为 redis 的集合使用的是无序(unordered)方式存储元素,所以用户不能像使用列表那样将元素推入集合的某一端,或者从集合的某一端弹出元素。不过用户可以使用 SADD 命令将元素添加到集合中,或者使用 SREM 命令从集合里面移除元素。另外还可以通过 SISMEMBER 命令快速地检查一个元素是否已经存在于集合中,或者使用 SMEMBERS 命令获取集合包含的所有元素(如果集合包含的元素非常多,那么 SMEMBERS 命令的执行速度可能会很慢,所以需要谨慎地使用这个命令)
sadd key member [member...]
在尝试将一个元素添加到集合的时候,命令返回 1 表示这个元素成功地添加到了集合里面
而返回 0 则表示这个元素已经存在于这个集合中,如:
smembers key
获取集合包含的所有元素将得到一个由元素组成的序列,Python 客户端会将这个序列转换成 Python 集合
sismember key value
srem key member [member...]
redis 的散列可以存储多个键值对之间的映射。和字符串一样,散列存储的值即可以是字符串也可以是数字值,并且用户同样可以对散列值的数字值执行自增操作或者自减操作
散列在很多方面就像是一个微型的 redis,不少字符串命令都有相应的散列版本,关于散列的命令如下表所示:
命令 | 作用 |
---|---|
HSET | 在散列里面关联给定的键值对 |
HGET | 获取指定的散列键的值 |
HGETALL | 获取散列包含的所有键值对 |
HDEL | 如果给定的键存在于散列里面,那么移除这个键 |
hset key value
在使用 hset 添加键值到散列的时候,命令会返回一个值来表示给定的键是否已经存在于散列中
hgetall key
hdel key
或者 hdel key value
在删除键值对的时候,命令会返回一个值来表示给定的键在移除之前是否存在于散列里面
hget key
有序集合和散列一样,都是用键值对存储。有序集合的键被称为成员(member),每个成员都是各不相同的。而有序集合的值则被分为值(score),分值必须为浮点数。有序集合是 redis 里面唯一一个不仅可以根据成员变量访问元素(这点和散列一样),而且可以根据分值以及分值的排列顺序来访问元素的结构
关于 zset 的命令如下表所示:
命令 | 作用 |
---|---|
ZADD | 将一个带有给定分值的成员添加到有序集合里面 |
ZRANGE | 根据元素在有序排列中所处的位置,从有序集合里面获取多个元素 |
ZRANGEBYSCORE | 获取有序集合在给定分值范围内的所有元素 |
ZREM | 如果给定成员存在于有序集合,那么移除这个成员 |
zadd key [NX|XX] [CH] [INCR] score member [score member ...]
在尝试往有序集合添加元素的时候,命令会返回新的添加元素的数量
zrange key start stop [WITHSCORES]
获取有序集合中包含的所有元素,这个 WITHSCORES 如果要写的话得是小写,不然会报错
zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
zrem key member [member ...]