Merge pull request #129 from anaer/patch-1

Update ch4.md
This commit is contained in:
Gang Yin 2021-09-14 09:24:20 +08:00 committed by GitHub
commit a8f682feee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

8
ch4.md
View File

@ -90,7 +90,7 @@ JSONXML和CSV属于文本格式因此具有人类可读性尽管它们
JSON比XML简洁但与二进制格式相比还是太占空间。这一事实导致大量二进制编码版本JSONMessagePackBSONBJSONUBJSONBISON和Smile等 和 XML例如WBXML和Fast Infoset的出现。这些格式已经在各种各样的领域中采用但是没有一个能像文本版JSON和XML那样被广泛采用。 JSON比XML简洁但与二进制格式相比还是太占空间。这一事实导致大量二进制编码版本JSONMessagePackBSONBJSONUBJSONBISON和Smile等 和 XML例如WBXML和Fast Infoset的出现。这些格式已经在各种各样的领域中采用但是没有一个能像文本版JSON和XML那样被广泛采用。
这些格式中的一些扩展了一组数据类型例如区分整数和浮点数或者增加对二进制字符串的支持另一方面它们没有改变JSON / XML的数据模型。特别是由于它们没有规定模式所以它们需要在编码数据中包含所有的对象字段名称。也就是说在[例4-1]()中的JSON文档的二进制编码中需要在某处包含字符串`userName``favoriteNumber`和`interest`。 这些格式中的一些扩展了一组数据类型例如区分整数和浮点数或者增加对二进制字符串的支持另一方面它们没有改变JSON / XML的数据模型。特别是由于它们没有规定模式所以它们需要在编码数据中包含所有的对象字段名称。也就是说在[例4-1]()中的JSON文档的二进制编码中需要在某处包含字符串`userName``favoriteNumber`和`interests`。
**例4-1 本章中用于展示二进制编码的示例记录** **例4-1 本章中用于展示二进制编码的示例记录**
@ -152,7 +152,7 @@ Thrift和Protocol Buffers每一个都带有一个代码生成工具它采用
与[图4-1](Img/fig4-1.png)类似,每个字段都有一个类型注释(用于指示它是一个字符串,整数,列表等),还可以根据需要指定长度(字符串的长度,列表中的项目数) 。出现在数据中的字符串`(“Martin”, “daydreaming”, “hacking”)`也被编码为ASCII或者说UTF-8与之前类似。 与[图4-1](Img/fig4-1.png)类似,每个字段都有一个类型注释(用于指示它是一个字符串,整数,列表等),还可以根据需要指定长度(字符串的长度,列表中的项目数) 。出现在数据中的字符串`(“Martin”, “daydreaming”, “hacking”)`也被编码为ASCII或者说UTF-8与之前类似。
与[图4-1](img/fig4-1.png)相比,最大的区别是没有字段名`(userName, favoriteNumber, interest)`。相反,编码数据包含字段标签,它们是数字`(1, 2和3)`。这些是模式定义中出现的数字。字段标记就像字段的别名 - 它们是说我们正在谈论的字段的一种紧凑的方式,而不必拼出字段名称。 与[图4-1](img/fig4-1.png)相比,最大的区别是没有字段名`(userName, favoriteNumber, interests)`。相反,编码数据包含字段标签,它们是数字`(1, 2和3)`。这些是模式定义中出现的数字。字段标记就像字段的别名 - 它们是说我们正在谈论的字段的一种紧凑的方式,而不必拼出字段名称。
Thrift CompactProtocol编码在语义上等同于BinaryProtocol但是如[图4-3](img/fig4-3.png)所示它只将相同的信息打包成只有34个字节。它通过将字段类型和标签号打包到单个字节中并使用可变长度整数来实现。数字1337不是使用全部八个字节而是用两个字节编码每个字节的最高位用来指示是否还有更多的字节来。这意味着-64到63之间的数字被编码为一个字节-8192和8191之间的数字以两个字节编码等等。较大的数字使用更多的字节。 Thrift CompactProtocol编码在语义上等同于BinaryProtocol但是如[图4-3](img/fig4-3.png)所示它只将相同的信息打包成只有34个字节。它通过将字段类型和标签号打包到单个字节中并使用可变长度整数来实现。数字1337不是使用全部八个字节而是用两个字节编码每个字节的最高位用来指示是否还有更多的字节来。这意味着-64到63之间的数字被编码为一个字节-8192和8191之间的数字以两个字节编码等等。较大的数字使用更多的字节。
@ -248,9 +248,9 @@ Avro的关键思想是Writer模式和Reader模式不必是相同的 - 他们只
使用Avro向前兼容性意味着您可以将新版本的模式作为Writer并将旧版本的模式作为Reader。相反向后兼容意味着你可以有一个作为Reader的新版本模式和作为Writer的旧版本模式。 使用Avro向前兼容性意味着您可以将新版本的模式作为Writer并将旧版本的模式作为Reader。相反向后兼容意味着你可以有一个作为Reader的新版本模式和作为Writer的旧版本模式。
为了保持兼容性,您只能添加或删除具有默认值的字段。 我们的Avro模式中的字段`favourNumber`的默认值为`null`。例如假设您添加了一个有默认值的字段这个新的字段将存在于新模式而不是旧模式中。当使用新模式的Reader读取使用旧模式写入的记录时将为缺少的字段填充默认值。 为了保持兼容性,您只能添加或删除具有默认值的字段。 我们的Avro模式中的字段`favoriteNumber`的默认值为`null`。例如假设您添加了一个有默认值的字段这个新的字段将存在于新模式而不是旧模式中。当使用新模式的Reader读取使用旧模式写入的记录时将为缺少的字段填充默认值。
如果你要添加一个没有默认值的字段新的Reader将无法读取旧Writer写的数据所以你会破坏向后兼容性。如果您要删除没有默认值的字段旧的Reader将无法读取新Writer写入的数据因此您会打破向前兼容性。在一些编程语言中null是任何变量可以接受的默认值但在Avro中并不是这样如果要允许一个字段为`null`,则必须使用联合类型。例如,`union {nulllongstring} field;`表示field可以是数字或字符串也可以是`null`。如果要将null作为默认值则它必须是union的分支之一[^iv]。这样的写法比默认情况下就允许任何变量是`null`显得更加冗长,但是通过明确什么可以和什么不可以是`null`有助于防止出错【22】。 如果你要添加一个没有默认值的字段新的Reader将无法读取旧Writer写的数据所以你会破坏向后兼容性。如果您要删除没有默认值的字段旧的Reader将无法读取新Writer写入的数据因此您会打破向前兼容性。在一些编程语言中null是任何变量可以接受的默认值但在Avro中并不是这样如果要允许一个字段为`null`,则必须使用联合类型。例如,`union {null, long, string} field;`表示field可以是数字或字符串也可以是`null`。如果要将null作为默认值则它必须是union的分支之一[^iv]。这样的写法比默认情况下就允许任何变量是`null`显得更加冗长,但是通过明确什么可以和什么不可以是`null`有助于防止出错【22】。
[^iv]: 确切地说默认值必须是联合的第一个分支的类型尽管这是Avro的特定限制而不是联合类型的一般特征。 [^iv]: 确切地说默认值必须是联合的第一个分支的类型尽管这是Avro的特定限制而不是联合类型的一般特征。