AVRO1.4.1规范-Schema的定义和声明

[size=medium]AVRO1.4.1规范-Schema的定义和声明[/size](参考自[url]http://avro.apache.org/docs/current/spec.html[/url])
guibin.beijing@gmail.com

Avro 1.4.1规范定义了Avro序列化系统,它即将成为官方规范,Avro的各种实现方式必须遵循该规范。2

[size=medium]Schema定义[/size]
AVRO的Schema是用JSON的格式表示的,Schema可以用
[list]
[*] JSON String 来命名一个定义的类型
[*] JSON 对象,形式如:
[quote]{"type": "typeName" ...attributes...}[/quote]
typeName可以是一个原生类型或者下面将要定义的衍生类型。这篇文档没有定义JSON对象中的属性,这些属性可以成为meta data,但是不能影响序列化数据的格式。
[*] JSON 数组,代表内嵌类型的并集(union)。
[/list]

[size=medium]原生类型[/size]
原生类型如下所示:
[list]
[*] null: 表示没有值
[*] boolean: 表示一个二进制布尔值
[*] int: 表示32位有符号整数
[*] long: 表示64位有符号整数
[*] float: 表示32位的单精度浮点数(IEEE 754)
[*] double: 表示64位双精度浮点数(IEEE 754)
[*] bytes: 表示8位的无符号字节序列
[*] string: Unicode 编码的字符序列
总共就这8种原生数据类型,这些原生数据类型均没有明确的属性。
[/list]
原生数据类型也可以使用JSON定义类型名称,比如schema "string"和{"type": "string"}是同义且相等的。

[size=medium]复杂类型[/size]
AVRO支持6种类型的复杂类型,分别是:records, enums, arrays, maps, unions and fixed.
[size=small][b]Records[/b][/size]
Records使用类型名称“record”,并且支持三个必选属性。
[list]
[*] [b]type[/b]: 必有属性。
[*] [b]name[/b]: 必有属性,是一个JSON string,提供了记录的名字。
namespace,也是一个JSON string,用来限定和修饰name属性。
[*] doc: 可选属性,是一个JSON string,为使用这个Schema的用户提供文档。
[*] aliases: 可选属性,是JSON的一个string数组,为这条记录提供别名。
[*] [b]fields[/b]: 必选属性,是一个JSON数组,数组中列举了所有的field。每一个field都是一个JSON对象,并且具有如下属性:
name: 必选属性,field的名字,是一个JSON string。
doc: 可选属性,为使用此Schema的用户提供了描述此field的文档。
type: 必选属性,定义Schema的一个JSON对象,或者是命名一条记录定义的JSON string。
default: 可选属性,即field的默认值,当读到缺少这个field的实例时用到。默认值的允许的范围由这个field的Schama的类型决定,如下表所示。其中union fields的默认值对应于union中第一个Schema。Bytes和fixed的field的默认值都是JSON string,并且指向0-255的unicode都对应于无符号8位字节值0-255。
[table]
[b]field default values[/b]
|[b]avro type[/b]|[b]json type[/b]|[b]example[/b]
|null|null|null|
|boolean|boolean|[b]true[/b]|
|int, long|integer|[b]1[/b]|
|float, double|number|[b]1.1[/b]|
|bytes|string|"\u00ff"|
|string|string|"foo"|
|record|object|{"a":1}|
|enum|string|"FOO"|
|array|array|[1]|
|map|object|{"a":1}|
|fixed|string|"\u00ff"|
[/table]
order: 可选属性,指定这个field如何影响record的排序。有效的可选值为“ascending”(默认),"descending"和"ignore"
alias: JSON的string数组,为这个field提供别名。

比如,一个64位值的链表定义为
[quote]{
"type": "record",
"name": "LongList",
"aliases": ["LinkedLongs"], // old name for this
"fields" : [
{"name": "value", "type": "long"}, // each element has a long
{"name": "next", "type": ["LongList", "null"]} // optional next element
]
}
[/quote]
[/list]

[size=small][b]Enums[/b][/size]
Enums使用的名为“enum”的type并且支持如下的属性:
[list]
[*] name: 必有属性,是一个JSON string,提供了enum的名字。
namespace,也是一个JSON string,用来限定和修饰name属性。
[*] aliases: 可选属性,是JSON的一个string数组,为这个enum提供别名。
[*] doc: 可选属性,是一个JSON string,为使用这个Schema的用户提供文档。
[*] symbols: 必有属性,是一个JSON string数组,列举了所有的symbol,在enum中的所有symbol都必须是唯一的,不允许重复。比如下面的例子:
[quote]{ "type": "enum",
"name": "Suit",
"symbols" : ["SPADES", "HEARTS", "DIAMONDS", "CLUBS"]
}[/quote]
[/list]

[size=small][b] Arrays[/b][/size]
Array使用名为"array"的type,并且支持一个属性[list]
[*] items: array中元素的Schema
比如一个string的数组声明为:
[quote]{"type": "array", "items": "string"}[/quote]
[/list]

[size=small][b] Maps[/b][/size]
Map使用名为"map"的type,并且支持一个属性
[list]
[*] values: 用来定义map的值的Schema。Maps的key都是string。比如一个key为string,value为long的maps定义为:
[quote]{"type": "map", "values": "long"}[/quote]
[/list]

[size=small][b] Unions[/b][/size]
Unions就像上面提到的,使用JSON的数组表示。比如[quote]["string", "null"][/quote]声明了一个union的Schema,其元素即可以是string,也可以是null。
Unions不能包含多个相同类型的Schema,除非是命名的record类型、命名的fixed类型和命名的enum类型。比如,如果unions中包含两个array类型,或者包含两个map类型都不允许;但是两个具有不同name的相同类型却可以。由此可见,[b]union是通过Schema的name来区分元素Schema的[/b],因为array和map没有name属性,当然只能存在一个array或者map。(使用name作为解析的原因是这样做会使得读写unions更加高效)。unions不能紧接着包含其他的union。

[size=small][b] Fixed[/b][/size]
Fixed类型使用"fixed"的type name,并且支持三个属性:
[list]
[*] name: 必有属性,表示这个fixed的名称,JSON string。
namespace同上
[*] aliases: 可选属性,同上
[*] size: 必选属性,一个整数,志明每个值的字节数。
比如16字节的fixed可以声明为:
[quote]{"type": "fixed", "size": 16, "name": "md5"}[/quote]
[/list]

[size=medium]Names[/size]
Record, enums 和 fixed都是命名的类型,这三种类型都各有一个全名,全名有两部分组成:名称和命名空间。名称的相等是定义在全名基础上的。
全名的名字部分和record的field名字必须:
[list]
[*] 以[A-Za-z_]开头
[*] 接下来的名字中只能包含[A-Za-z0-9_]
namespace是以点分隔的一系列名字。
In record, enum and fixed definitions, the fullname is determined in one of the following ways:
在record、enum和fixed的定义中,全名由以下的任意一条决定:
[*] 同时指定name和namespace,比如使用 "name": "X", "namespace": "org.foo"来表示全名org.foo.X。
[*] 指定全名。如果name中包含点号,则认为是全名。比如用 "name": "org.foo.X" 表示全名org.foo.X。
[*] 仅仅指定name,name中没有点号。在这种情况下命名空间取自距离最近的父亲的Schema或者protocol。比如声明了"name": "X", 这段声明在一条记录“org.foo.Y”的field中,那么X的全名就是org.foo.X。
原生类型没有命名空间,并且在不可以在命名空间中定义原生类型。如果多个全名定义相等的话,一个Schema可以包含多个全名定义。
[/list]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值