Краткий ответ: PostgreSQL не эквивалентен SQL Server NVARCHAR.
Типы NVARCHAR (N) в разных базах данных не эквивалентны.Стандарт допускает широкий выбор сопоставлений символов и кодировок / наборов символов.При работе с юникодом PostgreSQL и SQLServer попадают в разные лагеря и эквивалентности не существует.
Они отличаются от
- семантика длины
- представляемое содержимое
- порядок сортировки
- семантика заполнения
Таким образом, перемещение данных из одной системы БД (или кодировки / набора символов) в другую может привести к усечению / потере содержимого .
В частности, нет эквивалента между типом символов PostgreSQL (9.1) и SQL Server NVARCHAR.
Вы можете перенести данные в двоичный тип PostgreSQL, но затем потеряете возможности текстовых запросов.
(Если только PostgreSQL не начнет поддерживать набор символов Unicode на основе UTF-16)
1) Семантика длины
N интерпретируется по-разному (Символы, Байты, 2 * N = Байты) в зависимости от базы данных и кодировки.
Microsoft SQL Server использует кодировку UCS2 с длиной VARCHAR, интерпретируемой как точки UCS-2, то есть длина * 2 = длина в байтах (https://docs.microsoft.com/en-us/sql/t-sql/data-types/nchar-and-nvarchar-transact-sql?view=sql-server-2017):
их NVARCHAR (1) может хранить1 символ UCS2 (2 байта UCS2).Oracle UTF-кодировка имеет ту же семантику (и внутреннее хранилище CESU-8).
Postgres 9.1 имеет только набор символов Unicode UTF-8 (https://www.postgresql.org/docs/9.1/multibyte.html), который, как и Oracle (в кодировке AL32UTF8 или AL16UTF16), может хранить 1 полную кодовую точку UCS32. Это потенциально до 4 байтов(См., Например, http://www.oracletutorial.com/oracle-basics/oracle-nvarchar2/, в котором явно указано, что столбец NVARCHAR2 (50) может занимать до 200 байт).
Разница становится существенной, если иметь дело с символами вне базовой многоязычной плоскости, которые считаются за единицу "char unit "в utf8 ucs32 (go, char, char32_t, PostgreSQL), но представлены в UTF-16 как суррогатные пары, которые считаются двумя единицами (Java, Javascript, C #, ABAP, wchar_t, SQLServer).
например, U + 1F60A SMILING FACE SMILING EYES будет занимать все пространство в SQL Server NVARCHAR (2), но только одна единица символов в PostgreSQL.
Классические БД корпоративного уровня предложат по крайней мере выбор с UTF-16 как семантика (SAP HANA (CESU-8), DB 2 с сопоставлением, SQL Anywhere (CESU8BIN), ...) Например, Oracle также предлагает то, что они вводят в заблуждение, как UTF-8 ColLation, который эффективно CESU-8.Он имеет ту же семантику длины, представимое содержимое, что и UTF-16 (= Microsoft SQL Server), и является подходящим сопоставлением, используемым корпоративными системами на основе UTF-16 (например, SAP R / 3) или на сервере приложений Java.
Обратите внимание, что некоторые базы данных могут по-прежнему интерпретировать NVARCHAR (N) как ограничение длины в байтах, даже с кодировкой Unicode переменной длины (пример SAP IQ).
2) Непредставляемый контент
Система на основе UTF-16 / CESU-8 может представлять половину суррогатных пар, а система на основе UTF-8 / UTF-32 - нет.Это содержимое непредставимо в этом наборе символов, но часто встречается в корпоративных системах на основе UTF-16.(Например, имена путей Windows могут содержать такие не-utf-8 представимые символы, см., например, https://github.com/rust-lang/rust/issues/12056).. Таким образом, UTF-16 является «расширенным набором» UTF-8 / UTF-16, который обычно является критерием убийцы при работе сданные из корпоративных / ОС-систем, основанные на этой кодировке (SAP, Windows, Java, JavaScript). Обратите внимание, что кодировка JSON Javascript уделяла особое внимание возможности представления этих символов (https://tools.ietf.org/html/rfc8259#page-10).
(2) и (3) более актуальны для запросов на миграцию, но не для миграции данных.
3) Порядок двоичной сортировки:
Обратите внимание, что порядок двоичной сортировки CESU-8 / UTF-16 отличается от UTF-8 / UTF-32.
Порядок сортировки UTF-16 / CESU-8 / Java / JavaScript / ABAP:
U+0041 LATIN CAPITAL LETTER A
U+1F60A SMILING FACE WITH SMILING EYES
U+FB03 LATIN SMALL LIGATURE ffi
UTF-8 / UCS-32 (go) порядок сортировки:
U+0041 LATIN CAPITAL LETTER A
U+FB03 LATIN SMALL LIGATURE ffi
U+1F60A SMILING FACE WITH SMILING EYES
4) Семантика заполнения
Семантика заполнения отличается в базах данных, особенно при сравнении VARCHAR с содержанием CHAR.