Как я могу хранить символы UTF-16 в базе данных Postgres? - PullRequest
1 голос
/ 09 декабря 2011

Я пытаюсь сохранить некоторый текст (например, č) в базе данных Postgres, однако при получении этого значения оно отображается на экране как ?.Я не уверен, почему это происходит, у меня сложилось впечатление, что это был персонаж, который не был поддержан в UTF-8, но был в UTF-8, однако, судя по первому ответу, это неверное предположение.

Оригинальный вопрос (который все еще может быть действительным):

Я читал о суррогатных парах UTF-8, которые могут достичь того, что мне нужно, и я видел несколькопримеры, включающие stringinfo объект TextElementEnumerators, но я не смог найти практического подтверждения концепции.

Может кто-нибудь привести пример того, как вы будете писать и читать UTF-16 (возможно, с использованием этого суррогата)концепция пары) в базу данных postgres.Спасибо.

Обновленный вопрос: почему символ č возвращается из базы данных в виде знака вопроса?

Мы используем NPGSQL для доступа к базе данных и VB.Net.

Ответы [ 3 ]

5 голосов
/ 09 декабря 2011

Нет такой вещи, как персонаж, который существует в UTF-16, но не в UTF-8. Оба способны кодировать все Unicode. Другими словами, если вы можете заставить UTF-8 работать, он должен иметь возможность хранить любой допустимый текст Unicode.

РЕДАКТИРОВАТЬ: Суррогатные пары фактически являются функцией UTF-16, а не UTF-8. Они позволяют символу, который не находится в основной многоязычной плоскости (BMP), быть представленными как две кодовые единицы UTF-16. По сути, UTF-16 часто рассматривается как кодирование с фиксированной шириной (ровно два байта на символ Unicode), но это позволяет только правильно кодировать BMP. Суррогатные пары (довольно хакерский) способ расширить диапазон за пределы BMP.

Я очень сомневаюсь, что персонаж, которого вы пытаетесь изобразить, находится за пределами BMP, поэтому я подозреваю, что вам нужно искать проблему в другом месте. В частности, стоит сбросить точные символьные значения текста (например, приведя каждое значение char к int) до того, как оно попадет в базу данных и после того, как вы его загрузите. В идеале, делайте это в коротком, но полном консольном приложении.

1 голос
/ 15 декабря 2018

Как я могу сохранить все "символы" UTF-16 в базе данных Postgres?

Краткий ответ, это невозможно напрямую, поскольку PostgreSQL поддерживает только набор символов UTF-8.

Форматы на основе UTF-16, такие как Java, JavaScript, Windows, могут содержать половинные суррогатные пары, которые не представлены в UTF-8 или UTF-32. Они могут быть легко созданы путем подстроки строки Java, JavaScript, VB.Net. Поскольку они не могут быть представлены в UTF-8 или UTF-32 и, следовательно, не могут быть сохранены в базе данных, которая поддерживает только набор символов UTF-8, такой как PostgreSQL.

Имена путей Windows могут содержать половину суррогатных пар, которые не могут быть прочитаны как utf-8 (https://github.com/rust-lang/rust/issues/12056).

Можно использовать систему баз данных, которая поддерживает набор символов UTF-16 / CESU-8, который более адаптирован к Java / Android, JavaScript / NodeJS, .Net / wchar_t / языкам / платформам Windows. (SQLServer, Oracle (сопоставление UTF-8), DB2, Informix, HANA, SQL Anywhere, MaxDB обычно поддерживают такую ​​кодировку.

Обратите внимание, что при использовании смайликов в виде кодовых точек Юникода вне Базовой многоязычной плоскости эти различия станут более актуальными и для западных пользователей.

На postgres вы можете: а) принять потери, б) хранить данные в виде двоичных данных или же в) перевести их на закодированное представление (например, код JSON rfc кодирует их как два экранированных символа, чтобы иметь возможность передавать половину суррогатов в сетевом формате на основе UTF-8 / Ascii без потерь (https://tools.ietf.org/html/rfc4627 Раздел 2.5).

Например, Смайлики, находящиеся вне Базового многоязычного плана, эта проблема станет более актуальной и в западном мире.

В зависимости от выбора языка сервера приложений (Java, Scala, C # / Windows, JavaScript / NodeJS) и уровня инвестиций в языковую поддержку (с использованием, например, функций разделения строк ICU на границах графемы (* 1024) * вместо простого усечения проблема может быть менее актуальной, но большинство корпоративных систем и языков попадают в лагерь UTF-16 сегодня, когда программное обеспечение использует простые операции с подстрокой.

0 голосов
/ 15 декабря 2018

Что касается проблемы сохранения / извлечения č

  1. Проверьте набор символов, на котором работает Postgre db, набор символов UTF-8 (https://www.postgresql.org/docs/9.1/multibyte.html) или символнабор, который может представлять символ.

  2. Убедитесь, что соединение клиента с базой данных настроено для выполнения соответствующего преобразования кодовой страницы (для VB.Net это будет от UTF-16LE до UTF-8 или кодировка базы данных, обычно это параметр в строке подключения (кодировка).

  3. Проверьте, что вход является фактическим UTF-8 / UTF-16 в VB.последовательность байтов сети, а не последовательность байтов Windows-1250.

  4. Убедитесь, что это не просто ограничение инструмента вывода или консоли (например, консоль Windows обычно не отображает символы Юникода, но использует набор символов Windows-12xx (можно попробовать * 1019)*https://superuser.com/questions/269818/change-default-code-page-of-windows-console-to-utf-8), но обычно лучше проверять последовательность байтов в отладчике VB.Net.

  5. Убедитесь, что длина столбца CHAR / VARCHAR достаточна для хранения вашего представления, даже еслипредставлены в разложении NFKD.

Указанная вами графема имеет несколько различных представлений Unicode.

 U+010D LATIN SMALL LETTER C WITH CARON
 U+0063 LATIN SMALL LETTER c followed by U+030C COMBINING CARON

И другие представления других наборов символов (например, 0xE8 в ISO-8859-2 / Windows-1250 (https://en.wikipedia.org/wiki/Windows-1250) или ISO-8859-13 /Windows-1257.

Все представления Unicode попадают в базовую многоязычную плоскость, поэтому суррогатная проблема UTF-16 с postgre asуказанный в названии вопроса и отвеченный ниже, скорее всего, не имеет отношения к вашей проблеме.

...