Skip to content

Commit

Permalink
fix punctuation marks
Browse files Browse the repository at this point in the history
  • Loading branch information
yingang committed Jan 6, 2022
1 parent 072814f commit bbc7bb8
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 50 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
>
> —— Vonng
现今,尤其是在互联网领域,大多数应用都属于数据密集型应用。本书从底层数据结构到顶层架构设计,将数据系统设计中的精髓娓娓道来。其中的宝贵经验无论是对架构师DBA、还是后端工程师、甚至产品经理都会有帮助。
现今,尤其是在互联网领域,大多数应用都属于数据密集型应用。本书从底层数据结构到顶层架构设计,将数据系统设计中的精髓娓娓道来。其中的宝贵经验无论是对架构师DBA、还是后端工程师、甚至产品经理都会有帮助。

这是一本理论结合实践的书,书中很多问题,译者在实际场景中都曾遇到过,读来让人击节扼腕。如果能早点读到这本书,该少走多少弯路啊!

Expand Down Expand Up @@ -138,9 +138,9 @@
0. 全文校订 by [@yingang](https://github.com/yingang)
1. [序言初翻修正](https://github.com/Vonng/ddia/commit/afb5edab55c62ed23474149f229677e3b42dfc2c) by [@seagullbird](https://github.com/Vonng/ddia/commits?author=seagullbird)
2. [第一章语法标点校正](https://github.com/Vonng/ddia/commit/973b12cd8f8fcdf4852f1eb1649ddd9d187e3644) by [@nevertiree](https://github.com/Vonng/ddia/commits?author=nevertiree)
3. [第六章部分校正](https://github.com/Vonng/ddia/commit/d4eb0852c0ec1e93c8aacc496c80b915bb1e6d48)[第十章的初翻](https://github.com/Vonng/ddia/commit/9de8dbd1bfe6fbb03b3bf6c1a1aa2291aed2490e) by @[MuAlex](https://github.com/Vonng/ddia/commits?author=MuAlex)
3. [第六章部分校正](https://github.com/Vonng/ddia/commit/d4eb0852c0ec1e93c8aacc496c80b915bb1e6d48)[第十章的初翻](https://github.com/Vonng/ddia/commit/9de8dbd1bfe6fbb03b3bf6c1a1aa2291aed2490e) by [@MuAlex](https://github.com/Vonng/ddia/commits?author=MuAlex)
4. [第一部分](part-i.md)前言,[ch2](ch2.md)校正 by [@jiajiadebug](https://github.com/Vonng/ddia/commits?author=jiajiadebug)
5. [词汇表](glossary.md)[后记](colophon.md)关于野猪的部分 by @[Chowss](https://github.com/Vonng/ddia/commits?author=Chowss)
5. [词汇表](glossary.md)[后记](colophon.md)关于野猪的部分 by [@Chowss](https://github.com/Vonng/ddia/commits?author=Chowss)
6. [繁體中文](https://github.com/Vonng/ddia/pulls)版本与转换脚本 by [@afunTW](https://github.com/afunTW)
7. 感谢所有作出贡献,提出意见的朋友们:

Expand Down
22 changes: 11 additions & 11 deletions ch2.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ CODASYL中的查询是通过利用遍历记录列和跟随访问路径表在数

#### 哪种数据模型更有助于简化应用代码?

如果应用程序中的数据具有类似文档的结构(即,一对多关系树,通常一次性加载整个树),那么使用文档模型可能是一个好主意。将类似文档的结构分解成多个表(如[图2-1](img/fig2-1.png)中的`positions``education``contact_info`)的关系技术可能导致繁琐的模式和不必要的复杂的应用程序代码。
如果应用程序中的数据具有类似文档的结构(即,一对多关系树,通常一次性加载整个树),那么使用文档模型可能是一个好主意。将类似文档的结构分解成多个表(如[图2-1](img/fig2-1.png)中的`positions``education``contact_info`)的关系技术可能导致繁琐的模式和不必要的复杂的应用程序代码。

文档模型有一定的局限性:例如,不能直接引用文档中的嵌套的项目,而是需要说“用户251的位置列表中的第二项”(很像层次模型中的访问路径)。但是,只要文件嵌套不太深,这通常不是问题。

Expand Down Expand Up @@ -286,7 +286,7 @@ UPDATE users SET first_name = substring_index(name, ' ', 1); -- MySQL

自2000年代中期以来,大多数关系数据库系统(MySQL除外)都已支持XML。这包括对XML文档进行本地修改的功能,以及在XML文档中进行索引和查询的功能。这允许应用程序使用那种与文档数据库应当使用的非常类似的数据模型。

从9.3版本开始的PostgreSQL 【8】,从5.7版本开始的MySQL以及从版本10.5开始的IBM DB2 [30]也对JSON文档提供了类似的支持级别。鉴于用在Web APIs的JSON流行趋势,其他关系数据库很可能会跟随他们的脚步并添加JSON支持。
从9.3版本开始的PostgreSQL 【8】,从5.7版本开始的MySQL以及从版本10.5开始的IBM DB2【30】也对JSON文档提供了类似的支持级别。鉴于用在Web APIs的JSON流行趋势,其他关系数据库很可能会跟随他们的脚步并添加JSON支持。

在文档数据库中,RethinkDB在其查询语言中支持类似关系的连接,一些MongoDB驱动程序可以自动解析数据库引用(有效地执行客户端连接,尽管这可能比在数据库中执行的连接慢,需要额外的网络往返,并且优化更少)。

Expand Down Expand Up @@ -541,18 +541,18 @@ db.observations.aggregate([

### 属性图

在属性图模型中,每个**顶点(vertex)** 包括:
在属性图模型中,每个顶点(vertex)包括:

* 唯一的标识符
* 一组 **出边(outgoing edges)**
* 一组 **入边(ingoing edges)**
* 一组出边(outgoing edges)
* 一组入边(ingoing edges)
* 一组属性(键值对)

每条 **(edge)** 包括:
每条边(edge)包括:

* 唯一标识符
* **边的起点/尾部顶点(tail vertex)**
* **边的终点/头部顶点(head vertex)**
* 边的起点(**尾部顶点**,即tail vertex)
* 边的终点(**头部顶点**,即head vertex)
* 描述两个顶点之间关系类型的标签
* 一组属性(键值对)

Expand Down Expand Up @@ -640,11 +640,11 @@ RETURN person.name

答案是肯定的,但有些困难。在关系数据库中,你通常会事先知道在查询中需要哪些连接。在图查询中,你可能需要在找到待查找的顶点之前,遍历可变数量的边。也就是说,连接的数量事先并不确定。

在我们的例子中,这发生在Cypher查询中的`() -[:WITHIN*0..]-> ()`规则中。一个人的`LIVES_IN`边可以指向任何类型的位置:街道、城市、地区、地区、国家等。城市可以在一个地区,在一个州内的一个地区,在一个国家内的一个州等等`LIVES_IN`边可以直接指向正在查找的位置,或者一个在位置层次结构中隔了数层的位置。
在我们的例子中,这发生在Cypher查询中的`() -[:WITHIN*0..]-> ()`规则中。一个人的`LIVES_IN`边可以指向任何类型的位置:街道、城市、地区、地区、国家等。一个城市可以在(WITHIN)一个地区内,一个地区可以在(WITHIN)在一个州内,一个州可以在(WITHIN)一个国家内,等等`LIVES_IN`边可以直接指向正在查找的位置,或者一个在位置层次结构中隔了数层的位置。

在Cypher中,用`WITHIN * 0`非常简洁地表述了上述事实:“沿着`WITHIN`边,零次或多次”。它很像正则表达式中的`*`运算符。
在Cypher中,用`WITHIN*0..`非常简洁地表述了上述事实:“沿着`WITHIN`边,零次或多次”。它很像正则表达式中的`*`运算符。

自SQL:1999,查询可变长度遍历路径的思想可以使用称为**递归公用表表达式**`WITH RECURSIVE`语法)的东西来表示。[例2-5]()显示了同样的查询 - 查找从美国移民到欧洲的人的姓名 - 在SQL使用这种技术(PostgreSQLIBM DB2Oracle和SQL Server均支持)来表述。但是,与Cypher相比,其语法非常笨拙。
自SQL:1999,查询可变长度遍历路径的思想可以使用称为**递归公用表表达式**`WITH RECURSIVE`语法)的东西来表示。[例2-5]()显示了同样的查询 - 查找从美国移民到欧洲的人的姓名 - 在SQL使用这种技术(PostgreSQLIBM DB2Oracle和SQL Server均支持)来表述。但是,与Cypher相比,其语法非常笨拙。

**例2-5 与示例2-4同样的查询,在SQL中使用递归公用表表达式表示**

Expand Down
14 changes: 7 additions & 7 deletions ch4.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

因此,除非临时使用,采用语言内置编码通常是一个坏主意。

### JSONXML和二进制变体
### JSONXML和二进制变体

当我们谈到可以被多种编程语言读写的标准编码时,JSON和XML是最显眼的角逐者。它们广为人知,广受支持,也“广受憎恶”。 XML经常收到批评:过于冗长与且过份复杂【9】。 JSON的流行则主要源于(通过成为JavaScript的一个子集)Web浏览器的内置支持,以及相对于XML的简单性。 CSV是另一种流行的与语言无关的格式,尽管其功能相对较弱。

Expand Down Expand Up @@ -148,7 +148,7 @@ Thrift和Protocol Buffers每一个都带有一个代码生成工具,它采用

**图4-2 使用Thrift二进制协议编码的记录**

[^iii]: 实际上,Thrift有三种二进制协议:BinaryProtocol、CompactProtocol和DenseProtocol,尽管DenseProtocol只支持C ++实现,所以不算作跨语言[18]。 除此之外,它还有两种不同的基于JSON的编码格式【19】。 真逗!
[^iii]: 实际上,Thrift有三种二进制协议:BinaryProtocol、CompactProtocol和DenseProtocol,尽管DenseProtocol只支持C ++实现,所以不算作跨语言【18】。 除此之外,它还有两种不同的基于JSON的编码格式【19】。 真逗!

[图4-1](Img/fig4-1.png)类似,每个字段都有一个类型注释(用于指示它是一个字符串,整数,列表等),还可以根据需要指定长度(字符串的长度,列表中的项目数) 。出现在数据中的字符串`(“Martin”, “daydreaming”, “hacking”)`也被编码为ASCII(或者说,UTF-8),与之前类似。

Expand Down Expand Up @@ -395,7 +395,7 @@ Web浏览器不是唯一的客户端类型。例如,在移动设备或桌面

[^vi]: 即使在每个阵营内也有很多争论。 例如,**HATEOAS(超媒体作为应用程序状态的引擎)** 就经常引发讨论【35】。

REST不是一个协议,而是一个基于HTTP原则的设计哲学【34,35】。它强调简单的数据格式,使用URL来标识资源,并使用HTTP功能进行缓存控制,身份验证和内容类型协商。与SOAP相比,REST已经越来越受欢迎,至少在跨组织服务集成的背景下【36】,并经常与微服务相关[31]。根据REST原则设计的API称为RESTful。
REST不是一个协议,而是一个基于HTTP原则的设计哲学【34,35】。它强调简单的数据格式,使用URL来标识资源,并使用HTTP功能进行缓存控制,身份验证和内容类型协商。与SOAP相比,REST已经越来越受欢迎,至少在跨组织服务集成的背景下【36】,并经常与微服务相关【31】。根据REST原则设计的API称为RESTful。

相比之下,SOAP是用于制作网络API请求的基于XML的协议[^vii]。虽然它最常用于HTTP,但其目的是独立于HTTP,并避免使用大多数HTTP功能。相反,它带有庞大而复杂的多种相关标准(Web服务框架,称为`WS-*`),它们增加了各种功能【37】。

Expand All @@ -421,7 +421,7 @@ Web服务仅仅是通过网络进行API请求的一系列技术的最新版本
* 每次调用本地功能时,通常需要大致相同的时间来执行。网络请求比函数调用要慢得多,而且其延迟也是非常可变的:好的时候它可能会在不到一毫秒的时间内完成,但是当网络拥塞或者远程服务超载时,可能需要几秒钟的时间完成一样的东西。
* 调用本地函数时,可以高效地将引用(指针)传递给本地内存中的对象。当你发出一个网络请求时,所有这些参数都需要被编码成可以通过网络发送的一系列字节。如果参数是像数字或字符串这样的基本类型倒是没关系,但是对于较大的对象很快就会变成问题。

- 客户端和服务可以用不同的编程语言实现,所以RPC框架必须将数据类型从一种语言翻译成另一种语言。这可能会捅出大篓子,因为不是所有的语言都具有相同的类型 —— 例如回想一下JavaScript的数字大于$2^{53}$的问题(请参阅“[JSONXML和二进制变体](#JSONXML和二进制变体)”)。用单一语言编写的单个进程中不存在此问题。
- 客户端和服务可以用不同的编程语言实现,所以RPC框架必须将数据类型从一种语言翻译成另一种语言。这可能会捅出大篓子,因为不是所有的语言都具有相同的类型 —— 例如回想一下JavaScript的数字大于$2^{53}$的问题(请参阅“[JSONXML和二进制变体](#JSONXML和二进制变体)”)。用单一语言编写的单个进程中不存在此问题。

所有这些因素意味着尝试使远程服务看起来像编程语言中的本地对象一样毫无意义,因为这是一个根本不同的事情。 REST的部分吸引力在于,它并不试图隐藏它是一个网络协议的事实(尽管这似乎并没有阻止人们在REST之上构建RPC库)。

Expand Down Expand Up @@ -469,7 +469,7 @@ RPC方案的前后向兼容性属性从它使用的编码方式中继承:

#### 消息代理

过去,**消息代理(Message Broker)** 主要是TIBCOIBM WebSphere和webMethods等公司的商业软件的秀场。最近像RabbitMQActiveMQHornetQNATS和Apache Kafka这样的开源实现已经流行起来。我们将在[第十一章](ch11.md)中对它们进行更详细的比较。
过去,**消息代理(Message Broker)** 主要是TIBCOIBM WebSphere和webMethods等公司的商业软件的秀场。最近像RabbitMQActiveMQHornetQNATS和Apache Kafka这样的开源实现已经流行起来。我们将在[第十一章](ch11.md)中对它们进行更详细的比较。

详细的交付语义因实现和配置而异,但通常情况下,消息代理的使用方式如下:一个进程将消息发送到指定的队列或主题,代理确保将消息传递给那个队列或主题的一个或多个消费者或订阅者。在同一主题上可以有许多生产者和许多消费者。

Expand Down Expand Up @@ -507,8 +507,8 @@ Actor模型是单个进程中并发的编程模型。逻辑被封装在actor中
我们讨论了几种数据编码格式及其兼容性属性:

* 编程语言特定的编码仅限于单一编程语言,并且往往无法提供前向和后向兼容性。
* JSONXML和CSV等文本格式非常普遍,其兼容性取决于你如何使用它们。他们有可选的模式语言,这有时是有用的,有时是一个障碍。这些格式对于数据类型有些模糊,所以你必须小心数字和二进制字符串。
* 像ThriftProtocol Buffers和Avro这样的二进制模式驱动格式允许使用清晰定义的前向和后向兼容性语义进行紧凑,高效的编码。这些模式可以用于静态类型语言的文档和代码生成。但是,他们有一个缺点,就是在数据可读之前需要对数据进行解码。
* JSONXML和CSV等文本格式非常普遍,其兼容性取决于你如何使用它们。他们有可选的模式语言,这有时是有用的,有时是一个障碍。这些格式对于数据类型有些模糊,所以你必须小心数字和二进制字符串。
* 像ThriftProtocol Buffers和Avro这样的二进制模式驱动格式允许使用清晰定义的前向和后向兼容性语义进行紧凑,高效的编码。这些模式可以用于静态类型语言的文档和代码生成。但是,他们有一个缺点,就是在数据可读之前需要对数据进行解码。

我们还讨论了数据流的几种模式,说明了数据编码重要性的不同场景:

Expand Down
2 changes: 1 addition & 1 deletion ch5.md
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ PostgreSQL和Oracle等使用这种复制方法【16】。主要缺点是日志
但是,即使在$w + r> n$的情况下,也可能存在返回陈旧值的边缘情况。这取决于实现,但可能的情况包括:

* 如果使用宽松的法定人数(见“[宽松的法定人数与提示移交](#宽松的法定人数与提示移交)”),w个写入和r个读取落在完全不同的节点上,因此r节点和w之间不再保证有重叠节点【46】。
* 如果两个写入同时发生,不清楚哪一个先发生。在这种情况下,唯一安全的解决方案是合并并发写入(请参阅“[处理写入冲突](#处理写入冲突)”)。如果根据时间戳(最后写入胜利)挑选出一个胜者,则由于时钟偏差[35],写入可能会丢失。我们将在“[检测并发写入](#检测并发写入)”继续讨论此话题。
* 如果两个写入同时发生,不清楚哪一个先发生。在这种情况下,唯一安全的解决方案是合并并发写入(请参阅“[处理写入冲突](#处理写入冲突)”)。如果根据时间戳(最后写入胜利)挑选出一个胜者,则由于时钟偏差【35】,写入可能会丢失。我们将在“[检测并发写入](#检测并发写入)”继续讨论此话题。
* 如果写操作与读操作同时发生,写操作可能仅反映在某些副本上。在这种情况下,不确定读取是返回旧值还是新值。
* 如果写操作在某些副本上成功,而在其他节点上失败(例如,因为某些节点上的磁盘已满),在小于w个副本上写入成功。所以整体判定写入失败,但整体写入失败并没有在写入成功的副本上回滚。这意味着如果一个写入虽然报告失败,后续的读取仍然可能会读取这次失败写入的值【47】。
* 如果携带新值的节点失败,需要读取其他带有旧值的副本。并且其数据从带有旧值的副本中恢复,则存储新值的副本数可能会低于w,从而打破法定人数条件。
Expand Down
4 changes: 2 additions & 2 deletions ch7.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ SELECT COUNT(*)FROM emails WHERE recipient_id = 2 AND unread_flag = true

比起盲目地依赖工具,我们应该对存在的并发问题的种类,以及如何防止这些问题有深入的理解。然后就可以使用我们所掌握的工具来构建可靠和正确的应用程序。

在本节中,我们将看几个在实践中使用的弱(**非串行的**,即nonserializable)隔离级别,并详细讨论哪种竞争条件可能发生也可能不发生,以便你可以决定什么级别适合你的应用程序。一旦我们完成了这个工作,我们将详细讨论可串行化(请参阅“[可串行化](#可串行化)”)。我们讨论的隔离级别将是非正式的,通过示例来进行。如果你需要严格的定义和分析它们的属性,你可以在学术文献中找到它们[28,29,30]
在本节中,我们将看几个在实践中使用的弱(**非串行的**,即nonserializable)隔离级别,并详细讨论哪种竞争条件可能发生也可能不发生,以便你可以决定什么级别适合你的应用程序。一旦我们完成了这个工作,我们将详细讨论可串行化(请参阅“[可串行化](#可串行化)”)。我们讨论的隔离级别将是非正式的,通过示例来进行。如果你需要严格的定义和分析它们的属性,你可以在学术文献中找到它们28,29,30

### 读已提交

Expand Down Expand Up @@ -281,7 +281,7 @@ SELECT COUNT(*)FROM emails WHERE recipient_id = 2 AND unread_flag = true

出于这个原因,大多数数据库[^vi]使用[图7-4](img/fig7-4.png)的方式防止脏读:对于写入的每个对象,数据库都会记住旧的已提交值,和由当前持有写入锁的事务设置的新值。当事务正在进行时,任何其他读取对象的事务都会拿到旧值。 只有当新值提交后,事务才会切换到读取新值。

[^vi]: 在撰写本文时,唯一在读已提交隔离级别使用读锁的主流数据库是使用`read_committed_snapshot = off`配置的IBM DB2和Microsoft SQL Server [23,36]
[^vi]: 在撰写本文时,唯一在读已提交隔离级别使用读锁的主流数据库是使用`read_committed_snapshot = off`配置的IBM DB2和Microsoft SQL Server 23,36

### 快照隔离和可重复读

Expand Down
2 changes: 1 addition & 1 deletion glossary.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 术语表 【DRAFT】
# 术语表

> 请注意,本术语表中的定义简短而简单,旨在传达核心思想,而不是术语的完整细微之处。 有关更多详细信息,请参阅正文中的参考资料。
Expand Down
Loading

0 comments on commit bbc7bb8

Please sign in to comment.