char长度单位必须明确指定,KingbaseES默认按字符计数,支持char(10 char)或char(10 byte)显式声明;其定长特性会自动补空格,导致比对异常,需统一rtrim或改用varchar。

char 类型看似简单,但用错地方很容易引发存储浪费、查询不准、中英文混排错位等问题。关键不在“能不能存”,而在“按什么单位算长度”和“怎么应对多语言环境”。
char 的长度单位必须明确指定
定义 char(10) 时,数据库默认按字节还是字符?不同系统差异很大。KingbaseES 允许显式声明 char(10 char) 或 char(10 byte),这是避免踩坑的第一步。
- 选 char:一个中文通常占 3 字节(UTF-8),那么 char(4 byte) 只能存 1 个中文或 4 个英文,超长就报错
- 选 char:不管中英文,都按“字符个数”计数,“一二三四”刚好 4 个字符,符合直觉
- 建表时不写单位,依赖数据库默认行为——KingbaseES 默认按字符,但 PostgreSQL 默认按字节,迁移时极易出错
定长特性带来隐性问题
char 类型会自动补空格到指定长度,读取时多数客户端/驱动默认不 trim,导致比对失败或显示异常。
- 插入 'abc' 到 char(5),实际存的是 'abc '(两个空格)
- 用 WHERE col = 'abc' 查询可能查不到,因为实际值带空格
- 应用层需统一处理 rtrim(),或改用 varchar 配合约束(如 CHECK(length(col)
国际化场景下慎用 char
当字段要支持中、日、韩、阿拉伯、emoji 等混合内容时,char 的固定长度机制更难掌控。
- emoji 通常占 4 字节(UTF-8),一个 ? 在 char(4 byte) 里直接存不下
- 某些越南文、阿拉伯文连字在渲染时宽度不等,但 char 只管存储长度,不管显示宽度
- 若业务要求严格对齐(如导出固定宽文本报表),可用 char + rtrim,但需在应用层统一清洗
替代方案更实用
绝大多数场景,varchar 是比 char 更安全、更灵活的选择。
- varchar(50) 存 '张三' 占 6 字节(UTF-8),存 'John' 占 4 字节,省空间也省心
- 配合 CHECK 约束可模拟定长语义,例如:CHECK(length(name) BETWEEN 2 AND 20)
- 需要前缀索引或全文检索时,varchar 支持更完善,char 在部分版本中存在隐式转换风险

















