sql >> Databáze >  >> RDS >> PostgreSQL

Počítá se Postgresql varchar pomocí délky znaků Unicode nebo délky znaků ASCII?

Limit délky stanovený pomocí varchar(N) typů a počítá se podle length funkce je ve znacích, ne v bajtech. Takže 'abcdef'::char(3) je zkrácen na 'abc' ale 'a€cdef'::char(3) je zkrácen na 'a€c' , a to i v kontextu databáze kódované jako UTF-8, kde 'a€c' je zakódováno pomocí 5 bajtů.

Pokud se při obnově souboru výpisu objevila stížnost, že 'Mér' nepřejde do varchar(3) sloupec, což naznačuje, že jste obnovovali soubor výpisu s kódováním UTF-8 do databáze SQL_ASCII.

Například jsem to udělal v databázi UTF-8:

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

A pak to vyhodil a pokusil se to načíst do databáze SQL_ASCII:

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

A jistě:

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

Naproti tomu, pokud vytvořím databázi enctest jako kódování LATIN1 nebo UTF8, načte se dobře.

K tomuto problému dochází v důsledku kombinace dumpingu databáze s vícebajtovým kódováním znaků a pokusu o její obnovení do databáze SQL_ASCII. Použití SQL_ASCII v podstatě zakáže překódování klientských dat na data serveru a předpokládá jeden bajt na znak, přičemž odpovědnost za použití správné mapy znaků ponechává na klientech. Protože soubor výpisu obsahuje uložený řetězec jako UTF-8, tedy čtyři bajty, databáze SQL_ASCII to vidí jako čtyři znaky, a proto to považuje za porušení omezení. A vypíše hodnotu, kterou pak můj terminál znovu sestaví jako tři znaky.



  1. Jak přidám podmínky do podřízených podřízených modelů v sequelize, které by měly ovlivnit můj nadřazený model v findAndCountAll?

  2. Jak získat záznamy mezi 2 daty v MySQL

  3. mysql vyberte nejnižší cenu z více výběrů

  4. Změňte hodnoty NULL ve formátu Datetime na prázdný řetězec