Skip to content

Commit

Permalink
Merge pull request #1 from Vonng/master
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
Gilbert1024 authored Feb 26, 2019
2 parents 2f2c629 + c592e6c commit 8e3228b
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 70 deletions.
40 changes: 12 additions & 28 deletions ch1.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,17 @@

[TOC]

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

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

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

​ 存储数据,以便自己或其他应用程序之后能再次找到

***缓存(cache)***

​ 记住开销昂贵操作的结果,加快读取速度

***搜索索引(search indexes)***

​ 允许用户按关键字搜索数据,或以各种方式对数据进行过滤

***流处理(stream processing)***

​ 向其他进程发送消息,进行异步处理

***批处理(batch processing)***

​ 定期处理累积的大批量数据


​ 如果这些功能听上去平淡无奇,那是因为这些**数据系统(data system)**是非常成功的抽象:我们一直不假思索地使用它们并习以为常。绝大多数工程师不会幻想从零开始编写存储引擎,因为在开发应用时,数据库已经是足够完美的工具了。
​如果这些功能听上去平淡无奇,那是因为这些 **数据系统(data system)** 是非常成功的抽象:我们一直不假思索地使用它们并习以为常。绝大多数工程师不会幻想从零开始编写存储引擎,因为在开发应用时,数据库已经是足够完美的工具了。

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

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

```sql
SELECT tweets.*, users.*
FROM tweets
JOIN users ON tweets.sender_id = users.id
JOIN follows ON follows.followee_id = users.id
SELECT tweets.*, users.*
FROM tweets
JOIN users ON tweets.sender_id = users.id
JOIN follows ON follows.followee_id = users.id
WHERE follows.follower_id = current_user
```
![](img/fig1-2.png)
Expand Down Expand Up @@ -476,4 +460,4 @@
| 上一章 | 目录 | 下一章 |
| ----------------------------------- | ------------------------------- | ------------------------------------ |
| [第一部分:数据系统基础](part-i.md) | [设计数据密集型应用](README.md) | [第二章:数据模型与查询语言](ch2.md) |
| [第一部分:数据系统基础](part-i.md) | [设计数据密集型应用](README.md) | [第二章:数据模型与查询语言](ch2.md) |
2 changes: 1 addition & 1 deletion ch11.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ GROUP BY follows.follower_id

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

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

#### 失败后重建状态

Expand Down
6 changes: 3 additions & 3 deletions ch2.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,12 @@ UPDATE users SET first_name = substring_index(name, ' ', 1); -- MySQL

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

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

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

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

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

Expand Down Expand Up @@ -591,7 +591,7 @@ CREATE INDEX edges_heads ON edges (head_vertex);

### Cypher查询语言

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

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

Expand Down
2 changes: 1 addition & 1 deletion ch3.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

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

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

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

Expand Down
2 changes: 1 addition & 1 deletion ch4.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,4 +638,4 @@ Actor模型是单个进程中并发的编程模型。逻辑被封装在角色中

| 上一章 | 目录 | 下一章 |
| ---------------------------- | ------------------------------- | --------------------------------- |
| [第三章:存储与检索](ch3.md) | [设计数据密集型应用](README.md) | [第二部分:分布式数据](part-iimd) |
| [第三章:存储与检索](ch3.md) | [设计数据密集型应用](README.md) | [第二部分:分布式数据](part-ii.md) |
Loading

0 comments on commit 8e3228b

Please sign in to comment.