数据类型兼容性参考
将现有数据库的 DDL 和 SQL 迁移到 Lakehouse 时,本文列出常见的兼容性差异点,帮助提前规避问题。
数据类型映射
Lakehouse 支持多种类型别名,来自其他数据库的 DDL 可以直接使用,无需手动替换类型名。别名在解析时立即转换为 Lakehouse 的规范类型,
DESCRIBEDESCRIBE
和
SHOW CREATE TABLESHOW CREATE TABLE
显示的是规范名,不是原始别名。
MySQL
MySQL 类型 Lakehouse 类型 说明 TINYINTTINYINT
TINYINTTINYINT
直接支持 SMALLINTSMALLINT
SMALLINTSMALLINT
直接支持 INTINT
/ INTEGERINTEGER
INTINT
直接支持,INTEGERINTEGER
为别名 BIGINTBIGINT
BIGINTBIGINT
直接支持 FLOATFLOAT
FLOATFLOAT
直接支持 DOUBLEDOUBLE
DOUBLEDOUBLE
直接支持 DECIMAL(p,s)DECIMAL(p,s)
/ NUMERIC(p,s)NUMERIC(p,s)
DECIMAL(p,s)DECIMAL(p,s)
直接支持,NUMERICNUMERIC
为别名 VARCHAR(n)VARCHAR(n)
VARCHAR(n)VARCHAR(n)
直接支持,最大长度 1048576 CHAR(n)CHAR(n)
CHAR(n)CHAR(n)
直接支持,最大长度 255 TEXTTEXT
STRINGSTRING
直接支持,TEXTTEXT
为别名 DATEDATE
DATEDATE
直接支持 DATETIMEDATETIME
TIMESTAMP_NTZTIMESTAMP_NTZ
MySQL DATETIME 无时区,对应 TIMESTAMP_NTZ TIMESTAMPTIMESTAMP
TIMESTAMPTIMESTAMP
(即 TIMESTAMP_LTZTIMESTAMP_LTZ
)两者均为带时区时间戳 BOOLEANBOOLEAN
/ BOOLBOOL
BOOLEANBOOLEAN
直接支持;BOOLBOOL
别名不支持,需改为 BOOLEANBOOLEAN
⚠️ MySQL 的
DATETIMEDATETIME
应映射为
TIMESTAMP_NTZTIMESTAMP_NTZ
,而非
TIMESTAMPTIMESTAMP
。若误用
TIMESTAMPTIMESTAMP
,写入和读取会受会话时区影响,与 MySQL 行为不一致。
PostgreSQL
PostgreSQL 类型 Lakehouse 类型 说明 SMALLINTSMALLINT
/ INT2INT2
SMALLINTSMALLINT
INT2INT2
别名不支持,需改为 SMALLINTSMALLINT
或 SHORTSHORT
INTEGERINTEGER
/ INT4INT4
INTINT
INT4INT4
别名不支持,需改为 INTINT
或 INTEGERINTEGER
BIGINTBIGINT
/ INT8INT8
BIGINTBIGINT
INT8INT8
别名不支持,需改为 BIGINTBIGINT
或 LONGLONG
REALREAL
/ FLOAT4FLOAT4
FLOATFLOAT
REALREAL
支持;FLOAT4FLOAT4
不支持,需改为 FLOATFLOAT
DOUBLE PRECISIONDOUBLE PRECISION
/ FLOAT8FLOAT8
DOUBLEDOUBLE
FLOAT8FLOAT8
不支持,需改为 DOUBLEDOUBLE
NUMERIC(p,s)NUMERIC(p,s)
/ DECIMAL(p,s)DECIMAL(p,s)
DECIMAL(p,s)DECIMAL(p,s)
直接支持 VARCHAR(n)VARCHAR(n)
VARCHAR(n)VARCHAR(n)
直接支持 CHAR(n)CHAR(n)
CHAR(n)CHAR(n)
直接支持 TEXTTEXT
STRINGSTRING
直接支持,TEXTTEXT
为别名 DATEDATE
DATEDATE
直接支持 TIMESTAMPTIMESTAMP
(无时区)TIMESTAMP_NTZTIMESTAMP_NTZ
PostgreSQL 默认 TIMESTAMP 无时区 TIMESTAMPTZTIMESTAMPTZ
TIMESTAMPTIMESTAMP
(即 TIMESTAMP_LTZTIMESTAMP_LTZ
)带时区时间戳 BOOLEANBOOLEAN
BOOLEANBOOLEAN
直接支持 BYTEABYTEA
BINARYBINARY
二进制类型,需手动替换
⚠️ PostgreSQL 的
TIMESTAMPTIMESTAMP
(无时区)应映射为
TIMESTAMP_NTZTIMESTAMP_NTZ
。直接迁移到 Lakehouse 的
TIMESTAMPTIMESTAMP
会变成带时区类型,行为不同。
Hive
Hive 类型 Lakehouse 类型 说明 TINYINTTINYINT
TINYINTTINYINT
直接支持 SMALLINTSMALLINT
SMALLINTSMALLINT
直接支持 INTINT
INTINT
直接支持 BIGINTBIGINT
BIGINTBIGINT
直接支持 FLOATFLOAT
FLOATFLOAT
直接支持 DOUBLEDOUBLE
DOUBLEDOUBLE
直接支持 DECIMAL(p,s)DECIMAL(p,s)
DECIMAL(p,s)DECIMAL(p,s)
直接支持 STRINGSTRING
STRINGSTRING
直接支持 VARCHAR(n)VARCHAR(n)
VARCHAR(n)VARCHAR(n)
直接支持 CHAR(n)CHAR(n)
CHAR(n)CHAR(n)
直接支持 DATEDATE
DATEDATE
直接支持 TIMESTAMPTIMESTAMP
TIMESTAMP_NTZTIMESTAMP_NTZ
Hive TIMESTAMP 无时区语义 BOOLEANBOOLEAN
BOOLEANBOOLEAN
直接支持 BINARYBINARY
BINARYBINARY
直接支持 ARRAY<T>ARRAY<T>
ARRAY<T>ARRAY<T>
直接支持 MAP<K,V>MAP<K,V>
MAP<K,V>MAP<K,V>
直接支持 STRUCT<...>STRUCT<...>
STRUCT<...>STRUCT<...>
直接支持
Spark SQL
Spark 类型 Lakehouse 类型 说明 BooleanTypeBooleanType
BOOLEANBOOLEAN
直接支持 ByteTypeByteType
TINYINTTINYINT
Spark Byte 对应 Lakehouse TINYINT ShortTypeShortType
SMALLINTSMALLINT
直接支持 IntegerTypeIntegerType
INTINT
直接支持 LongTypeLongType
BIGINTBIGINT
直接支持 FloatTypeFloatType
FLOATFLOAT
直接支持 DoubleTypeDoubleType
DOUBLEDOUBLE
直接支持 DecimalTypeDecimalType
DECIMAL(p,s)DECIMAL(p,s)
直接支持 StringTypeStringType
STRINGSTRING
直接支持 BinaryTypeBinaryType
BINARYBINARY
直接支持 DateTypeDateType
DATEDATE
直接支持 TimestampTypeTimestampType
TIMESTAMP_LTZTIMESTAMP_LTZ
Spark 默认带时区 TimestampNTZTypeTimestampNTZType
TIMESTAMP_NTZTIMESTAMP_NTZ
Spark 3.4+ 新增无时区类型 ArrayTypeArrayType
ARRAY<T>ARRAY<T>
直接支持 MapTypeMapType
MAP<K,V>MAP<K,V>
直接支持 StructTypeStructType
STRUCT<...>STRUCT<...>
直接支持
⚠️ Spark 的
TimestampTypeTimestampType
默认带时区,对应 Lakehouse 的
TIMESTAMP_LTZTIMESTAMP_LTZ
。若 Spark 代码中使用
TimestampNTZTypeTimestampNTZType
,应映射为
TIMESTAMP_NTZTIMESTAMP_NTZ
。
⚠️ 通过 Spark Connector 写入 Lakehouse 时,必须全字段写入,不支持部分字段写入 ;且不支持主键表(PK 表)写入 。
行为差异
类型转换失败的处理方式
场景 MySQL / PostgreSQL Spark SQL Lakehouse 默认 CAST('abc' AS INT)CAST('abc' AS INT)
报错 返回 NULLNULL
返回 NULLNULL
数值溢出(如 CAST(200 AS TINYINT)CAST(200 AS TINYINT)
) 报错 返回 NULLNULL
返回 NULLNULL
非法日期(如 CAST('2023-02-29' AS DATE)CAST('2023-02-29' AS DATE)
) 报错 返回 NULLNULL
返回 NULLNULL
Lakehouse 默认运行在宽松模式,行为与 Spark SQL 一致 :转换失败不报错,静默返回 NULL。从 MySQL/PostgreSQL 等严格模式数据库迁移时,需要在 ETL 关键节点加入显式 NULL 检查,或开启严格模式:
SET cz.sql.cast.mode = strict;
CHAR 不补空格
MySQL 和标准 SQL 的
CHAR(n)CHAR(n)
会用空格将短字符串填充至 n 位,Lakehouse 不补空格。
LENGTH(CAST('abc' AS CHAR(10)))LENGTH(CAST('abc' AS CHAR(10)))
返回
33
,不是
1010
。
比较时也按实际内容比较,
'abc' = 'abc ''abc' = 'abc '
返回
falsefalse
。
VARCHAR/CHAR 超长静默截断
超出声明长度的字符串写入时静默截断,不报错。从有严格长度校验的数据库迁移时,建议在应用层保留长度校验逻辑。
INSERT VALUES 中字符串不隐式转为日期类型
在
INSERT VALUESINSERT VALUES
中,字符串不会隐式转换为
DATEDATE
、
TIMESTAMPTIMESTAMP
、
TIMESTAMP_NTZTIMESTAMP_NTZ
,需要显式声明类型:
-- 报错
INSERT INTO t(dt) VALUES ('2024-01-15');
-- 正确
INSERT INTO t(dt) VALUES (DATE'2024-01-15');
INSERT INTO t(dt) VALUES (CAST('2024-01-15' AS DATE));
SELECTSELECT
中字符串可以隐式匹配日期列,只有
INSERT VALUESINSERT VALUES
有此限制。
NOT IN 包含 NULL
v NOT IN (1, NULL)v NOT IN (1, NULL)
在三值逻辑下永远返回
NULLNULL
(而非
truetrue
或
falsefalse
),导致过滤条件失效。这与 MySQL、PostgreSQL 和 Spark SQL 行为一致,但容易被忽略:
-- 以下查询永远返回空结果,因为子查询可能包含 NULL
SELECT * FROM t WHERE id NOT IN (SELECT id FROM other);
-- 安全写法
SELECT * FROM t WHERE NOT EXISTS (SELECT 1 FROM other WHERE other.id = t.id);
Spark SQL 兼容性说明
Spark SQL 与 Lakehouse 在类型转换行为上高度一致(宽松模式下均返回 NULL)。完整的 Spark SQL 迁移指南(含建表语法、JSON 处理、窗口函数、LATERAL VIEW、配置映射等)详见 Spark SQL 迁移指南 。
核心注意事项 :
TimestampTypeTimestampType
→ TIMESTAMP_LTZTIMESTAMP_LTZ
,TimestampNTZTypeTimestampNTZType
→ TIMESTAMP_NTZTIMESTAMP_NTZ
DataFrame 写入必须全字段,不支持 PK 表
函数兼容性良好,40+ 常用函数完全支持
不支持的别名
以下别名在其他数据库中常见,但 Lakehouse 不支持,迁移时需手动替换:
不支持的写法 替换为 来源 BOOLBOOL
BOOLEANBOOLEAN
MySQL INT2INT2
SMALLINTSMALLINT
PostgreSQL INT4INT4
INTINT
PostgreSQL INT8INT8
BIGINTBIGINT
PostgreSQL FLOAT4FLOAT4
FLOATFLOAT
PostgreSQL FLOAT8FLOAT8
DOUBLEDOUBLE
PostgreSQL NUMBER(p,s)NUMBER(p,s)
DECIMAL(p,s)DECIMAL(p,s)
Oracle DOUBLE PRECISIONDOUBLE PRECISION
DOUBLEDOUBLE
Oracle/PostgreSQL INT16INT16
SMALLINTSMALLINT
Spark INT32INT32
INTINT
Spark INT64INT64
BIGINTBIGINT
Spark FLOAT32FLOAT32
FLOATFLOAT
Spark FLOAT64FLOAT64
DOUBLEDOUBLE
Spark
相关文档