PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Zählt Postgresql varchar mit Unicode-Zeichenlänge oder ASCII-Zeichenlänge?

Die von varchar(N) auferlegte Längenbegrenzung Typen und berechnet durch die length Funktion ist in Zeichen, nicht in Bytes. Also 'abcdef'::char(3) wird auf 'abc' gekürzt sondern 'a€cdef'::char(3) wird zu 'a€c' gekürzt , sogar im Kontext einer als UTF-8 codierten Datenbank, wobei 'a€c' wird mit 5 Bytes kodiert.

Beim Wiederherstellen einer Dump-Datei beschwerte sich 'Mér' würde nicht in ein varchar(3) gehen Spalte, was darauf hindeutet, dass Sie eine UTF-8-codierte Dump-Datei in einer SQL_ASCII-Datenbank wiederhergestellt haben.

Zum Beispiel habe ich das in einer UTF-8-Datenbank gemacht:

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

Und dann habe ich das ausgegeben und versucht, es in eine SQL_ASCII-Datenbank zu laden:

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

Und tatsächlich:

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

Wenn ich dagegen die Datenbank enctest als Codierung LATIN1 oder UTF8 erstelle, wird sie einwandfrei geladen.

Dieses Problem entsteht durch eine Kombination aus dem Sichern einer Datenbank mit einer Mehrbyte-Zeichencodierung und dem Versuch, sie in einer SQL_ASCII-Datenbank wiederherzustellen. Die Verwendung von SQL_ASCII deaktiviert grundsätzlich die Transcodierung von Clientdaten in Serverdaten und geht von einem Byte pro Zeichen aus, sodass es den Clients überlassen bleibt, die Verantwortung für die Verwendung der richtigen Zeichentabelle zu übernehmen. Da die Dump-Datei die gespeicherte Zeichenfolge als UTF-8 enthält, also vier Bytes, sieht eine SQL_ASCII-Datenbank dies als vier Zeichen und betrachtet sie daher als Verstoß gegen die Einschränkung. Und es druckt den Wert aus, den mein Terminal dann wieder zu drei Zeichen zusammensetzt.