Когда мы должны использовать NVARCHAR /NCHAR вместо VARCHAR / CHAR в SQL Server?

StackOverflow https://stackoverflow.com/questions/612430

Вопрос

Существует ли правило, когда мы должны использовать типы Unicode?

Я видел, что большинство европейских языков (немецкий, итальянский, английский, ...) прекрасно работают в одной базе данных в столбцах VARCHAR.

Я ищу что-то вроде:

  1. Если у вас китайский --> используйте NVARCHAR
  2. Если у вас есть немецкий и арабский языки -> используйте NVARCHAR

Как насчет сортировки сервера / базы данных?

Я не хочу всегда использовать NVARCHAR, как предложено здесь Каковы основные различия в производительности между типами данных SQL Server varchar и nvarchar?

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

Решение

Реальная причина, по которой вы хотите использовать NVARCHAR, заключается в том, что когда у вас есть разные языки в одном и том же столбце, вам нужно обращаться к столбцам в T-SQL без декодирования, вы хотите видеть данные "изначально" в SSMS, или вы хотите стандартизировать на Unicode.

Если вы рассматриваете базу данных как хранилище данных, вполне возможно хранить широкие строки и различные (даже переменной длины) кодировки в VARCHAR (например, UTF-8). Проблема возникает, когда вы пытаетесь кодировать и декодировать, особенно если кодовая страница отличается для разных строк. Это также означает, что SQL Server не сможет легко обрабатывать данные для целей запросов в T-SQL к (потенциально изменяемым) кодированным столбцам.

Использование NVARCHAR позволяет избежать всего этого.

Я бы порекомендовал NVARCHAR для любого столбца, в котором будут введены введенные пользователем данные, что является относительно неограниченным.

Я бы порекомендовал VARCHAR для любого столбца, который является естественным ключом (например, номерной знак транспортного средства, номер SSN, серийный номер, метка обслуживания, номер заказа, позывной в аэропорту и т. д.), который обычно определяется и ограничивается стандартом или законодательством или условность. Также VARCHAR для введенного пользователем и очень ограниченного (например, номера телефона) или кода (ACTIVE / CLOSED, Y / N, M / F, M / S / D / W и т. Д.). Нет абсолютно никаких причин использовать NVARCHAR для них.

Так что для простого правила:

VARCHAR, когда гарантируется ограничение NVARCHAR в противном случае

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

Вы должны использовать NVARCHAR всякий раз, когда вам приходится хранить несколько языков.Я считаю, что вы должны использовать это для азиатских языков, но не цитируйте меня по этому поводу.

Вот проблема, если вы возьмете, к примеру, русский язык и сохраните его в varchar, с вами все будет в порядке, если вы определите правильную кодовую страницу.Но допустим, вы используете английскую установку sql по умолчанию, тогда русские символы не будут обработаны правильно.Если бы вы использовали NVARCHAR(), они были бы обработаны должным образом.

Редактировать

Хорошо, позвольте мне процитировать MSDN и, возможно, я был конкретен, но вы не хотите хранить более одной кодовой страницы в столбце varcar, хотя вы можете, но не должны

Когда вы имеете дело с текстовыми данными, которые хранятся в типе данных char, varchar, varchar(max) или text, наиболее важное ограничение, которое следует учитывать заключается в том, что только информация с одной кодовой страницы может быть проверена системой.(Вы можете хранить данные с нескольких кодовых страниц, но это не рекомендуется.) Точная кодовая страница, используемая для проверки и хранения данных, зависит от параметров сортировки столбца.Если параметры сортировки на уровне столбцов не были определены, используется параметры сортировки базы данных .Чтобы определить кодовую страницу , которая используется для данного столбца, вы можете использовать функцию COLLATIONPROPERTY , как показано в следующих примерах кода:

Вот еще кое-что:

Этот пример иллюстрирует тот факт, что многие языки, такие как грузинский и хинди, не имеют кодовых страниц, поскольку они используют параметры сортировки только в Юникоде.Эти параметры сортировки не подходят для столбцов, использующих тип данных char, varchar или text

Так что грузинский или хинди действительно нужно сохранить как nvarchar.Арабский язык - это тоже проблема:

Другая проблема, с которой вы можете столкнуться, заключается в невозможности сохранения данных, когда они отсутствуют все символы, которые вы хотите поддерживать, содержатся на странице кода .Во многих случаях Windows считает конкретную кодовую страницу "наиболее подходящей" кодовой страницей, что означает нет гарантии, что вы можете полагаться на кодовую страницу для обработки всего текста;это просто лучшее из доступных.В Примером этого является арабская вязь:он поддерживает широкий спектр языков, включая белуджийский, берберский, фарси, Кашмирский, казахский, киргизский, пушту, Синдхи, уйгурский, урду и другие.Все эти языки содержат дополнительные символы помимо символов арабского язык, определенный в коде Windows страница 1256.Если вы попытаетесь сохранить эти дополнительные символы в столбце, отличном от Юникода, который имеет параметры сортировки Arabic , символы преобразуются в вопросительные знаки.

Что следует иметь в виду, когда вы используете Unicode, хотя вы можете хранить разные языки в одном столбце, вы можете сортировать только с помощью одного параметра сортировки.Есть некоторые языки, которые используют латинские символы, но сортируются не так, как другие латинские языки.Акценты - хороший пример этого, я не могу вспомнить этот пример, но был восточноевропейский язык, в котором Y не было похоже на английский Y.Затем идет испанский ch, который, как ожидают испанские пользователи, будет отсортирован после h.

В общем, со всеми проблемами, с которыми вам приходится сталкиваться при интернализации.По моему мнению, проще просто использовать символы Юникода с самого начала, избежать дополнительных преобразований и использовать пробел.Отсюда и мое предыдущее заявление.

Греческому языку понадобится UTF-8 для N типов столбцов: & # 945; & # 946; & # 947; ;)

Джош говорит:"....Что следует иметь в виду, когда вы используете Unicode, хотя вы можете хранить разные языки в одном столбце, вы можете сортировать только с помощью одного параметра сортировки.Есть некоторые языки, которые используют латинские символы, но сортируются не так, как другие латинские языки.Акценты - хороший пример этого, я не могу вспомнить этот пример, но был восточноевропейский язык, в котором Y не было похоже на английский Y.Затем есть испанский ch, который, как ожидают испанские пользователи, будет отсортирован после h."

Я носитель испанского языка, и "ch" - это не буква, а две "c" и "h", а испанский алфавит похож на:abcdefghijklmn - opqrstuvwxyz Мы ожидаем не "ch" после "h", а "i" Алфавит тот же, что и в английском, за исключением - или в HTML "-;"

Алекс

TL;DR;
Unicode - (nchar, nvarchar и ntext)
Не в юникоде - (char, varchar и text).

Из MSDN

Параметры сортировки в SQL Server предоставляют правила сортировки, регистр и ударение свойства чувствительности для ваших данных.Параметры сортировки, используемые с символьными типами данных, такими как char и varchar, определяют кодовую страницу и соответствующие символы, которые могут быть представлены для этих данных тип.

Предполагая, что вы используете параметры сортировки SQL по умолчанию SQL_Latin1_General_CP1_CI_AS затем следующий скрипт должен распечатать все символы, которые вы можете вставить VARCHAR поскольку он использует один байт для хранения одного символа (всего 256), если вы не видите его в напечатанном списке - вам нужно NVARCHAR.

declare @i int = 0;
while (@i < 256)
begin
print cast(@i as varchar(3)) + '  '+  char(@i)  collate SQL_Latin1_General_CP1_CI_AS 
print cast(@i as varchar(3)) + '  '+ char(@i)  collate Japanese_90_CI_AS  
set @i = @i+1;
end

Если вы измените параметры сортировки, скажем, на японский, вы заметите, что все странные европейские буквы превратились в обычные, а некоторые символы - в ? отметины.

Unicode - это стандарт для сопоставления кодовых точек с символами.Поскольку он разработан таким образом, чтобы охватывать все символы всех языков мира, нет необходимости в разных кодовых страницах для обработки разных наборов символов.Если вы храните символьные данные, отражающие несколько языков, всегда используйте типы данных в Юникоде (nchar, nvarchar и ntext) вместо типов данных, отличных от Юникода (char, varchar и text).

В противном случае ваша сортировка будет странной.

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