
# HetuEngine数据类型说明
目前建表时支持的数据类型有tinyint、smallint、bigint、int、boolean、real、decimal、double、varchar、string、binary、varbinary、timestamp、date、char、array、row、map、struct，其余的类型在数据查询和运算时支持。
通常情况下，大部分非复合数据类型都可以通过字面量加字符串的方式来输入，示例为添加了一个json格式的字符串：
```
select json '{"name": "aa", "gender": "man"}';
              _col0              
---------------------------------
 {"name":"aa","gender":"man"} 
(1 row)
```
#### 布尔类型
"真"值的有效文本值是：TRUE、't'、'true'、'1'。
"假"值的有效文本值是：FALSE、'f'、'false'、'0'。
使用TRUE和FALSE是比较规范的用法（也是SQL兼容的用法）。
示例：
```
select BOOLEAN '0';
 _col0 
-------
 false 
(1 row)
 
select BOOLEAN 'TRUE';
 _col0 
-------
 true  
(1 row)
 
select BOOLEAN 't';
 _col0 
-------
 true  
(1 row)
```
#### 整数类型
表1整数类型 
| 名称       | 描述  | 存储空间 | 取值范围                                                    | 字面量      |
|:---|:---|:---|:---|:---|
| TINYINT  | 微整数 | 8位   | -128\~127                                               | TINYINT  |
| SMALLINT | 小整数 | 16位  | -32,768 \~ +32,767                                      | SMALLINT |
| INTEGER  | 整数  | 32位  | -2,147,483,648 \~ +2,147,483,647                        | INT      |
| BIGINT   | 大整数 | 64位  | -9,223,372,036,854,775,808 \~ 9,223,372,036,854,775,807 | BIGINT   |
   
示例：
```
--创建具有TINYINT类型数据的表。  
CREATE TABLE int_type_t1  (IT_COL1 TINYINT) ;    
--插入TINYINT类型数据  
insert into int_type_t1  values (TINYINT'10');    
--查看数据。  
SELECT * FROM int_type_t1;  
 it_col1    
---------   
 10  
(1 row)    
--删除表。  
DROP TABLE int_type_t1;
```
#### 固定精度型
| 名称      | 描述                                                                                                                                                                                                                                                                                                                                                                                                      | 存储空间 | 取值范围                                                                                                   | 字面量     |
|:---|:---|:---|:---|:---|
| DECIMAL | 固定精度的十进制数。精度最高支持到38位，但精度小于18位能保障性能最好。 Decimal有两个输入参数： - precision：总位数，默认38  - scale：小数部分的位数，默认0 说明： 如果小数位为零，即十进制（38,0），则支持最高19位精度。    | 64位  | ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_formulaimage_0000002092671338.png "点击放大") | DECIMAL |
| NUMERIC | 同DECIMAL                                                                                                                                                                                                                                                                                                                                                                                                | 128位 | ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_formulaimage_0000002128390541.png "点击放大") | NUMERIC |
   
表2字面量示例 
| 字面量示例                           | 数据类型            |
|:---|:---|
| DECIMAL '0'                     | DECIMAL(1)      |
| DECIMAL '12345'                 | DECIMAL(5)      |
| DECIMAL '0000012345.1234500000' | DECIMAL(20, 10) |
   
```
--创建具有DECIMAL类型数据的表
CREATE TABLE decimal_t1 (dec_col1 DECIMAL(10,3)) ;    
--插入具有DECIMAL类型数据  
insert into decimal_t1 values (DECIMAL '5.325');     
--查看数据
SELECT * FROM decimal_t1;  
 dec_col1  
---------   
 5.325 
(1 row)    
--反例：小数位数超出定义长度，sql执行失败
insert into decimal_t1 values (DECIMAL '5.3253');
Query 20201126_034601_00053_tq98i@default@HetuEngine failed: Insert query has mismatched column types: Table: [decimal(10,3)], Query: [decimal(5,4)]
--删除表
DROP TABLE decimal_t1;  
--创建NUMERIC 类型表
CREATE TABLE tb_numberic_hetu(col1 NUMERIC(9,7));
CREATE TABLE
--插入数据
INSERT INTO tb_numberic_hetu values(9.12);
INSERT: 1 row
--查看数据
SELECT * FROM tb_numberic_hetu;
col1    
------------
  9.1200000 
(1 row)
```
#### 浮点型
| 名称     | 描述                                        | 存储空间 | 取值范围                                                    | 字面量    |
|:---|:---|:---|:---|:---|
| REAL   | 实数                                        | 32位  | 1.40129846432481707e-45 \~3.40282346638528860e+38，正或负   | REAL   |
| DOUBLE | 双精度浮点数，15到17个有效位，具体取决于使用场景，有效位数并不取决于小数点位置 | 64位  | 4.94065645841246544e-324 \~1.79769313486231570e+308，正或负 | DOUBLE |
| FLOAT  | 单精度浮点数，6到9个有效位，具体取决于使用场景，有效位数并不取决于小数点位置   | 32位  | 1.40129846432481707e-45 \~3.40282346638528860e+38，正或负   | FLOAT  |
   
用法说明：
- 分布式查询使用高性能硬件指令进行单精度或者双精度运算时，由于每次执行的顺序不一样，在调用聚合函数，比如SUM()，AVG()，特别是当数据规模非常大时，达到数千万甚至数十亿，其运算结果可能会略有不同。这种情况下，建议使用DECIMAL数据类型来运算。
- 可以使用别名来指定数据类型。 示例：
  ```
  --创建具有float类型数据的表
  CREATE TABLE float_t1 (float_col1 FLOAT) ;
  --插入具有float类型数据
  insert into float_t1 values (float '3.50282346638528862e+38');
  --查看数据
  SELECT * FROM float_t1;
  float_col1
  ------------
  Infinity
  (1 row)
  --删除表
  DROP TABLE float_t1;
  ```
  
- 当小数部分为0时，可以通过cast()转为对应范围的整数处理，小数部分会四舍五入。 示例：
  ```
  select CAST(1000.0001 as INT);
  _col0
  -------
  1000
  (1 row)
  select CAST(122.5001 as TINYINT);
  _col0
  -------
  123
  (1 row)
  ```
  

- 使用指数表达式时，可以将字符串转为对应类型。
  示例：
  ```
  select CAST(152e-3 as double);
  _col0
  -------
  0.152
  (1 row)
  ```
  
 
#### 字符类型
| 名称         | 描述                                                                              |
|:---|:---|
| VARCHAR(n) | 变长字符串，n指字节长度。                                                                   |
| CHAR(n)    | 定长字符串，不足补空格。n是指字节长度，如不带精度n，默认为1。                                                |
| VARBINARY  | 变长二进制数据。需要带上前缀X，如：X'65683F'，暂不支持指定长度的二进制字符串。                                    |
| JSON       | 取值可以是a JSON object、a JSON array、a JSON number、a JSON string、true、false or null。 |
| STRING     | 兼容impala的String，底层是varchar。                                                     |
| BINARY     | 兼容hive的Binary，底层实现为varbinary。                                                   |
   
- SQL表达式中，支持简单的字符表达式，也支持Unicode方式，一个Unicode字符串是以U\&为固定前缀，以4位数值表示的Unicode前需要加转义符。
  ```
  -- 字符表达式  
  select 'hello,winter!';  
        _col0         
  ------------------  
   hello,winter!   
  (1 row)  
  -- Unicode 表达式  
  select U&'Hello winter \2603 !';  
        _col0         
  ------------------  
   Hello winter ☃ !   
  (1 row)    
  -- 自定义转义符  
  select U&'Hello winter #2603 !' UESCAPE '#';  
        _col0         
  ------------------  
   Hello winter ☃ !   
  (1 row)
  ```
  
- VARBINARY与BINARY。
  ```
  -- 创建VARBINARY类型或BINARY类型的表
   create table binary_tb(col1 BINARY);
  -- 插入数据
   INSERT INTO binary_tb values (X'63683F');
  --查询数据
   select * from binary_tb ;  -- 63 68 3f
  ```
  
- 在做CHAR数值比较的时候，在对两个仅尾部空格数不同的CHAR进行比较时，会认为它们是相等的。
  ```
  SELECT CAST('FO' AS CHAR(4)) = CAST('FO     ' AS CHAR(5));
   _col0 
  -------
   true  
  (1 row)
  ```
  
 
#### 时间和日期类型
时间和日期类型目前精确到毫秒。
表3时间和日期类型 
| 名称                      | 描述                                                                                                                                                                                                                                              | 存储空间 |
|:---|:---|:---|
| DATE                    | 日期和时间。仅支持ISO 8601格式：'2020-01-01'                                                                                                                                                                                                                | 32位  |
| TIME                    | 不带时区的时间（时、分、秒、毫秒） 例如：TIME '01:02:03.456'                                                                                                                                                                       | 64位  |
| TIME WITH TIMEZONE      | 带时区的时间（时、分、秒、毫秒），时区用UTC值表示 例如：TIME '01:02:03.456 -08:00'                                                                                                                                                         | 96位  |
| TIMESTAMP               | 时间戳                                                                                                                                                                                                                                             | 64位  |
| TIMESTAMP WITH TIMEZONE | 带时区的时间戳                                                                                                                                                                                                                                         | 64位  |
| INTERVAL YEAR TO MONTH  | 时间间隔字面量，年，月，格式： SY-M S：可选符号（+/-） Y：年数 M：月数                                                                                                     | 128位 |
| INTERVAL DAY TO SECOND  | 时间间隔字面量，日，小时，分钟， 秒，精确到毫秒，格式：SD H:M:S.nnn S：可选符号（+/-） D：天数 M：分钟数 S：秒数 nnn：毫秒数 | 128位 |
   
示例：
```
-- 查询日期
SELECT DATE '2020-07-08';
   _col0    
------------
 2020-07-08 
(1 row)
-- 查询时间
SELECT TIME '23:10:15';
 _col0     
--------------
 23:10:15 
(1 row)
SELECT TIME '01:02:03.456 -08:00';
 _col0     
--------------
 01:02:03.456-08:00 
(1 row)
-- 时间间隔用法 
SELECT TIMESTAMP '2015-10-18 23:00:15' + INTERVAL '3 12:15:4.111' DAY TO SECOND;      
 _col0          
------------------------- 
 2015-10-22 11:15:19.111 
(1 row)
SELECT TIMESTAMP '2015-10-18 23:00:15' + INTERVAL '3-1' YEAR TO MONTH;
          _col0          
-------------------------
 2018-11-18 23:00:15 
(1 row)
select INTERVAL '3' YEAR + INTERVAL '2' MONTH ;
 _col0 
-------
 3-2   
(1 row)
select INTERVAL '1' DAY+INTERVAL '2' HOUR +INTERVAL '3' MINUTE +INTERVAL '4' SECOND ;
     _col0      
----------------
 1 02:03:04.000 
(1 row)
```
#### ARRAY
数组。
示例：ARRAY\[1, 2, 3\]。
```
--创建ARRAY类型表
create table array_tb(col1 ARRAY<STRING>);
--插入一条ARRAY类型数据
insert into array_tb values(ARRAY['HetuEngine','Hive','Mppdb']);
--查询数据
select * from array_tb; --    [HetuEngine, Hive, Mppdb]
```
#### MAP
键值对数据类型。
示例：MAP(ARRAY\['foo', 'bar'\]、ARRAY\[1, 2\])。
```
--创建Map类型表
create table map_tb(col1 MAP<STRING,INT>);
--插入一条Map类型数据
insert into map_tb values(MAP(ARRAY['foo','bar'],ARRAY[1,2]));
--查询数据
select * from map_tb; --   {bar=2, foo=1}
```
 #### ROW
ROW的字段可是任意所支持的数据类型，也支持各字段数据类型不同的混合方式。
```
--创建ROW表
create table row_tb (id int,col1 row(a int,b varchar));
--插入ROW类型数据
insert into row_tb values (1,ROW(1,'HetuEngine'));
--查询数据
select * from row_tb; 
 id |     col1     
---|--------------
  1 | {a=1, b=HetuEngine} 
--字段是支持命名的，默认情况下，Row的字段是未命名的
select  row(1,2e0),CAST(ROW(1, 2e0) AS ROW(x BIGINT, y DOUBLE));
           _col0          |    _col1     
---|--------------
 {1, 2.0} | {x=1, y=2.0} 
(1 row) 
--命名后的字段，可以通过域操作符"."访问
select col1.b from row_tb; -- HetuEngine
--命名和未命名的字段，都可以通过位置索引来访问，位置索引从1开始，且必须是一个常量
select col1[1] from row_tb;   -- 1
```
#### IPADDRESS
IP地址，可以表征IPv4或者IPv6地址。但在系统内，该类型是一个统一的IPv6地址。
对于IPv4的支持，是通过将IPv4映射到IPv6的取值范围（RFC 4291#section-2.5.5.2）来实现的。当创建一个IPv4时，会被映射到IPv6。当格式化时，如果数据是IPv4又会被重新映射为IPv4。 其他的地址则会按照RFC 5952所定义的规范格式来进行格式化。
示例：
```
select IPADDRESS '10.0.0.1', IPADDRESS '2001:db8::1';
  _col0   |    _col1
---|-------------
 10.0.0.1 | 2001:db8::1
(1 row)
```
#### UUID
标准UUID (Universally Unique IDentifier)，也被称为GUID (Globally Unique IDentifier)。
遵从RFC 4122标准所定义的格式。
示例：
```
select UUID '12151fd2-7586-11e9-8f9e-2a86e4085a59';
                _col0
--------------------------------------
 12151fd2-7586-11e9-8f9e-2a86e4085a59
(1 row)
```
#### HYPERLOGLOG
基数统计。
用HyperLogLog来近似计算唯一数的计数值，其代价要远小于用count来计算。
参见[HyperLogLog函数](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_300211.html)函数。
- HyperLogLog A HyperLogLog sketch可以用来高效地计算distinct()的近似值。
  它以一个稀疏的表征开始，然后变成一个密集的表征，此时效率将变得更高。
  

- P4HyperLogLog 类似于A HyperLogLog sketch，但是它以一个密集的表征开始。
  
 
#### QDIGEST
分位数（Quantile），亦称分位点，是指将一个随机变量的概率分布范围分为几个等份的数值点，常用的有中位数（即二分位数）、四分位数、百分位数等。quantile digest是一个分位数的集合，当需要查询的数据落在某个分位数附近时，就可以用这个分位数作为要查询数据的近似值。它的精度可以调节，但更高精度的结果会带来空间的昂贵开销。
#### STRUCT
底层用ROW实现，参照[ROW]。
示例：
```
-- 创建struct 表
create table struct_tab (id int,col1 struct<col2: integer, col3: string>);
--插入 struct 类型数据
 insert into struct_tab VALUES(1, struct<2, 'HetuEngine'>);
--查询数据
select * from struct_tab; 
 id |        col1         
---|---------------------
  1 | {col2=2, col3=HetuEngine}
```
