UCS-2 и SQL Server - PullRequest
       92

UCS-2 и SQL Server

5 голосов
/ 25 января 2012

В то время как исследует варианты для хранения в основном данных на английском языке, но иногда не в базе данных SQL Server, которая может быть довольно большой, я склоняюсь к хранению большинства строковых данных в кодировке UTF-8.

Однако Microsoft выбрала UCS-2 по причинам, которые я не до конца понимаю, что заставляет меня переоценить эту склонность.Документация по SQL Server 2012 действительно показывает, как создать UTF-8 UDT , но решение для UCS-2, вероятно, распространяется на SQL Server.

Википедия (котораяинтересно отметить, что UCS-2 устарел в пользу UTF-16) отмечает, что UTF-8 является набором символов переменной ширины, способным кодировать любую точку данных Unicode и что она provides the de facto standard encoding for interchange of Unicode text.Таким образом, создается впечатление, что любой символ Unicode может быть представлен в UTF-8, и, поскольку большая часть текста будет английской, представление будет почти в два раза компактнее, чем в UCS-2 (я знаю, что диск «дешевый», но кэш диска неи память не сравнится с размерами данных, с которыми я имею дело. Многие операции экспоненциально ухудшаются, когда рабочий набор больше доступной оперативной памяти).

С какими проблемами я могу столкнуться, переплывПоток UCS-2?

Ответы [ 2 ]

11 голосов
/ 30 сентября 2015

Хранение в основном данных на английском языке, но иногда не в базе данных SQL Server, которая потенциально может быть довольно большой, я склоняюсь к хранению большинства строковых данных в кодировке UTF-8.

В отличие от некоторых других СУБД, которые позволяют выбирать кодировку, SQL Server хранит данные Unicode только в UTF-16 (Little Endian) и данные не в Юникоде в 8-битной кодировке (Extended ASCII, DBCS или EBCDIC) для любой кодовой страницы, подразумеваемой сопоставлением поля.

Microsoft выбрала UCS-2 по причинам, которые я не до конца понимаю

Их решение выбрать UCS-2 имеет смысл, учитывая, что UTF-16 был введен в середине 1996 года и полностью определен в 2000 году. Многие другие системы также используют (или используют) его ( смотрите: https://en.wikipedia.org/wiki/UTF-16#Usage). Их решение продолжить с этим может быть более сомнительным, хотя, вероятно, это связано с тем, что Windows и .NET являются UTF-16. Физическая структура байтов такая же между UCS-2 и UTF-16, поэтому обновление систем с UCS-2 для поддержки UTF-16 должно быть чисто функциональным без необходимости изменять какие-либо существующие данные.

В документации по SQL Server 2012 показано, как создать UTT-UTF-8,

Хм, нет. Создание пользовательского пользовательского типа через SQLCLR - это , а не , в любом случае, вы получите замену любого собственного типа. Это очень удобно для создания чего-то для обработки специализированных данных. Но строки, даже другой кодировки, далеко не специализированы. Путь по этому маршруту для ваших строковых данных разрушит любое удобство использования вашей системы, не говоря уже о производительности, поскольку вы не сможете использовать любые встроенные строковые функции. Если бы вы смогли сохранить что-либо на диске, эти выгоды будут стерты с того, что вы потеряете в общей производительности. Хранение UDT выполняется путем сериализации его в VARBINARY. Таким образом, чтобы выполнить любое сравнение строк ИЛИ сортировку вне «двоичного» / «порядкового» сравнения, вам придется преобразовать все остальные значения, одно за другим, обратно в UTF-8, чтобы затем выполнить сравнение строк, которое может учитывать языковые различия.

Кроме того, эта «документация» - это всего лишь пример кода / доказательства концепции. Код был написан в 2003 году (http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/CS/UTF8String/Utf8String.cs) для SQL Server 2005. Я видел скрипт для проверки работоспособности, но ничего не касалось производительности.

но решение для UCS-2, вероятно, распространяется на SQL Server.

Да, очень сильно. По умолчанию обработка встроенных функций только для UCS-2. Но начиная с SQL Server 2012, вы можете заставить их обрабатывать полный набор символов UTF-16 (ну, начиная с Unicode версии 5 или 6, в зависимости от вашей ОС и версии .NET Framework), используя одно из сопоставлений, которые имеет имя, оканчивающееся на _SC (т.е. дополнительные символы).

Википедия ... отмечает, что UCS-2 устарела в пользу UTF-16

Правильно. UTF-16 и UCS-2 используют 2-байтовые кодовые точки. Но UTF-16 использует некоторые из них в парах (например, суррогатные пары) для сопоставления дополнительных символов. Кодовые точки, используемые для этих пар, зарезервированы для этой цели в UCS-2 и, следовательно, не используются для сопоставления с любыми используемыми символами. Вот почему вы можете хранить любой символ Unicode в SQL Server, и он будет сохранен и получен правильно.

Википедия ... отмечает, что UTF-8 - это набор символов переменной ширины, способный кодировать любую точку данных Unicode

Правильно, хотя и вводит в заблуждение.Да, UTF-8 имеет переменную ширину, но UTF-16 также является незначительно переменным, поскольку все дополнительные символы состоят из двух двухбайтовых кодовых точек.Следовательно, UTF-16 использует 2 или 4 байта на символ, хотя UCS-2 всегда составляет 2 байта.Но это не обманчивая часть.Вводит в заблуждение то, что любая другая кодировка Unicode не способна кодировать все остальные кодовые точки.Хотя UCS-2 может удерживать их, но не интерпретировать их, как UTF-16, так и UTF-32 могут отображать все кодовые точки Unicode, точно так же, как UTF-8.

и то, что он [ed: UTF-8] обеспечивает де-факто стандартную кодировку для обмена текстом Unicode.

Это может быть правдой, но это совершенно неактуально с операционной точки зрения.

это кажетсякак любой символ Unicode может быть представлен в UTF-8

Опять-таки, true, но совершенно не имеет значения, поскольку UTF-16 и UTF-32 также отображают все кодовые точки Unicode.

так как большая часть текста будет на английском языке, представление будет почти в два раза компактнее, чем с UCS-2

В зависимости от обстоятельств это вполне может быть правдой, и вы правы, если будете беспокоиться о такой расточительностииспользование.Однако, как я уже упоминал в вопросе, который приводит к этому (поддержка UTF-8, SQL Server 2012 и UTF8String UDT ), у вас есть несколько вариантов уменьшения количества неиспользуемого пространства, если большинство строк можетвписывается в VARCHAR, но некоторые должны быть NVARCHAR.Наилучший вариант - включить сжатие строк или сжатие страниц (только для Enterprise Editon!).Начиная с SQL Server 2008 R2, они позволяют полям, не относящимся к MAX NVARCHAR, использовать «Стандартную схему сжатия для Unicode», которая по крайней мере так же хороша, как UTF-8, а в некоторых случаях даже лучше, чем UTF-8.NVARCHAR(MAX) поля не могут использовать это необычное сжатие , но их данные IN ROW могут выиграть от обычного сжатия ROW и / или PAGE.Ниже приведено описание этого сжатия и таблица сравнения размеров данных для: raw UCS-2 / UTF-16, UTF-8 и UCS-2 / UTF-16 с включенным сжатием данных.

SQL Server 2008 R2 - Сжатие UCS2, что это такое - Влияние на системы SAP

Также см. Страницу MSDN для Сжатие данных для получения более подробной информации, поскольку существуют некоторые ограничения(помимо того, что оно доступно только в Enterprise Edition - НО доступно для всех выпусков, начиная с SQL Server 2016, SP1 !!) и некоторых обстоятельствах, когда сжатие может ухудшить ситуацию.

Я знаю, что диск «дешевый»

Достоверность этого утверждения зависит от того, как определяется «диск».Если вы говорите с точки зрения товарных частей, которые вы можете приобрести с полки в магазине для использования на вашем настольном компьютере / ноутбуке, то обязательно.Но если говорить с точки зрения хранилища на уровне предприятия, которое будет использоваться для ваших производственных систем, то получайте удовольствие, объясняя всем, кто контролирует бюджет, что они не должны отклонять SAN на миллион плюс доллар, который вам нужен, потому что это «дешево»."; -).

С какими проблемами я мог бы столкнуться, плывя по потоку UCS-2?

Ни о чем я не могу думать.Ну, до тех пор, пока вы не последуете каким-либо ужасным советам сделать что-то вроде реализации этого UDT или преобразования всех строк в VARBINARY или использования NVARCHAR(MAX) для всех строковых полей ;-).Но из всех вещей, о которых вы могли бы беспокоиться, SQL Server, использующий UCS-2 / UTF-16, не должен быть одним из них.

Но, если по какой-то причине эта проблема отсутствия встроенной поддержки UTF-8 является очень важной, вам может понадобиться найти другую СУБД, которая будет использовать UTF-8.


ОБНОВЛЕНИЕ 2018-10-02

Хотя этот вариант пока не подходит, в SQL Server 2019 появилась встроенная поддержка UTF-8 в типах данных VARCHAR / CHAR. В настоящее время в нем слишком много ошибок, чтобы его можно было использовать, но если они исправлены, то это вариант для некоторых сценариев. Пожалуйста, смотрите мой пост " Собственная поддержка UTF-8 в SQL Server 2019: Спаситель или Лжепророк? " для подробного анализа этой новой функции.

0 голосов
/ 26 января 2012

Что вы подразумеваете под "плаванием вверх по течению UCS-2"?

Вот ваши варианты:

  • Используйте новые сопоставления 2012 _SC (https://msdn.microsoft.com/en-us/library/ms143726.aspx). Эта идея исходит от srutzky. Вы должны проверить его ответ. Это, безусловно, лучшее решение.

Не рекомендуется, но возможно:

  • Реализация UDT. Это будет много работы, и вы потеряете толлинговую поддержку (OR сопоставления и, конечно, некоторые функции SQL Server, которые работают на нативных типах).
  • Использовать varbinary (max): требуется, чтобы вы выполняли пользовательский код преобразования. Нет индексации диапазона.
  • Используйте nvarchar (N) и включите сжатие строк. Начиная с SQL Server 2008 R2, он будет использовать такую ​​же компактную кодировку, как UTF-8. Но для этого требуется корпоративная версия.

См. Комментарии к серьезным недостаткам этих подходов.

...