处理文本长度时,很多人最常见的困惑就是:听说中文要占 3 个字节?那英文单词怎么算的?Oracle 的 VARCHAR2 好像给的挺大,但貌似还没存那么多就报错长度不够存了?
其实,关键就在于要先区分清楚三种不同的"长度"代表的含义。
01 | Unicode 码位数
三种长度,含义有所不同,其中 Unicode 码位数最好理解,直接是按字符逐个计数的方式。
对常见的中文、ASCII 英文字母、空格、换行、标点和单个 而言,通常各算 1 个 Unicode 码位。不像 UTF-8 字节数还需要稍微换算下。
笔者注:"肉眼看到的一个字符"不一定只包含一个码位,例如组合字符和部分 emoji 序列。
| 内容 | Unicode 码位数 | UTF-8 字节数 |
|---|---|---|
| 中 | 1 | 3 |
| A | 1 | 1 |
| hello | 5 | 5 |
| 你好 | 2 | 6 |
| 1 | 4 |
因此,英文"单词"没有固定长度,要看里面实际包含多少字符:
hello= 5don't= 5e-mail= 6AI2026= 6
02 | UTF-8 字节数为何不同
UTF-8 是一种编码方式,它决定字符存储时占多少字节。常见情况下,ASCII 英文字符占 1 字节,中文通常占 3 字节, 通常占 4 字节。
所以"一个中文占 3 个"说的通常是 UTF-8 字节数,并不是 Unicode 码位数。你好 有 2 个码位,但存成 UTF-8 通常需要 6 字节。
03 | Oracle VARCHAR2 要看 CHAR 还是 BYTE
Oracle 的长度规则还取决于列定义和数据库字符集。数据库字符集为 AL32UTF8 时,中文通常占 3 字节,但以下两种定义含义不同:
VARCHAR2(6000 CHAR):最多 6,000 个字符VARCHAR2(6000 BYTE):最多 6,000 个字节
前者关注字符数量,后者关注存储字节数,不能混为一谈,如果创建字段类型时,如果未显式指定 CHAR 或 BYTE,很多环境默认是 BYTE,但不要依赖默认值,建表时应明确写出语义,这也是很多人会踩坑的地方。
此外,VARCHAR2(6000 CHAR) 表示最多 6,000 个字符语义上的字符;但它仍受 VARCHAR2 的绝对字节上限限制。MAX_STRING_SIZE = STANDARD 时上限为 4000 字节,EXTENDED 时为 32767 字节。因此在 AL32UTF8 中,想稳定容纳 6000 个中文,通常需要 MAX_STRING_SIZE = EXTENDED;否则应使用 CLOB。
一个很实用的 Oracle 自检 SQL:
SELECT LENGTH(col) AS char_count,
LENGTHB(col) AS byte_count
FROM your_table;
04 | 应用层截断又是另一件事
Python 中的 text[:6000] 按 Unicode 码位截取:6,000 个中文大致可达到 18,000 个 UTF-8 字节;6,000 个 ASCII 英文字符约为 6,000 字节;中英文混合则介于两者之间。
因此,这类 6,000 限制是应用层控制传给模型内容规模的规则,不等同于 Oracle VARCHAR2 限制,也不是 UTF-8 字节限制。
关注我,和AI一起成长~