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

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

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

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

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

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

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

Ответы [ 5 ]

108 голосов
/ 05 марта 2009

Реальная причина, по которой вы хотите использовать 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 иначе

10 голосов
/ 05 марта 2009

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

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

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

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

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

Вот еще немного:

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

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

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

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

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

3 голосов
/ 05 марта 2009

Греческому понадобится UTF-8 для N типов столбцов: αβγ;)

2 голосов
/ 04 мая 2009

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

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

Alex

0 голосов
/ 23 марта 2016

TL; DR;
Юникод - (nchar, nvarchar и ntext)
Non-Unicode - (char, varchar и текст).

От 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 - это стандарт для отображения кодовых точек на символы. Так как он предназначен для охвата всех символов всех языков мир, нет необходимости в разных кодовых страницах для обработки разных наборы символов. Если вы храните символьные данные, которые отражают несколько языки, всегда используйте типы данных Unicode (nchar, nvarchar и ntext) вместо не-Unicode типов данных (char, varchar и text).

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

...