gpt4 book ai didi

postgresql - Postgresql varchar 计数使用 unicode 字符长度还是 ASCII 字符长度?

转载 作者:行者123 更新时间:2023-11-29 11:09:10 25 4
gpt4 key购买 nike

我尝试从 SQL 文件导入数据库转储,但在将字符串 Mér 插入定义为 varying(3) 的字段时插入失败。我没有捕捉到确切的错误,但它指向具有 varying(3) 约束的特定值。

鉴于我认为这对我当时所做的事情并不重要,我只是将值更改为 Mer,它起作用了,然后我继续前进。

varying 字段的限制是否考虑了字节字符串的长度?真正让我感到困惑的是,这是从另一个 PostgreSQL 数据库中转储的。因此,约束如何允许最初写入值是没有意义的。

最佳答案

varchar(N) 类型强加并由 length 函数计算的长度限制是以字符为单位,而不是以字节为单位。所以 'abcdef'::char(3) 被截断为 'abc''a€cdef'::char(3) 是被截断为 'a€c',即使在编码为 UTF-8 的数据库上下文中,其中 'a€c' 使用 5 个字节进行编码。

如果还原转储文件时提示 'Mér' 不会进入 varchar(3) 列,这表明您正在还原 UTF-8 编码的转储文件到 SQL_ASCII 数据库中。

例如,我在 UTF-8 数据库中这样做:

create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');

然后将其转储并尝试将其加载到 SQL_ASCII 数据库中:

pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest

果然:

psql:dump.sql:34: ERROR:  value too long for type character varying(3)
CONTEXT: COPY t, line 1, column key: "Mér"

相比之下,如果我将数据库 enctest 创建为 LATIN1 或 UTF8 编码,它可以正常加载。

出现此问题的原因是转储具有多字节字符编码的数据库,并试图将其恢复到 SQL_ASCII 数据库中。使用 SQL_ASCII 基本上禁用客户端数据到服务器数据的转码,并假定每个字符一个字节,让客户端负责使用正确的字符映射。由于转储文件包含存储的字符串为 UTF-8,即四个字节,因此 SQL_ASCII 数据库将其视为四个字符,因此将其视为违反约束。它打印出值,然后我的终端将其重新组合为三个字符。

关于postgresql - Postgresql varchar 计数使用 unicode 字符长度还是 ASCII 字符长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4249745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com