Redshift DDL导出时NVARCHAR/NCHAR转为VARCHAR/CHAR问题咨询
Redshift导出DDL时NVARCHAR/NCHAR自动转换为VARCHAR/CHAR的问题解答
类型转换的核心原因
- Redshift官方将
NVARCHAR、NCHAR定义为VARCHAR、CHAR的别名,底层存储均为UTF-8编码的字符类型,系统视图、官方SHOW TABLE命令的默认输出逻辑会直接返回底层原生类型,因此会自动替换别名类型。 - 第三方工具(Aginity、Workbench/J等)的Redshift驱动默认配置了类型映射规则,会将识别到的别名类型统一转换为原生的VARCHAR/CHAR输出。
保留NVARCHAR/NCHAR类型的导出方案
自定义查询系统表拼接DDL
直接查询Redshift系统表自行拼接建表语句,跳过官方视图、工具的自动类型转换逻辑,示例查询如下:
SELECT n.nspname AS schema_name, c.relname AS table_name, 'CREATE TABLE ' || n.nspname || '.' || c.relname || ' (' || string_agg( a.attname || ' ' || CASE t.typname WHEN 'nvarchar' THEN 'NVARCHAR(' || (a.atttypmod - 4) || ')' WHEN 'nchar' THEN 'NCHAR(' || (a.atttypmod - 4) || ')' WHEN 'varchar' THEN 'VARCHAR(' || (a.atttypmod - 4) || ')' WHEN 'char' THEN 'CHAR(' || (a.atttypmod - 4) || ')' ELSE t.typname END || CASE WHEN a.attnotnull THEN ' NOT NULL' ELSE '' END, ', ' ORDER BY a.attnum ) || ');' AS create_table_ddl FROM pg_namespace n JOIN pg_class c ON n.oid = c.relnamespace JOIN pg_attribute a ON c.oid = a.attrelid JOIN pg_type t ON a.atttypid = t.oid WHERE n.nspname NOT IN ('pg_catalog', 'information_schema') AND c.relkind = 'r' -- 仅查询普通表,可按需调整为视图、外部表等类型 AND a.attnum > 0 AND NOT a.attisdropped GROUP BY n.nspname, c.relname ORDER BY n.nspname, c.relname;
该查询会直接返回对应表的完整建表语句,保留原始声明的NVARCHAR/NCHAR类型,支持全量批量导出。
自定义修改
v_generate_tbl_ddl视图
导出官方自带v_generate_tbl_ddl视图的原有定义,修改其中的类型判断分支,删除NVARCHAR、NCHAR转VARCHAR、CHAR的转换逻辑,直接输出原始类型名,后续使用自定义后的视图导出DDL即可。
兼容替代方案
如果不需要严格保留类型名称,仅需避免双字节字符加载报错,可以在导出的VARCHAR/CHAR类型后添加CHAR关键字,例如将VARCHAR(100)修改为VARCHAR(100 CHAR),该写法的长度计数规则和NVARCHAR(100)完全一致,同样支持日文等双字节字符的存储和S3数据加载,不会触发长度溢出报错。
内容的提问来源于stack exchange,提问作者Sachiko
相关产品推荐
相关产品推荐

