В SQL Server 2019 Microsoft вводит поддержку UTF-8 для CHAR
и VARCHAR
типов данных и говорит:
Эта функция может обеспечить значительную экономию памяти в зависимости от используемого набора символов. Например, изменение существующего типа данных столбца со строками ASCII с NCHAR (10) на CHAR (10) с использованием сортировки с поддержкой UTF-8 приводит к почти 50% снижению требований к хранилищу. Это сокращение вызвано тем, что NCHAR (10) требует 22 байта для хранения, тогда как CHAR (10) требует 12 байтов для той же строки Unicode.
UTF-8 поддерживает все сценарии, поэтому мы можем начать хранить данные Unicode в столбцах varchar
и char
столбцах. И, как сказано в документации, это может уменьшить размер таблиц и индексов, и оттуда мы можем получить еще лучшую производительность, поскольку считывается меньшее количество данных.
Мне интересно , это значит , мы можем прекратить использовать nvarchar
и nchar
столбцы , который реализует UTF-16?
Кто-нибудь может указать сценарий и причину, чтобы не использовать типы данных char с UTF
кодировкой и продолжать использовать n-chars?
CHAR
типы UTF-8, чем типы Unicode (со сжатием или без, так как в конечном итоге данные должны быть сжаты для обработки). Также учтите, что собственный тип строки Windows - это Unicode, поэтому строки UTF-8 часто необходимо декодировать. Компромиссы означают, что маловероятно, чтоN
типы будут удалены в ближайшее время.CHAR
, вероятно, является SQL Server в Linux, если движок получает встроенную поддержку для обработки строк непосредственно как UTF-8 - здесь UTF-8 - это «собственный» набор символов (более или менее) и сохранение последовательности, поскольку UTF-16 является менее эффективной альтернативой. Конечно, использование Windows в тех местах, где вы уже используетеCHAR
, не повредит , поскольку параметры сортировки, ограничивающие символы, которые могут быть сохранены, никогда не были привлекательными.Ответы:
Уменьшение размера возможно только , если большинство персонажей, по существу
[space]
,0 - 9
,A - Z
,a - z
, и некоторые основные знаки препинания. За пределами этого конкретного набора символов (в терминах практического использования, стандартных значений ASCII 32–126) вы будете в лучшем случае равны по размеруNVARCHAR
/ UTF-16 или во многих случаях больше.Быть осторожен. UTF-8 - это не волшебный переключатель «все исправить». При прочих равных условиях, да, чтение меньше улучшает производительность. Но здесь «все остальные вещи» не равны. Даже при хранении только стандартных символов ASCII (то есть: все символы имеют длину 1 байт, что требует вдвое меньше места по сравнению с сохранением в
NVARCHAR
), существует небольшое ухудшение производительности при использовании UTF-8. Я полагаю, что проблема связана с тем, что UTF-8 является кодировкой переменной длины, что означает, что каждый байт должен интерпретироваться так, как он читается, чтобы узнать, является ли он полным символом или является ли следующий байт его частью. Это означает, что все строковые операции должны начинаться с начала и проходить побайтово. С другой стороны,NVARCHAR
/ UTF-16 всегда составляет 2 байта (даже дополнительные символы состоят из двух 2-байтовых кодовых точек), поэтому все можно прочитать в 2-байтовых фрагментах.В моем тестировании, даже с использованием только стандартных символов ASCII, сохранение данных в формате UTF-8 не дало экономии прошедшего времени, но было определенно хуже для процессорного времени. И это было без сжатия данных, поэтому, по крайней мере, было использовано меньше дискового пространства. Но при использовании сжатия пространство, необходимое для UTF-8, было только на 1% - 1,5% меньше. Таким образом, экономия места не достигается, а время процессора увеличивается для UTF-8.
Ситуация усложняется при использовании,
NVARCHAR(MAX)
так как сжатие Unicode не работает с этим типом данных, даже если значение достаточно мало для хранения в строке. Но если данные достаточно малы, они все равно должны извлечь выгоду из сжатия строк или страниц (в этом случае они действительно становятся быстрее, чем UTF-8). Однако данные вне строки не могут использовать сжатие. Тем не менее, сделав таблицу Clustered Columnstore Index, вы значительно уменьшите размерNVARCHAR(MAX)
(даже если он все еще немного больше, чем UTF-8 при использовании Clustered Columnstore Index).Определенно. На самом деле, я не вижу убедительной причины использовать его в большинстве случаев. Единственный сценарий, который действительно выигрывает от UTF-8, это:
VARCHAR
)Мои тесты показывают, что почти во всех случаях NVARCHAR работал быстрее, особенно когда данных было больше. Фактически, для 21 тыс. Строк со средним объемом 5 тыс. Символов на строку требуется 165 МБ для UTF-8 и 236 МБ для
NVARCHAR
несжатого. И все же онNVARCHAR
был в 2 раза быстрее по прошествии времени и, по крайней мере, в 2 раза быстрее (иногда больше) времени процессора. Тем не менее, это заняло еще 71 МБ на диске.Помимо этого, я все еще не рекомендовал бы использовать UTF-8, по крайней мере, для CTP 2, из-за множества ошибок, которые я обнаружил в этой функции.
Для подробного анализа этой новой функции, включая объяснение различий между UTF-16 и UTF-8, и список этих ошибок, пожалуйста, смотрите мой пост:
Встроенная поддержка UTF-8 в SQL Server 2019: Спаситель или Лжепророк?
источник
Поддержка UTF-8 дает вам новый набор опций. Потенциальная экономия места (без сжатия строк или страниц ) является одним из соображений, но выбор типа и кодировки, вероятно, следует делать в первую очередь на основе фактических требований к сравнению, сортировке, импорту и экспорту данных .
Возможно, вам придется изменить больше, чем вы думаете, так как, например,
nchar(1)
тип обеспечивает два байта памяти. Этого достаточно для хранения любого символа в BMP (кодовые точки от 000000 до 00FFFF). Некоторые символы в этом диапазоне будут кодироваться с помощью только 1 байта в UTF-8, в то время как другим потребуется 2 или даже 3 байта (см. Эту сравнительную таблицу для получения дополнительной информации). Поэтому для обеспечения покрытия того же набора символов в UTF-8 потребуетсяchar(3)
.Например:
дает знакомую ошибку:
Или если флаг трассировки 460 активен:
Расширение столбца UTF8 до
char(2)
илиvarchar(2)
устранение ошибки дляNCHAR(911)
:Однако, если это, например
NCHAR(8364)
, вам нужно будет расширить столбец доchar(3)
илиvarchar(3)
.Также обратите внимание, что все параметры сортировки UTF-8 используют дополнительные символы, поэтому не будут работать с репликацией.
Помимо всего прочего, поддержка UTF-8 в настоящее время доступна только для предварительного просмотра, поэтому она недоступна для производственного использования.
источник