分布式数据库NoSQL(十)——初识Redis
目录
Redis下载
第1关:6-1-1Redis中的数据结构
Redis与其他数据库的对比
Redis的特性
快速安装 Redis 与 Python(可跳过)
Redis数据结构简介
启动方式
Redis中的字符串
Redis中的列表
Redis中的集合
Redis中的哈希
Redis中的有序集合
编程要求
第2关:6-1-2 使用 Python 与 Redis 交互
第3关:6-1-3 使用Python+Redis实现文章投票网站后端功能
实现投票功能
创建文章数据
对文章进行排序
编程要求
Redis下载
链接:https://pan.baidu.com/s/1WGFRMALrVCS5eDreaOxVfw
提取码:1234解压文件安装,一路next,记得改路径。
或者从 https://redis.io/download 下载最新的稳定版本 Redis 源码
第1关:6-1-1Redis中的数据结构
Redis是一个速度非常快的非关系型数据库(non-relational database
),它可以存储键(key
)和五种不同类型的值(value
)之间的映射(mapping
),可基于内存存储亦可持久化到硬盘的日志型,Key-Value
数据库。
Redis与其他数据库的对比
如果你使用过关系型数据库,例如:Mysql
,那么你肯定写过关联两张表数据的查询语句。而 Redis
属于NoSQL
,它不使用表,也不会预定义数据模式或强制用户对 Redis
的各种数据进行关联。
NoSQL
(Not Only SQL
),意指“不仅仅是SQL
”,其泛指非关系型数据库,主要分为四类:
键值(
Key-Value
)存储数据库;列存储数据库;
文档型数据库;
图形(
Graph
)数据库;
Redis
也经常与高性能键值缓存服务器 memcached
做比较:两者均可用于存储键值映射,性能相差也甚少,但 Redis
能存储除普通字符串值之外的四种数据结构,而 memcached
只能存储普通的字符串值。这些不同使得 Redis
能够解决更为广泛的问题,而且既能作为主数据库使用,也可以作为辅助数据库使用。
我们通过一张表来对比常用的数据库与缓存服务器:
名称 | 类型 | 数据存储选项 | 查询类型 | 附加功能 |
---|---|---|---|---|
Redis
|
基于内存的非关系型数据库 | 字符串、列表、集合、哈希、有序集合 | 针对数据类型有专属命令,另有批量操作和不完全的事务支持 | 发布与订阅、复制、持久化、脚本扩展 |
memcached
|
基于内存的键值缓存 | 键值映射 | 创建、读取、更新、删除等 | 多线程支持 |
MySQL
|
关系型数据库 | 数据表、视图等 | 查询、插入、更新、删除、内置函数、自定义存储过程等 |
支持 ACID 性质、复制等
|
MongoDB
|
基于硬盘的非关系型文档存储数据库 |
无 schema 的 BSON 文档
|
创建、读取、更新、删除、条件查询等 | 复制、分片、空间索引等 |
Redis的特性
由于Redis是内存型数据库,在使用之前就要考虑当服务器被关闭时,服务器存储的数据是否能保留。Redis 拥有两种不同形式的持久化方法,都可以用紧凑的格式将数据写入硬盘:
RDB
持久化
- 在指定的时间间隔内生成数据集的时间点快照
AOF
持久化
- 记录服务器执行的所有写操作命令
- 新命令会被追加到文件的末尾
- 在服务器启动时,通过重新执行这些命令还原数据集
除此之外,为了扩展Redis的读性能,并为Redis提供故障转移支持,Redis实现了主从复制特性:
- 执行复制的从服务器连接主服务器
- 接收主服务器发送的初始副本
- 接收主服务器执行的所有写命令
- 在从服务器上执行所有写命令,实时更新数据库
- 读命令可以向任意一个从服务器发送
快速安装 Redis 与 Python(可跳过)
为了避免安装到旧版 Redis
的问题,我们直接使用源码编译安装 Redis
,首先你需要获取并安装 make
等一系列构建工具:
$ sudo apt-get update
$ sudo apt-get install make gcc python-dev
构建工具安装完毕后,你需要执行以下操作:
从 https://redis.io/download 下载最新的稳定版本 Redis 源码
//也可以根据开头百度网盘的链接下载
解压源码,编译、安装并启动 Redis
下载并安装 Python 语言的 Redis 客户端库
其中,安装 Redis
的过程如下:
~:$ wget -q http://download.redis.io/releases/redis-5.0.0.tar.gz
~:$ tar -xzf redis-5.0.0.tar.gz
~:$ cd redis-5.0.0
# 注意观察编译消息,最后不应该产生任何错误(`Error`)
~/redis-5.0.0:$ make
# 注意观察安装消息,最后不应该产生任何错误(`Error`)
~/redis-5.0.0:$ sudo make install
# 启动 Redis 服务器,注意通过日志确认 Redis 顺利启动
~/redis-5.0.0:$ redis-server redis.conf
除了上述的启动 Redis 服务器方式,你还可以通过 Redis 默认的配置在后台启动它(常用启动方式):
$ redis-server &
因为近几年发布的 Ubuntu
和 Debian
都预装了 Python 2.6
或 Python 2.7
,所以你不再需要花时间去安装 Python
。你可以通过一个名为 setuptools
的辅助包更方便的下载和安装 Redis
客户端:
~:$ sudo python -m easy_install redis hiredis
这里的 redis
包为 Python
提供了连接 Redis
的接口,hiredis
包则是可选的,它是一个使用 C
语言编写的高性能 Redis
客户端。
Redis数据结构简介
Redis
的五种数据结构分别是:
- 字符串(
STRING
)- 列表(
LIST
)- 集合(
SET
)- 哈希(
HASH
)- 有序集合(
ZSET
)
ZSET
可以说是 Redis
特有的数据结构,我们会在之后的实训中详细介绍它,在本实训中,我们只简要介绍他们的功能和小部分命令。他们的存储的值如下:
结构类型 | 存储的值 |
---|---|
STRING
|
字符串、整数或浮点数 |
LIST
|
一个链表,上面的每个节点都是一个字符串 |
SET
|
包含若干个字符串的无序集合,且集合中的元素都是唯一的 |
HASH
|
包含键值对的无序散列表 |
ZSET
|
成员中的字符串与分值的有序映射,其排序由分值决定 |
启动方式
在安装完 Redis
并启动了 redis-server
后,我们可以使用 redis-cli
控制台与 Redis
进行交互,其启动方式是在终端中输入:
$ redis-cli
其会默认连接本机 6379
端口启动的 Redis
服务器,接下俩你可以使用它来体验 Redis
各种数据结构和其命令的使用。
Redis中的字符串
STRING拥有一些和其他键值存储相似的命令,比如 GET
(获取值),SET
(设置值),DEL
(删除值)等,例如:
$ redis-cli
redis-cli 127.0.0.1:6379> set hello redis
OK
redis-cli 127.0.0.1:6379> get hello
"redis"
redis-cli 127.0.0.1:6379> del hello
(integer) 1
redis-cli 127.0.0.1:6379> get hello
(nil)
其中:
SET
命令的第一个参数是键(Key
),第二个参数是值(Value
)- 尝试获取不存在的键时会得到一个
nil
Redis中的列表
就像前面所说的,Redis中的列表是一个“链表”,这和大多数编程语言相似。所以他们的操作也十分相似:
LPUSH
命令可用于将元素推入列表的左侧RPUSH
命令可将元素推入列表的右侧LPOP
和RPOP
就分别从列表的左侧和右侧弹出元素LINDEX
可以获取指定位置上的元素LRANGE
可以获取指定范围的全部元素
我们通过 redis-cli
来亲自体验:
redis 127.0.0.1:6379> rpush testlist item
(integer) 1
redis 127.0.0.1:6379> rpush testlist item2
(integer) 2
redis 127.0.0.1:6379> rpush testlist item
(integer) 3
redis 127.0.0.1:6379> lrange testlist 0 -1
1) "item"
2) "item2"
3) "item"
redis 127.0.0.1:6379> lindex testlist 1
"item2"
redis 127.0.0.1:6379> lpop testlist
"item"
redis 127.0.0.1:6379> lrange testlist 0 -1
1) "item2"
2) "item"
注:在列表中,元素可以重复出现。
Redis中的集合
集合和列表的区别就在于:列表可以存储多个相同的字符串,而集合通过散列表来保证存储的字符串都是各不相同的(这些散列表只有键,而没有对应的值)。
- 由于集合是无序的,所以我们只能通过统一的
SADD
命令将元素添加到集合中SREM
命令将元素从集合中移除。SMEMBERS
命令获取到集合中的所有元素SISMEMBER
命令来判断一个元素是否已存在在集合中
redis 127.0.0.1:6379> sadd testset item
(integer) 1
redis 127.0.0.1:6379> sadd testset item2
(integer) 1
redis 127.0.0.1:6379> sadd testset item
(integer) 0
redis 127.0.0.1:6379> smembers testset
1) "item"
2) "item2"
redis 127.0.0.1:6379> sismember testset item3
(integer) 0
redis 127.0.0.1:6379> sismember testset item
(integer) 1
redis 127.0.0.1:6379> srem testset item2
(integer) 1
redis 127.0.0.1:6379> srem testset item2
(integer) 0
redis 127.0.0.1:6379> smembers testset
1) "item"
上面示例的集合中包含的元素少,所以执行 SMEMBERS
命令没有问题,一旦集合中包含的元素非常多时,SMEMBERS
命令的执行速度会很慢,所以要谨慎的使用这个命令。
Redis中的哈希
哈希可以存储多个键值对之间的映射。和字符串一样,哈希存储的值既可以是字符串又可以是数字值,并且可以对数字值进行自增/自减操作。
哈希就像是一个缩小版的 Redis
,有一系列命令对哈希进行插入、获取、删除:
redis 127.0.0.1:6379> hset testhash key1 value1
(integer) 1
redis 127.0.0.1:6379> hset testhash key2 value2
(integer) 1
redis 127.0.0.1:6379> hset testhash key1 newvalue
(integer) 0
redis 127.0.0.1:6379> hgetall testhash
1) "key1"
2) "newvalue"
3) "key2"
4) "value2"
redis 127.0.0.1:6379> hdel testhash key2
(integer) 1
redis 127.0.0.1:6379> hget testhash key1
"newvalue"
redis 127.0.0.1:6379> hgetall testhash
1) "key1"
2) "newvalue"
其中:
hset
用于插入元素
- 第一个参数为该哈希的键名,如果该哈希不存在,则创建一个
- 第二个参数为哈希中的域名
- 如果不存在,则创建该域,并与第三个参数的值进行映射
- 如果存在,则使用第三个参数更新该域的值
- 第三个参数为哈希中的值
hgetall
会获取到该哈希的所有域-值对hget
用于获取哈希中的某一个域hdel
用户删除哈希中的某一个域
Redis中的有序集合
有序集合和哈希一样,也是存储键值对。
只是有序集合的键被称为成员(member
),每个成员都是唯一的,有序集合的值则被称为分值(score
),这个分值必须为浮点数。所以有序集合既可以通过成员访问元素,也可以通过分值来排序元素。
ZADD
命令将带有指定分值的成员添加到有序集合中ZRANGE
命令根据分值有序排列后的集合获取到指定范围的元素ZRANGEBYSCORE
命令获取指定分值范围内的元素ZREM
命令从有序集合中删除指定成员
redis 127.0.0.1:6379> zadd testzset 100 member1
(integer) 1
redis 127.0.0.1:6379> zadd testzset 200 member0
(integer) 1
redis 127.0.0.1:6379> zrange testzset 0 -1 withscores
1) "member1"
2) "100"
3) "member0"
4) "200"
redis 127.0.0.1:6379> zrangebyscore testzset 0 150 withscores
1) "member1"
2) "100"
redis 127.0.0.1:6379> zrem testzset member1
(integer) 1
redis 127.0.0.1:6379> zrange testzset 0 -1 withscores
1) "member0"
2) "200"
编程要求
根据提示,打开命令行,启动 Redis
客户端并创建一些值:
- 使用默认配置后台启动 Redis 服务器
- 启动 Redis 客户端
redis-cli
- 设置字符串
- 键为
hello
- 值为
redis
- 键为
- 设置列表,键为
educoder-list
- 从列表左侧推入元素
hello
- 从列表右侧推入元素
educoder
- 从列表右侧推入元素
bye
- 从列表右侧弹出一个元素
- 从列表左侧推入元素
- 设置集合,键为
educoder-set
- 添加元素
c
- 添加元素
python
- 添加元素
redis
- 删除元素
c
- 添加元素
- 设置哈希,键为
educoder-hash
- 添加键:
python
,值为:language
- 添加键:
ruby
,值为:language
- 添加键:
redis
,值为:database
- 删除键
ruby
- 添加键:
- 设置有序列表,键为
educoder-zset
- 添加成员
jack
,分值为200
- 添加成员
rose
,分值为400
- 添加成员
lee
,分值为100
- 添加成员
root@evassh-13781135:~# redis-cli
127.0.0.1:6379> set hello redis
OK
127.0.0.1:6379> lpush educoder-list hello
(integer) 1
(0.84s)
127.0.0.1:6379> rpush educoder-list educoder
(integer) 2
127.0.0.1:6379> rpush educoder-list bye
(integer) 3
127.0.0.1:6379> rpop educoder-list
"bye"
127.0.0.1:6379> sadd educoder-set c
(integer) 1
127.0.0.1:6379> sadd educoder-set python
(integer) 1
127.0.0.1:6379> sadd educoder-set redis
(integer) 1
127.0.0.1:6379> srem educoder-set c
(integer) 1
127.0.0.1:6379> hset educoder-hash python language
(integer) 1
127.0.0.1:6379> hset educoder-hash ruby language
(integer) 1
127.0.0.1:6379> hset educoder-hash redis database
(integer) 1
127.0.0.1:6379> hdel educoder-hash ruby
(integer) 1
127.0.0.1:6379> zadd educoder-zset 200 jack
(integer) 1
127.0.0.1:6379> zadd educoder-zset 400 rose
(integer) 1
127.0.0.1:6379> zadd educoder-zset 100 lee
(integer) 1
第2关:6-1-2 使用 Python 与 Redis 交互
如果你在上一关中已经使用 easy_install
包安装了 redis
包,那么你现在连接 Redis
就很简单了,可以使用以下两种方法:
方法1
:
# 导入 redis 模块
import redis# 创建 redis 客户端
conn = redis.Redis()...
# 使用完资源之后删除客户端 conn
del conn
方法2
:
# 导入 redis 模块
import redis# 创建连接池
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, decode_responses=True)# 创建客户端并连接到 Redis
r = redis.Redis(connection_pool=pool)
两种方法的对比如下:
- 方法
1
:需要在使用完该客户端后手动删除客户端,以避免创建多个连接 - 方法
2
:- 使用了连接池总揽多个客户端与服务端的连接
- 不需要手动删除客户端
- 同时有效的减少多个客户端连接的损耗
所以我们在实际开发中使用第二种方法较多。
在创建了客户端之后,你就可以使用 coon
或 r
这个客户端来进行 Redis
操作了。
通过客户端对 Redis 的数据进行操作
通过客户端对 Redis
的数据进行操作和第一关直接在 Redis
中的操作命令基本相同。只是在客户端中操作如下,要在命令前加上客户端的名字和.
(假设使用方法2
创建客户端r
):
# 使用 SET 命令设置一个字符串键
r.set("test", "hello")
# 显示字符串键 test 的值
print(r.get("test"))
编程要求
根据提示,在右侧Begin-End
区域补充代码,实现使用 Python
编写程序与 Redis
交互:
- 使用方法
2
创建客户端r1
连接到Redis
- 设置下表中的两个字符串键:
键 | 值 |
---|---|
test1
|
hello
|
test2
|
Redis
|
#!/usr/bin/env python
#-*- coding:utf-8 -*-def write_redis():#********* Begin *********#import redispool = redis.ConnectionPool(host='127.0.0.1',port=6379,decode_responses=True)r = redis.Redis(connection_pool=pool)r.set("test1","hello")r.set("test2","Redis")#********* End *********#
第3关:6-1-3 使用Python+Redis实现文章投票网站后端功能
本关任务:编写一个简化版文章投票网站的后端处理逻辑。
相关知识
第一关中,我们对 Redis
提供的五种数据结构有了基本的了解,这一关我们学习如何使用这些数据结构来解决实际问题。
大多数网站都提供了对新闻、文章或者问答进行投票的功能,并根据文章的发布时间/投票数量进行排序。本关卡中,我们将使用 Redis
构建简单的文字投票及排序功能。
为了完成本关任务,你需要掌握:1
.实现投票功能,2
.创建文章数据,3
.对文章进行排序。
实现投票功能
实现投票功能,要注重文章的时效性与投票的公平性,所以需要给投票功能加上一些约束条件:
- 文章发布满一个星期后,不再允许用户对该文章投票
- 一个用户对一篇文章只能投一次票
所以我们需要使用:
- 一个有序集合
time
,存储文章的发布时间 - 一个集合
voted:*
,存储已投票用户名单- 其中
*
是被投票文章的ID
- 其中
一个有序集合 score
,存储文章的得票数
ONE_WEEK_IN_SECONDS = 7 * 24 * 60 * 60def article_vote(r, user_id, article_id):
# 使用 time.time() 获取当前时间
# 减去一周的秒数,从而获取一周前的Unix时间
cutoff = time.time() - ONE_WEEK_IN_SECONDS
if r.zscore('time', article_id) < cutoff:
returnif r.sadd('voted:' + article_id, user_id):
r.zincrby('score', article_id, 1)
当用户尝试投票时,使用 ZSCORE
命令读取 time
有序集合,得到这篇文章的发布时间,再判断文章的发布时间是否超过一周。ZSCORE
命令的语法如下:
r.zscore(key, member)
key
:是有序集合的键名member
:是有序集合中的某个成员
若未超过,则使用 SADD
命令尝试将用户追加到这篇文章的已投票用户名单中,如果添加成功,则说明该用户未投过票。SADD
命令的语法是:
r.sadd(key, member)
key
:是集合的键名member
:是要添加进集合的元素
由于集合中的元素是唯一的,所以sadd
函数会根据member
是否存在在集合中做出不同返回:
- 若该元素不存在在集合中,返回
True
- 若该元素已存在在集合中,返回
False
所以返回为 True
时使用 ZINCRBY
命令来为文章的投票数加 1
。zincrby
函数语法如下:
r.zincrby(key, member, increment)
key
:是有序集合的键名member
:是有序集合中要增加分值的成员increment
:是要增加的分值
创建文章数据
现在系统中还缺少文章数据,所以我们要提供一个创建文章的函数,并把文章数据存储到 Redis
中。创建文章的步骤如下:
- 创建新的文章
ID
- 将文章作者加入到这篇文章的已投票用户名单中
- 存储文章详细信息到
Redis
中
将文章的发布时间和初始投票数加入到 time
和 score
两个有序集合中
def post_article(r, user, title, link):
# 创建新的文章ID,使用一个整数计数器对 article 键执行自增
# 如果该键不存在,article 的值会先被初始化为 0
# 然后再执行自增命令
article_id = str(r.incr('article'))voted = 'voted:' + article_id
r.sadd(voted, user)
r.expire(voted, ONE_WEEK_IN_SECONDS)now = time.time()
article = 'article:' + article_id
r.hmset(article, {
'title': title,
'link': link,
'poster': user,
})r.zadd('score', article_id, 1)
r.zadd('time', article_id, now)return article_id
将文章作者加入已投票用户名单中和之前一样,这里不再赘述,但在这里我们需要为这个已投票用户名单设置一个过期时间,让它在一周后(到期后)自动删除,减少 Redis
的内存消耗。为键设置过期时间的命令是:
r.expire(key, seconds)
key
:要设置过期时间的键名seconds
:过期时间的长度(单位:秒)
这里我们要设置的时间是一周,所以我们可以使用上面定义好的全局变量 ONE_WEEK_IN_SECONDS
。
接下来要存储文章详细信息了,前面介绍过 hset
可以执行单个字段(域)的设置,这里我们使用 hmset
一次性设置多个字段(域),其语法如下:
r.hmset(key, {field: value, [field: value ...]})
我们可以使用 Python
的散列来一次性存储多个字段(域)到 Redis
,只需要将整个散列当作 key
对应的值通过 hmset
函数设置进去就行。
最后,将初始投票数和创建时间设置到 score
和 time
中都可以通过 ZADD
命令来实现:
r.zadd(key, member, score)
key
:有序集合的键名member
:要加入有序集合的成员score
:该成员的分值
这里需要注意的是,因为该篇文章的作者已经被加入到该文章已投票用户名单中,为了保持数据一致性,我们需要将文章的初始投票数设为 1
。
对文章进行排序
实现了文章投票和创建文章功能,接下来我们就需要将评分最高的文章和最新发布的文章从 Redis
中取出了。
首先我们要根据排序方式的不同:
- 按评分排序,则从
score
有序集合中取出一定量的文章ID
(score
有序集合存放文章ID
和对应的投票数) - 按时间排序,则从
time
有序集合中取出一定量的文章ID
(time
有序集合存放文章ID
和对应的发布时间)
- 按评分排序,则从
构成一个有序文章信息列表,每个元素都:
使用 HGETALL
命令,取出每篇文章的全部信息
def get_articles(r, start, end, order='score'):
ids = r.zrevrange(order, start, end)
articles = []
for id in ids:
article_data = r.hgetall(id)
article_data['id'] = id
articles.append(article_data)return articles
这里因为需要对有序集合进行排序,所以我们在取出文章 ID
时需要使用到 ZREVRANGE
命令,以分值从大到小的排序方式取出文章 ID
。ZREVRANGE
命令的语法是:
r.zrevrange(key, start, stop)
key
:有序集合的键名start
:开始的数组下标stop
:结束的数组下标
得到多个文章 ID
后,我们还需要根据每一个文章 ID
获取文章的全部信息,这时就需要使用到 HGETALL
命令,它的语法如下:
r.hgetall(key)
key
:哈希的键名
我们取出文章的全部信息后,还为文章信息添加了一个字段 id
。这是因为文章 ID
在 Redis
中是作为键名存储的,不在值当中,所以我们需要附加这个字段到文章信息中。
实现这些方法后,我们大体实现了一个文章投票的后端处理逻辑,能够为文章投票并能根据投票结果改变文章的排序情况。
编程要求
根据提示,在右侧Begin-End
区域补充代码,完成简化版文章投票网站的后端处理逻辑:
在
article_vote()
函数中:- 该方法作用是:对文章投票
- 参数说明:
r
:Redis 客户端
user_id
:投票用户article_id
:被投票文章- 已提供一周前
Unix
时间戳,存放在变量cutoff
- 当满足“该文章发布不超过一周”条件时,为文章投一票:
- 已提供一周前
该用户没有为该文章投过票
在
post_article()
函数中:- 该方法作用是:创建文章
- 参数说明:
r
:Redis 客户端
user
:发布用户title
:文章标题link
:文章链接- 已提供:
article_id
,新文章ID
- 已提供:
voted
,新文章已投票用户名单存储键名article
,新文章详细信息存储键名now
,文章创建时间- 按照
ID
递增的顺序依次创建文章 - 保证发布文章的用户不能给自己的文章投票
- 文章在发布一周后删除已投票用户名单
- 存储文章详细信息到
Redis
中,包括字段: 文章标题、文章链接、发布用户 - 存储文章的发布时间和初始投票数:初始投票数为
1
- 按照
在
get_articles()
函数中:- 该方法作用是:对文章进行排序
- 参数说明:
r
:Redis 客户端start
:从排序为start
的文章开始获取
end
:到排序为end
的文章结束获取order
:排序方式,分为两种:time
:按时间排序score
:按投票数排序
已提供文章信息空列表,
articles
实现按时间/投票数排序
将排序后的文章及其全部信息组成一个列表:
- 按照不同排序规则取出排序在参数提供的区间范围内的文章
- 及每篇文章的全部信息,包括文章
ID
#!/usr/bin/env python
#-*- coding:utf-8 -*-import timeONE_WEEK_IN_SECONDS = 7 * 24 * 60 * 60def article_vote(r, user_id, article_id):cutoff = time.time() - ONE_WEEK_IN_SECONDS# 请在下面完成要求的功能#********* Begin *********#if r.zscore('time',article_id) < cutoff:returnif r.sadd('voted:' + article_id,user_id):r.zincrby('score',article_id,1)#********* End *********#def post_article(r, user, title, link):article_id = str(r.incr('article'))voted = 'voted:' + article_idnow = time.time()article = 'article:' + article_id# 请在下面完成要求的功能#********* Begin *********#r.sadd(voted,user)r.expire(voted,ONE_WEEK_IN_SECONDS)r.hmset(article,{'title':title,'link':link,'poster':user})r.zadd('score',article_id,1)r.zadd('time',article_id,now)#********* End *********#return article_iddef get_articles(r, start, end, order='score'):articles = []# 请在下面完成要求的功能#********* Begin *********#ids = r.zrevrange(order,start,end)for id in ids:article_data = r.hgetall(id)article_data['id'] = idarticles.append(article_data)#********* End *********#return articles
分布式数据库NoSQL(十)——初识Redis相关推荐
- 【云计算与大数据技术】分布式数据库NoSQL中KV、列式、图、文档数据库的讲解(图文解释 超详细)
一.NoSQL数据库概述 NoSQL泛指非关系型数据库,相对于传统关系型数据库,NoSQL有着更复杂的分类,包括KV数据库,文档数据库,列式数据库以及图数据库等等,这些类型的数据库能够更好的适应复杂类 ...
- 基于MySQL的分布式数据库TDSQL十年锻造经验分享
下载网站:www.SyncNavigator.CN 客服QQ1793040 ---------------------------------------------------------- 关于 ...
- 分布式数据库NoSQL(二)——MongoDB 数据库基本操作
MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系 ...
- 专注分布式数据库技术研发,巨杉获福布斯认可
日前,福布斯中国公布「中国企业科技50强」榜单.本次评选活动由福布斯中国与红杉中国合作,首度发布"中国企业科技50强评选",通过估值.利润.增长率.人文及市场领导力等多个维度构建评 ...
- redis学习-分布式数据库CAP原理
传统的ACID分别是什么 A (Atomicity) 原子性 C (Consistency) 一致性 I (Isolation) 独立性 D (Durability) 持久性 关系型数据库遵循ACID ...
- 企业级nosql数据库应用与实战-redis
企业级nosql数据库应用与实战-redis 项目场景: 随着互联网2.0时代的发展,越来越多的公司更加注重用户体验和互动,这些公司的平台上会出现越来越多方便用户操作和选择的新功能,如优惠券发放.抢红 ...
- 蚂蚁金服隗华:十五年时间见证分布式数据库的崛起
北大计算所启蒙 "做中国人自己的技术" 如果用一句话来评价读书时的隗华(花名:风羿),那一定是"德智体美劳全面发展的好学生".本科在北航读的计算机专业,硕士则就 ...
- Redis数据库系列(四)、Redis事务、乐观锁和分布式锁
第四章.Redis事务.乐观锁和分布式锁 什么是事务机制? 4.1.关系型数据库中的事务机制遵循ACID规则 关系型数据库例如MySql.Oracle: 事务的英文是transaction,以现实中的 ...
- 腾讯十年老兵:区块链本质上是一个异地多活的分布式数据库
\ 区块链前哨导读:本文整理自 9 月 8 日"腾讯技术工程-区块链技术沙龙"上的演讲. 讲师介绍:潘安群,腾讯 TEG 计费平台部账户中心总监,专家工程师:中国计算机学会 CCF ...
最新文章
- 非对称加密算法之RSA介绍及OpenSSL中RSA常用函数使用举例
- Linux系统.xsesion日志文件,linux系统日志
- 源码编译spring
- Mysql Mariadb 创建新用户
- poj 1151(线段树求面积并)
- 局部变量和成员变量的初始值问题
- python读取lmdb文件_python将图片转成lmdb格式
- hdu 2119最小点集覆盖
- 错误:用脚本window.showModalDialog打开的页面,点击button时打开新窗口
- java实体null值显示_java反射实现前端接收实体对象,去除“null”字符串(示例代码)...
- oracle union all 特别慢_Oracle查询性能优化
- vim编辑器的快捷键使用
- 网站推广效率最高的20种办法
- 超硬核 Web 前端学霸笔记,学完就去找工作!
- keil教程——解压缩BCD码
- 云计算实训总结_云计算·实训报告书
- VM无法将网络更改为桥接状态:没有未桥接的主机网络适配器
- JavaWeb - 小米商城:用户注册
- 4.3、Android Studio突破64K方法限制
- arcgis for android(二)显示二维地图
热门文章
- 表不存在,但是可以查询、删除(没有返回结果,一直hang住)
- 表单重复提交(前端未做单击防重复点击策略)
- 【歪门邪道】Android页面上快速实现蒙层引导需求
- 计算机专业的学生买什么电脑,设计类学生买什么电脑
- 诚之和:各业务不断爆出裁员,字节跳动如何“过冬”?
- 相亲交友v6.7.6
- 记录一次上网正常但是【登录客户端应用网络异常问题】
- android菜单键 r9,Android OPPO R9 后台 无法启动 Activity 问题
- 查看在线人物 修改金币 元宝 等人物属性
- 海量大数据地图可视化