testbook

数据类型

Inceptor对原生数据类别(primitive data type)和复杂数据类别(complex data type)都支持。

原生数据类别

数据类型 描述 示例
TINYINT 1字节(8位)有符号整数,从-128到127 1
SMALLINT 2字节(16位)有符号整数,从-32768到32767 1
INT 4字节(32位)有符号整数,从-2147483648到2147483647 1
BIGINT 8字节(64位)有符号整数,从-9223372036854775808到9223372036854775807 1
FLOAT 4字节单精度浮点数 1.0
DOUBLE 8字节双精度浮点数 1.0
DECIMAL 不可变的,任意精度的,有符号的十进制数 1.012,1e+44
BOOLEAN true/false TRUE
STRING 字符串 'a', ''a''
VARCHAR 可变长度的字符 'a', 'a '
DATE 日期。格式:'YYYY-MM-DD', 从'0001-01-01''9999-12-31' '2014-01-01'
TIMESTAMP时间戳,表示日期和时间。格式:'YYYY-MM-DD HH:MM:SS.fffffffff' ,可达到小数点后9位(纳秒级别)精度 '2014-01-01 00:00:00'
INTERVAL DAY/MONTH/YEAR用于存储一段以年,月或日为单位的时间INTERVAL '10' day

说明

  • DECIMAL
    DECIMAL类型让用户可以自定义数据的精度。一个DECIMAL由一个任意精度的整数未标度(unscaled value)和一个32位的整数标度(scale)组成。DECIMAL表示的数值是 unscaledValue × 10-scale。也就是说,如果标度是正数,DECIMAL数值是unscaledValue小数点左移scale位;如果标度是负数,DECIMAL数值是unscaledValue后加scale个0;如果标度是0,DECIMAL的值就是unscaledValue。DECIMAL可以用于所有常见运算(如+, -, *, /)和相应的UDF(如Floor, Ceil, Round,等等)。用户也可以用数值型(numeric type)的常见方法来在DECIMAL和别的数值型之间转换。

  • VARCHAR
    VARCHAR生成时会带有一个长度指定数(length specifier)(1和65355之间),用来定义字符串中的最大字符数。如果一个向VARCHAR转换的STRING型中的字符个数超过了长度指定数,那么这个STRING会被自动缩短。和STRING类型一样, VARCHAR末尾的空格数是有意义的,会影响比较结果。
  • DATE
    DATE类型只能和DATE, TIMESTAMP和STRING互显性转换(cast)。具体如下表:
    有效显性转换 转换结果
    cast(date as date) 相同DATE值
    cast(timestamp as date) 根据本地时区从TIMESTAMP得出年/月/日,将其作为DATE值返回
    cast(string as date) 如果字符串的形式是'YYYY-MM-DD', 将对应年/月/日作为DATE值返回。如果字符串不具有这种形式,返回NULL。
    cast(date as timestamp) 根据本地时区生成并返回对应DATE值年/月/日零点的TIMESTAMP值。
    cast(date as string) 根据DATE的年/月/日值生成并返回'YYYY-MM-DD'格式的字符串。
  • TIMESTAMP
    支持传统的UNIX TIMESTAMP,提供达到纳秒级别精度的选择。TIMESTAMP是以和UNIX epoch (协调世界时1970年1月1日00:00:00)之间的秒数差定义的。可以向TIMESTAMP隐性转换的数类型有:
    • 整数数值型:当作UNIX TIMESTAMP秒数处理。
    • 浮点数数值型:当作有小数点后精度的UNIX TIMESTAMP处理。
    • 字符串:必须具有"YYYY-MM-DD HH:MM:SS[.fffffffff]"格式。小数点后秒数精度可选。
    Inceptor提供了在时区间转换的UDF:to_utc_timestamp, from_utc_time。所有现成的日期时间UDF(month, day, year, hour等)都可以用于TIMESTAMP。在文本文件中,TIMESTAMP的格式必须是YYYY-MM-DD HH:MM:SS[.fffffffff]格式。如果是以其他格式表示的,先用合适的数据类型(INT,FLOAT,STRING 等)声明然后再用UDF转换成TIMESTAMP。
  • INTERVAL
    在Inceptor中,INTERVAL类型可以分别表示以年、月、日为单位的一段时间。INTERVAL类型的数据只能和DATE类型相加,得到一个新的DATE类型。
    INTERVAL 'n' DAY        //长度为n天的一段时间
    INTERVAL 'n' MONTH      //长度为n月的一段时间
    INTERVAL 'n' YEAR       //长度为n年的一段时间
    
    以下三条计算都能得到一年以后的日期:
    cast('1998-08-04' AS DATE) +  INTERVAL '365' DAY
    cast('1998-08-04' AS DATE) +  INTERVAL '1' YEAR
    cast('1998-08-04' AS DATE) +  INTERVAL '12' MONTH
    
  • 原生数据之间的隐性转换(conversion)

    Inceptor原生数据之间的隐性转换遵从下面的金字塔结构。类型可以在这个金字塔中从上向下隐性转换。但是不能由下向上隐性转换。如果需要从下向上转换,必须使用显性转换(cast)。注意,FLOAT可以隐性转换成DOUBLE,而BOOLEAN不能和任何类型之间进行转换。
    pyramid

    复杂数据类别

    数据类型 描述 示例
    ARRAY 一组有序字段,所有字段的数据类型必须相同 array(1,2)
    MAP 一组无序的键/值对。键的类型必须是原生数据类型,值的类型可以是原生或复杂数据类型。同一个MAP的键的类型必须相同,值的类型也必须相同。 map('a', 1, 'b', 2)
    STRUCT 一组命名的字段,字段的数据类型可以不同 struct('a', 1, 1.0)
    UNIONTYPE 由一组命名的字段组成,字段的数据类型可以不同,但是一个UNIONTYPE同时只能被赋予其中一种数据类型。 见下

    CREATE TABLE union_test(foo UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>);
    SELECT foo FROM union_test;
    
    {0:1}
    {1:2.0}
    {2:["three","four"]}
    {3:{"a":5,"b":"five"}}
    {2:["six","seven"]}
    {3:{"a":8,"b":"eight"}}
    {0:9}
    {1:10.0}
    

    去序列化的UNIONTYPE的第一部份(冒号前面的部分)是一个标签(tag),用于表示被使用的字段。0表示第一个字段的数据类型(本例为INT),1表示第二个字段的数据类型(本例为DOUBLE),等等。UNIONTYPE用create_union这个UDF来创建,在创建时,必须要向create_union提供标签:

    SELECT create_union(0, key), create_union(if(key<100, 0, 1), 2.0, value), create_union(1, "a", struct(2, "b")) FROM src LIMIT 2;
    
    {0:"238"}    {1:"val_238"}    {1:{"col1":2,"col2":"b"}}
    {0:"86"}    {0:2.0}    {1:{"col1":2,"col2":"b"}}