2. Trino 内存 catalog 建表与数据类型映射

Trino 内存 catalog 建表与数据类型映射 学习卡片

memory connector 的定位与建表边界

memory connector 把表结构和数据全部保存在 coordinator 的 JVM 堆内存中,进程重启即丢失,因此它适合做类型验证、SQL 语法试验和临时数据中转,不适合承载持久化业务数据。在 Trino 中它通过 memory catalog 暴露,默认 schema 为 default。建表时 Trino 会把 SQL 类型映射到 memory connector 内部支持的 Java 类型,映射不上的类型会在建表阶段直接报错,而不是等到插入数据才失败。

memory catalog 建表与类型映射链路 SQL 类型声明 BOOLEAN TINYINT / SMALLINT INTEGER / BIGINT REAL / DOUBLE DECIMAL(p,s) VARCHAR(n) CHAR(n) DATE TIME / TIME(p) TIMESTAMP TIMESTAMP WITH TZ ARRAY<T> MAP<K,V> ROW(...) memory 类型映射 标量类型 → Java 原生/包装类型 DECIMAL(p,s) → BigDecimal DATE / TIME / TS → 长整型毫秒/天 ARRAY / MAP / ROW → 嵌套 Block 不支持类型 建表即报错 查询显示与转换行为 TINYINT 显示为整数 插入 127 正常,128 溢出报错 DECIMAL(5,2) 保留两位 123.456 → 123.46(四舍五入) TIMESTAMP 无时区 WITH TZ 显示带 +08:00 偏移 ARRAY/MAP 显示为 [..]/{..} 元素类型需与声明一致

创建类型覆盖表

下面在 memory.default 下建一张覆盖常用类型的表。注意 TIMESTAMP WITH TIME ZONE 在 memory connector 中可正常建表,但显示时会带上会话时区偏移;VARBINARY 也受支持,这里用 VARCHAR 代替以保持可读性。

CREATE TABLE memory.default.type_demo (
    id            INTEGER,
    flag          BOOLEAN,
    tiny_val      TINYINT,
    small_val     SMALLINT,
    big_val       BIGINT,
    real_val      REAL,
    double_val    DOUBLE,
    price         DECIMAL(5,2),
    name          VARCHAR(20),
    fixed_code    CHAR(4),
    birth_date    DATE,
    log_time      TIME,
    created_at    TIMESTAMP,
    tz_time       TIMESTAMP WITH TIME ZONE,
    tags          ARRAY(VARCHAR),
    attrs         MAP(VARCHAR, INTEGER),
    addr          ROW(city VARCHAR, zip VARCHAR)
);

执行后可用 DESCRIBE memory.default.type_demo; 核对列类型。若某列类型不被支持,建表语句会直接失败并提示类型不兼容,此时应改用受支持类型或换用其他 connector。

插入样例数据并观察显示

插入一行覆盖各类型的样例数据,其中 DECIMAL(5,2) 故意给三位小数,用于观察舍入;TIMESTAMP WITH TIME ZONE 使用带偏移的字面量。

INSERT INTO memory.default.type_demo VALUES (
    1,
    true,
    127,
    32000,
    9000000000,
    1.5,
    3.1415926,
    123.456,
    'Trino',
    'AB',
    DATE '2024-03-15',
    TIME '14:30:00',
    TIMESTAMP '2024-03-15 14:30:00',
    TIMESTAMP '2024-03-15 14:30:00 +08:00',
    ARRAY['a', 'b', 'c'],
    MAP(ARRAY['x', 'y'], ARRAY[10, 20]),
    ROW('Beijing', '100000')
);

查询并观察各列显示:

SELECT * FROM memory.default.type_demo;

预期现象:tiny_val 显示 127;price 显示 123.46(四舍五入到两位);fixed_code 显示 'AB'(CHAR 定长,尾部空格在显示时可能被保留或补齐,取决于客户端);tz_time 显示带 +08:00 偏移;tags 显示为 [a, b, c];attrs 显示为 {x=10, y=20};addr 显示为 {city=Beijing, zip=100000}。

类型转换与边界验证

用几个查询验证类型转换行为,这些是 memory connector 上最容易踩坑的点:

  • SELECT CAST(128 AS TINYINT); 会报溢出错误,因为 TINYINT 范围是 -128~127。
  • SELECT CAST('123.456' AS DECIMAL(5,2)); 返回 123.46,验证舍入规则。
  • SELECT CAST(123.456 AS DECIMAL(5,2)); 同样返回 123.46。
  • SELECT typeof(tags), typeof(attrs), typeof(addr) FROM memory.default.type_demo; 返回 array(varchar)、map(varchar, integer)、row(city varchar, zip varchar),确认嵌套类型被正确识别。
  • SELECT element_at(attrs, 'x'), tags[1], addr.city FROM memory.default.type_demo; 验证嵌套类型访问语法。
memory connector 的数据不持久化,Trino 重启后表和行都会消失。若需要保留验证结果,应把建表和插入语句保存为脚本,或改用 Hive/Iceberg 等持久化 connector。

常见问题与排查

现象可能原因处理方式
建表报类型不支持使用了 memory connector 未映射的类型改用受支持类型,或换 connector
插入 TINYINT 报溢出值超出 -128~127改用 SMALLINT/INTEGER,或修正数据
DECIMAL 显示位数与插入不同按声明精度四舍五入调整 DECIMAL(p,s) 的 s
TIMESTAMP WITH TZ 显示偏移与预期不同会话时区影响显示用 AT TIME ZONE 显式转换
重启后表不存在memory 数据在堆内存,不持久化重新执行建表与插入脚本