Skip to content

Commit d3c635c

Browse files
authored
Merge pull request #1 from Vonng/master
update
2 parents 944470e + c592e6c commit d3c635c

File tree

10 files changed

+53
-69
lines changed

10 files changed

+53
-69
lines changed

ch1.md

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,17 @@
1010

1111
[TOC]
1212

13-
现今很多应用程序都是**数据密集型(data-intensive)**的,而非**计算密集型(compute-intensive)**的。因此CPU很少成为这类应用的瓶颈,更大的问题通常来自数据量、数据复杂性、以及数据的变更速度。
13+
​现今很多应用程序都是 **数据密集型(data-intensive)** 的,而非 **计算密集型(compute-intensive)** 的。因此CPU很少成为这类应用的瓶颈,更大的问题通常来自数据量、数据复杂性、以及数据的变更速度。
1414

1515
数据密集型应用通常由标准组件构建而成,标准组件提供了很多通用的功能;例如,许多应用程序都需要:
1616

17-
***数据库(database)***
17+
​- 存储数据,以便自己或其他应用程序之后能再次找到 (***(数据库(database))***
18+
​- 记住开销昂贵操作的结果,加快读取速度(***缓存(cache)***
19+
​- 允许用户按关键字搜索数据,或以各种方式对数据进行过滤(***搜索索引(search indexes)***
20+
-​ 向其他进程发送消息,进行异步处理(***流处理(stream processing)***
21+
- 定期处理累积的大批量数据(***批处理(batch processing)***
1822

19-
​ 存储数据,以便自己或其他应用程序之后能再次找到
20-
21-
***缓存(cache)***
22-
23-
​ 记住开销昂贵操作的结果,加快读取速度
24-
25-
***搜索索引(search indexes)***
26-
27-
​ 允许用户按关键字搜索数据,或以各种方式对数据进行过滤
28-
29-
***流处理(stream processing)***
30-
31-
​ 向其他进程发送消息,进行异步处理
32-
33-
***批处理(batch processing)***
34-
35-
​ 定期处理累积的大批量数据
36-
37-
38-
39-
​ 如果这些功能听上去平淡无奇,那是因为这些**数据系统(data system)**是非常成功的抽象:我们一直不假思索地使用它们并习以为常。绝大多数工程师不会幻想从零开始编写存储引擎,因为在开发应用时,数据库已经是足够完美的工具了。
23+
​如果这些功能听上去平淡无奇,那是因为这些 **数据系统(data system)** 是非常成功的抽象:我们一直不假思索地使用它们并习以为常。绝大多数工程师不会幻想从零开始编写存储引擎,因为在开发应用时,数据库已经是足够完美的工具了。
4024

4125
​ 但现实没有这么简单。不同的应用有着不同的需求,因而数据库系统也是百花齐放,有着各式各样的特性。实现缓存有很多种手段,创建搜索索引也有好几种方法,诸如此类。因此在开发应用前,我们依然有必要先弄清楚最适合手头工作的工具和方法。而且当单个工具解决不了你的问题时,组合使用这些工具可能还是有些难度的。
4226

@@ -193,10 +177,10 @@
193177
1. 发布推文时,只需将新推文插入全局推文集合即可。当一个用户请求自己的主页时间线时,首先查找他关注的所有人,查询这些被关注用户发布的推文并按时间顺序合并。在如[图1-2](img/fig1-2.png)所示的关系型数据库中,可以编写这样的查询:
194178

195179
```sql
196-
SELECT tweets.*, users.*
197-
FROM tweets
198-
JOIN users ON tweets.sender_id = users.id
199-
JOIN follows ON follows.followee_id = users.id
180+
SELECT tweets.*, users.*
181+
FROM tweets
182+
JOIN users ON tweets.sender_id = users.id
183+
JOIN follows ON follows.followee_id = users.id
200184
WHERE follows.follower_id = current_user
201185
```
202186
![](img/fig1-2.png)
@@ -476,4 +460,4 @@
476460
477461
| 上一章 | 目录 | 下一章 |
478462
| ----------------------------------- | ------------------------------- | ------------------------------------ |
479-
| [第一部分:数据系统基础](part-i.md) | [设计数据密集型应用](README.md) | [第二章:数据模型与查询语言](ch2.md) |
463+
| [第一部分:数据系统基础](part-i.md) | [设计数据密集型应用](README.md) | [第二章:数据模型与查询语言](ch2.md) |

ch11.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ GROUP BY follows.follower_id
676676

677677
​ Storm的Trident基于类似的想法来处理状态【78】。依赖幂等性意味着隐含了一些假设:重启一个失败的任务必须以相同的顺序重放相同的消息(基于日志的消息代理能做这些事),处理必须是确定性的,没有其他节点能同时更新相同的值【98,99】。
678678

679-
当从一个处理节点故障转移到另一个节点时,可能需要进行**防护(fencing)**(参阅“[领导和锁](ch8.md#领导和锁)”),以防止被假死节点干扰。尽管有这么多注意事项,幂等操作是一种实现**恰好一次语义**的有效方式,仅需很小的额外开销。
679+
当从一个处理节点故障切换到另一个节点时,可能需要进行**防护(fencing)**(参阅“[领导和锁](ch8.md#领导和锁)”),以防止被假死节点干扰。尽管有这么多注意事项,幂等操作是一种实现**恰好一次语义**的有效方式,仅需很小的额外开销。
680680

681681
#### 失败后重建状态
682682

ch2.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,12 +264,12 @@ UPDATE users SET first_name = substring_index(name, ' ', 1); -- MySQL
264264

265265
大型表上运行`UPDATE`语句在任何数据库上都可能会很慢,因为每一行都需要重写。要是不可接受的话,应用程序可以将`first_name`设置为默认值`NULL`,并在读取时再填充,就像使用文档数据库一样。
266266

267-
读时模式更具优势,当由于某种原因(例如,数据是异构的)集合中的项目并不都具有相同的结构时。例如,因为
267+
当由于某种原因(例如,数据是异构的)集合中的项目并不都具有相同的结构时,读时模式更具优势。例如,如果
268268

269269
* 存在许多不同类型的对象,将每种类型的对象放在自己的表中是不现实的。
270270
* 数据的结构由外部系统决定。你无法控制外部系统且它随时可能变化。
271271

272-
在这样的情况下,模式的坏处远大于它的帮助,无模式文档可能是一个更加自然的数据模型。但是,要是所有记录都具有相同的结构,那么模式是记录并强制这种结构的有效机制。第四章将更详细地讨论模式和模式演化。
272+
在上述情况下,模式的坏处远大于它的帮助,无模式文档可能是一个更加自然的数据模型。但是,要是所有记录都具有相同的结构,那么模式是记录并强制这种结构的有效机制。第四章将更详细地讨论模式和模式演化。
273273

274274
#### 查询的数据局部性
275275

@@ -591,7 +591,7 @@ CREATE INDEX edges_heads ON edges (head_vertex);
591591

592592
### Cypher查询语言
593593

594-
Cypher是属性图的声明式查询语言,为Neo4j图形数据库而发明【37】。(它是以电影“黑客帝国”中的一个角色开命名的,而与密码术中的密码无关【38】。)
594+
Cypher是属性图的声明式查询语言,为Neo4j图形数据库而发明【37】。(它是以电影“黑客帝国”中的一个角色来命名的,而与密码术中的密码无关【38】。)
595595

596596
[例2-3]()显示了将[图2-5](img/fig2-5.png)的左边部分插入图形数据库的Cypher查询。可以类似地添加图的其余部分,为了便于阅读而省略。每个顶点都有一个像`USA``Idaho`这样的符号名称,查询的其他部分可以使用这些名称在顶点之间创建边,使用箭头符号:`(Idaho) - [:WITHIN] ->(USA)`创建一条标记为`WITHIN`的边,`Idaho`为尾节点,`USA`为头节点。
597597

ch3.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
[第2章](ch2.md)中,我们讨论了数据模型和查询语言,即程序员将数据录入数据库的格式,以及再次要回数据的机制。在本章中我们会从数据库的视角来讨论同样的问题:数据库如何存储我们提供的数据,以及如何在我们需要时重新找到数据。
1717

18-
作为程序员,为什么要关心数据库内部存储与检索的机理?你可能不会去从头开始实现自己的存储引擎,但是你**确实**需要从许多可用的存储引擎中选择一个合适的。而且为了调谐存储引擎以适配应用工作负载,你也需要大致了解存储引擎在底层究竟做什么。
18+
作为程序员,为什么要关心数据库内部存储与检索的机理?你可能不会去从头开始实现自己的存储引擎,但是你**确实**需要从许多可用的存储引擎中选择一个合适的。而且为了协调存储引擎以适配应用工作负载,你也需要大致了解存储引擎在底层究竟做什么。
1919

2020
特别需要注意,针对**事务**性负载和**分析性**负载优化的存储引擎之间存在巨大差异。稍后我们将在 “[事务处理还是分析?](#事务处理还是分析?)” 一节中探讨这一区别,并在 “[列存储](#列存储)”中讨论一系列针对分析优化存储引擎。
2121

0 commit comments

Comments
 (0)