2009-03-04 8 views
59

Существует ли правило, когда мы должны использовать типы Unicode?Когда мы должны использовать NVARCHAR/NCHAR вместо VARCHAR/CHAR в SQL Server?

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

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

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

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

Я не хочу, чтобы всегда использовать NVARCHAR, как предложено здесь What are the main performance differences between varchar and nvarchar SQL Server data types?

ответ

96

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

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

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

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

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

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

VARCHAR, когда гарантированно быть ограничены NVARCHAR иначе

+2

>> Когда у вас разные языки в одной колонке ... Вот и все! –

+3

Следует отметить, что * «разные языки» * означает не только то, что разные строки могут содержать значения с разных языков. Это также означает, что если стандартная сортировка базы данных (то есть локальная машина сервера) отличается от локали любого клиентского компьютера. например Серверная машина настроена на 'en-US', но мой компьютер настроен на' fr-US'. –

+0

@IanBoyd В общем, сортировка будет очень проблематичной при смешивании языков в столбце и возвращении элементов на нескольких языках в одном наборе и использовании этой сортировки для упорядочения. Сопоставление также может влиять на комбинации персонажей, которые будут рассматриваться как один (венгерский dz и ly): http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue - nvarchar не собирается решать это –

3

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

10

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

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

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

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

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

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

Этого примера иллюстрирует тот факт, что многих мест, таких как грузинский и Хинди, не имеют кодовых страниц, так как они являются сортировками только для Юникода.Эти сопоставления не подходят для колонн, которые используют CHAR, VARCHAR или тип данных текст

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

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

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

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

+3

>> Вы должны использовать NVARCHAR в любое время, когда вам нужно хранить несколько языков. Это неправда. Немецкий и итальянский и английский хорошо подходят в одном столе с колонками VARCHAR. Пожалуйста, уточните –

+0

См. Http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx и http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue для примеров с dz и ly на венгерском языке. –

2

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

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

Алекс

+0

Привет, Алекс, вы когда-нибудь хранили разные языки в 1 колонке? У нас были разные столбцы для разных языков в 1 таблице. –

+0

Возможно, они ссылаются на чешский язык. У нас есть «ch» между «h» и «i», и это отдельная буква алфавита. – jahav

0

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

From 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 и текст).

Иначе ваша сортировка пойдет странно.