跳到主要内容

数据类型

引入或更新: v1.2.100

本页解释了数据类型的各个方面,包括数据类型列表、数据类型转换、转换方法,以及处理NULL值和NOT NULL约束。

数据类型列表

以下是Databend中通用数据类型的列表:

数据类型别名存储大小最小值最大值
BOOLEANBOOL1 byteN/AN/A
TINYINTINT81 byte-128127
SMALLINTINT162 bytes-3276832767
INTINT324 bytes-21474836482147483647
BIGINTINT648 bytes-92233720368547758089223372036854775807
FLOATN/A4 bytes-3.40282347e+383.40282347e+38
DOUBLEN/A8 bytes-1.7976931348623157E+3081.7976931348623157E+308
DECIMALN/A16/32 bytes-10^P / 10^S10^P / 10^S
DATEN/A4 bytes1000-01-019999-12-31
TIMESTAMPN/A8 bytes0001-01-01 00:00:009999-12-31 23:59:59.999999 UTC
VARCHARSTRINGN/AN/AN/A

以下是Databend中半结构化数据类型的列表:

数据类型别名示例描述
ARRAYN/A[1, 2, 3, 4]相同数据类型的值的集合,通过其索引访问。
TUPLEN/A('2023-02-14','Valentine Day')不同数据类型的值的有序集合,通过其索引访问。
MAPN/A{"a":1, "b":2, "c":3}一组键值对,其中每个键是唯一的,并映射到一个值。
VARIANTJSON[1,{"a":1,"b":{"c":2}}]不同数据类型的元素集合,包括ARRAYOBJECT
BITMAPN/A0101010101用于表示一组值的二进制数据类型,其中每个位表示值的存在或不存在。

数据类型转换

显式转换

我们有两种表达式将一个值转换为另一种数据类型。

  1. CAST函数,如果在转换过程中发生错误,它会抛出错误。

我们还支持pg风格的转换:CAST(c as INT)c::Int相同

  1. TRY_CAST函数,如果在转换过程中发生错误,它返回NULL。

隐式转换(“强制”)

关于“强制”(自动转换)的一些基本规则

  1. 所有整数数据类型都可以隐式转换为BIGINTINT64)数据类型。

例如:

Int --> bigint
UInt8 --> bigint
Int32 --> bigint
  1. 所有数值数据类型都可以隐式转换为DoubleFloat64)数据类型。

例如:

Int --> Double
Float --> Double
Int32 --> Double
  1. 所有非空数据类型T都可以隐式转换为Nullable(T)数据类型。

例如:

Int --> Nullable<Int>
String --> Nullable<String>
  1. 所有数据类型都可以隐式转换为Variant数据类型。

例如:

Int --> Variant
  1. 字符串数据类型是最低级别的数据类型,不能隐式转换为其他数据类型。
  2. Array<T> --> Array<U> 如果 T --> U
  3. Nullable<T> --> Nullable<U> 如果 T--> U
  4. Null --> Nullable<T> 对于任何 T 数据类型。
  5. 数值可以隐式转换为其他数值数据类型,如果不会丢失精度。

常见问题

为什么数值类型不能自动转换为字符串类型。

这在其他流行的数据库中是微不足道的,甚至可以工作。但它会引入歧义。

例如:

select 39 > '301';
select 39 = ' 39 ';

我们不知道如何根据数值规则或字符串规则进行比较。因为根据不同的规则,它们的结果是不同的。

select 39 > 301 是 false,而 select '39' > '301' 是 true。

为了使语法更精确且减少歧义,我们抛出错误给用户,以获得更精确的SQL。

为什么布尔类型不能自动转换为数值类型。

这也会带来歧义。 例如:

select true > 0.5;

错误信息:“不能从可空数据转换为非空类型”是什么意思。

这意味着你的源列中有一个空值。你可以使用TRY_CAST函数或将目标类型设为可空类型。

select concat(1, col) 不工作

你可以改进SQL为select concat('1', col)

我们可能会在未来改进表达式,如果可能的话,将字面量1解析为字符串值(concat函数只接受字符串参数)。

NULL值和NOT NULL约束

NULL值用于表示数据不存在或未知。在Databend中,每一列本质上都能够包含NULL值,这意味着一列可以容纳NULL值和常规数据。

如果你需要一个不允许NULL值的列,请使用NOT NULL约束。如果一列在Databend中配置为不允许NULL值,并且你在插入数据时没有为该列显式提供值,则会自动应用与该列数据类型关联的默认值。

数据类型默认值
整数数据类型0
浮点数据类型0.0
字符和字符串空字符串 ('')
日期和时间数据类型'1970-01-01' 对于 DATE, '1970-01-01 00:00:00' 对于 TIMESTAMP
布尔数据类型False

例如,如果你创建一个表如下:

CREATE TABLE test(
id Int64,
name String NOT NULL,
age Int32
);

DESC test;

Field|Type |Null|Default|Extra|
-----+-------+----+-------+-----+
id |BIGINT |YES |NULL | |
name |VARCHAR|NO |'' | |
age |INT |YES |NULL | |
  • "id"列可以包含NULL值,因为它没有"NOT NULL"约束。这意味着它可以存储整数或留空以表示缺失数据。

  • "name"列必须始终有一个值,因为"NOT NULL"约束不允许NULL值。

  • "age"列,像"id"一样,也可以包含NULL值,因为它没有"NOT NULL"约束,允许空条目或NULL值表示未知年龄。

以下INSERT语句插入一行,其中"age"列为NULL值。这是允许的,因为"age"列没有NOT NULL约束,因此它可以包含NULL值以表示缺失或未知数据。

INSERT INTO test (id, name, age) VALUES (2, 'Alice', NULL);

以下INSERT语句插入一行到"test"表中,为"id"和"name"列提供值,但没有为"age"列提供值。这是允许的,因为"age"列没有NOT NULL约束,因此它可以留空或分配NULL值以表示缺失或未知数据。

INSERT INTO test (id, name) VALUES (1, 'John');

以下INSERT语句尝试插入一行,没有为"name"列提供值。列类型的默认值将被应用。

INSERT INTO test (id, age) VALUES (3, 45);