跳到主要内容

数据类型

Introduced or updated: v1.2.100

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

数据类型列表

以下是 Databend 中的常规数据类型列表:

数据类型别名存储大小最小值最大值
BOOLEANBOOL1 字节N/AN/A
TINYINTINT81 字节-128127
SMALLINTINT162 字节-3276832767
INTINT324 字节-21474836482147483647
BIGINTINT648 字节-92233720368547758089223372036854775807
FLOATN/A4 字节-3.40282347e+383.40282347e+38
DOUBLEN/A8 字节-1.7976931348623157E+3081.7976931348623157E+308
DECIMALN/A16/32 字节-10^P / 10^S10^P / 10^S
DATEN/A4 字节1000-01-019999-12-31
TIMESTAMPN/A8 字节0001-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。

隐式转换 ("Coercion")

关于 "Coercion" (也称为自动转换)的一些基本规则

  1. 所有整数数据类型都可以隐式转换为 BIGINT (也称为 INT64)数据类型。

例如:

Int --> bigint
UInt8 --> bigint
Int32 --> bigint
  1. 所有数字数据类型都可以隐式转换为 Double (也称为 Float64)数据类型。

例如:

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

例如:

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

例如:

Int --> Variant
  1. String 数据类型是最低的数据类型,不能隐式转换为其他数据类型。
  2. 如果 T --> U,则 Array<T> --> Array<U>
  3. 如果 T--> U,则 Nullable<T> --> Nullable<U>
  4. 对于任何 T 数据类型,Null --> Nullable<T>
  5. 如果没有精度损失,则数值可以隐式转换为其他数值数据类型。

常见问题解答

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

这很简单,甚至在其他流行的数据库中也可以工作。但是这会引入歧义。

例如:

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

我们不知道如何使用数值规则或 String 规则来比较它们。因为根据不同的规则,它们会产生不同的结果。

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

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

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

这也会带来歧义。 例如:

select true > 0.5;

什么是错误消息:“can't cast from nullable data into non-nullable type”。

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

select concat(1, col) 不起作用

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

我们将来可能会改进表达式,如果可能的话,可以将文字 1 解析为 String 值(concat 函数只接受 String 参数)。

NULL 值和 NOT NULL 约束

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

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

数据类型默认值
整数数据类型0
浮点数据类型0.0
字符和字符串空字符串 ('')
日期和时间数据类型DATE 为 '1970-01-01',TIMESTAMP 为 '1970-01-01 00:00:00'
布尔数据类型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” 约束。这意味着它可以存储整数或留空以表示缺少数据。

  • 由于 “NOT NULL” 约束, “name” 列必须始终具有值,不允许 NULL 值。

  • 与 “id” 类似, “age” 列也可以包含 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);