Вопрос

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

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

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

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

Это было полезно?

Решение

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

В отличие от некоторых других СУБД, которые позволяют выбирать кодировку, SQL Server хранит данные в формате Unicode. только в UTF-16 (Little Endian) и данные, отличные от Unicode, в 8-битной кодировке (расширенный 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 показано, как создать UDT 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 и, следовательно, не используются для сопоставления с какими-либо пригодными для использования символами.Вот почему вы можете сохранить любой символ Юникода в 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.

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

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

такое ощущение, что любой символ Юникода может быть представлен в UTF-8

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

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

В зависимости от обстоятельств это вполне может быть правдой, и вы правы, беспокоясь о таком расточительном использовании.Однако, как я уже упоминал в вопросе, который привел к этому ( Поддержка UTF-8, SQL Server 2012 и UDT UTF8String. ), у вас есть несколько вариантов уменьшить потерю пространства, если большинство строк могут поместиться в VARCHAR все же некоторые должны быть NVARCHAR.Лучший вариант — включить СЖАТИЕ СТРОК или СЖАТИЕ СТРАНИЦ (только для Enterprise Edition!).Начиная с SQL Server 2008 R2, они допускают не-MAX NVARCHAR поля использовать «Стандартную схему сжатия для Unicode», которая по крайней мере так же хороша, как UTF-8, а в некоторых случаях даже лучше, чем UTF-8. NVARCHAR(MAX) поля не могут использовать это необычное сжатие, но их данные IN ROW могут выиграть от обычного сжатия ROW и/или PAGE.Ниже приведено описание этого сжатия и таблица сравнения размеров данных для:необработанные 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:Спаситель или лжепророк?", для подробного анализа этой новой функции.

Другие советы

Что вы подразумеваете под «плаванием по потоку UCS-2»?

Вот ваши опции:

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

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

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

      См. Комментарии к чтению о тяжелых недостатках, которые имеют эти подходы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top