Яка різниця між варчаром і нварчаром?


1354

Це просто nvarcharпідтримує багатобайтові символи? Якщо це так, чи дійсно є якийсь інший момент, окрім проблем із зберіганням varchars?


6
Мені подобається думка incomudro, саме це спонукало мене до розкопок про різницю між varchar & nvarchar в першу чергу. Наш додаток Java проти db SQL Server використовує myBatis, який, здається, надсилає рядки як nvarchar за замовчуванням (все ще не впевнений, як (або якщо) це переоцінити). Простий запит виявлявся як величезна проблема продуктивності, тому що я визначив стовпець, який він вибирав, як varchar, а не nvarchar, і ігнорував індекс у стовпці.
Прочитати Шона

Відповіді:


1652

nvarcharСтовпець може зберігати будь-які дані Unicode. varcharКолонка обмежена 8-бітної кодової сторінки. Деякі люди вважають, що його varcharслід використовувати, оскільки він займає менше місця. Я вважаю, що це не правильна відповідь. Незмінність кодової сторінки - це біль, а Unicode - ліки для проблем із кодовою сторінкою. На сьогоднішній день із дешевим диском та пам'яттю насправді немає причин витрачати час на обробку кодових сторінок.

Всі сучасні операційні системи та платформи розробки використовують Unicode внутрішньо. Використовуючи, nvarcharа не використовуючи varchar, ви можете уникнути кодування перетворень кожного разу, коли читаєте або записуєте в базу даних. Конверсії потребують часу та схильні до помилок. І відновлення після помилок конверсії - це нетривіальна проблема.

Якщо ви взаємодієте з додатком, який використовує лише ASCII, я все-таки рекомендую використовувати Unicode в базі даних. Алгоритми зіставлення ОС і БД краще працюватимуть з Unicode. Unicode дозволяє уникнути проблем перетворення під час взаємодії з іншими системами. І ви будете готуватися до майбутнього. І ви завжди можете перевірити, що ваші дані обмежені 7-бітним ASCII для будь-якої застарілої системи, яку вам доведеться підтримувати, навіть користуючись деякими перевагами повного зберігання Unicode.


8
Це чудова інформація. Тож чи я це правильно розумію, якщо дійшов висновку, що вибір в кінцевому підсумку стає одним із - який ресурс дешевший: процесор + накладні витрати або зберігання?
Метт Кашатт

141
@MatthewPatrickCashatt - Ви могли це бачити саме так. Але якщо ви уявляєте собі славний світ, в якому всі текстові дані знаходяться в Unicode, і розробникам просто не доводиться думати про те, що в чомусь кодується, і цілий клас помилок просто не виникає, то ви можете побачити, що існує насправді вибору взагалі немає.
Джеффрі Л Уітлідж


8
@Martin Smith - У тих випадках крихітна перевага, яку надає варчар (компактне зберігання), зникає. Гадаю, варчар ще гірший, ніж я думав!
Джефрі Л Вітлідж

9
@PeterAllenWebb - Ви можете "зберігати" будь-які дані Unicode, оскільки сурогатні пари в UTF-16 можуть зберігатися в UCS-2 так, ніби вони були символами. Це буде прозоро працювати для зберігання та пошуку даних. Тепер, що ви не можете зробити, це отримати надійні перетворення справ і порівняння за межами BMP, але я не висловлював жодних претензій з цього приводу. Отже, якщо у вас є багато тексту Desseret, який ви хочете обробити, найкраще це зробити поза межами бази даних. Але просто чудово зберігати його там. (Звичайно, варчар теж не збирається вам там допомагати!)
Джеффрі Л Уітлідж

259

varchar : Дані символів без змін Unicode. Порівняння бази даних визначає, на якій кодовій сторінці зберігаються дані.

nvarchar : Дані символів Unicode змінної довжини. Залежно від порівняння бази даних для порівнянь.

Озброївшись цими знаннями, використовуйте те, що відповідає вашим вхідним даним (ASCII проти Unicode).


5
Чи існує таке обмеження, як varchar не може зберігати дані Unicode? Її всі 1 і 0. Я в змозі зберегти китайський вміст як varchar просто чудово в моїй БД. Я просто вказую його UTF-8, хоча. Як це працює тоді?
Нішант

3
@Nishant пізня відповідь : звичайно, ви можете зберігати UTF-8 у varchar, але це порушить рядкові функції SQL Server. Якщо ви здійснюєте всі пошуки / перетворення у вашій програмі, то так, ви можете це зробити (але яка користь?). UCS-2 підтримує лише кодування Unicode, що підтримується SS (так, не UTF-16 до SS2k16), і його рядкові функції працюють лише з цим кодуванням. До речі, що з індексами? Якщо ви хочете зберігати довільні дані, краще замість цього використовуйте двійкові.
Адріано Репетті

Так, це просто порушує функції пошуку рядків.
Нішант

8
Отже, ви знаєте ... це не "працює". Це схоже на зберігання floatв intта перехід, "добре переконайтесь, що децималі пропали". Просто ні.
user7116

70

Я завжди використовую nvarchar, оскільки він дозволяє всім, що будую, витримувати майже будь-які дані, які я накидаю на нього. Моя система CMS робить китайську мову випадково, тому що я використовував nvarchar. У наші дні будь-які нові програми насправді не повинні стосуватися кількості необхідного місця.


25
Ідея про те, що нові додатки не повинні стосуватися обмеження місця, є дещо недалекоглядною, і кожен, хто має справу з базами даних на рівні середнього та великого бізнесу, з радістю скаже вам, абсолютно неправильна.
Фратер

60
Щоб вільно вводити слова в рот tags2k, я думаю, що більш точним висловленням може бути "все більше малоймовірно, що будь-які нові додатки повинні більше турбуватися про необхідний простір, ніж про інтернаціоналізацію та інші проблеми набору символів".
Кован

1
"В наші дні будь-які нові програми насправді не повинні стосуватися кількості необхідного місця." - Якщо ви не користуєтесь безкоштовним хмарним сховищем, де платний план - ВІДПОВІДНИЙ стрибок у $ (див. Спільні плани AppHarbor SQL Server).
Ґендер

3
@ganders вий! Ти там. Узагальнені твердження завжди найкращі лише тимчасово. Обчислювальна техніка, безумовно, гра в гойдалки та навколо. Я напевно переймаюся тим, скільки місця я використовую на Windows Azure CCP. Це сказало, що я ніколи не буду використовувати варчар над nvarchar. Ооо, я просто суперечив собі?
rism

1
@ism, я вважаю, що ви усунули будь-який ризик суперечності своїм використанням цитат "never", принаймні технічно.
Smandoli

30

Це залежить від того, як встановлено Oracle. Під час встановлення встановлюється параметр NLS_CHARACTERSET. Ви можете знайти його за допомогою запиту SELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET'.

Якщо ваш NLS_CHARACTERSET - це кодування Unicode, подібне до UTF8, чудово. Використання VARCHAR та NVARCHAR майже однакові. Перестаньте читати зараз, просто займіться цим. В іншому випадку, або якщо у вас немає контролю над набором символів Oracle, читайте далі.

VARCHAR - Дані зберігаються в кодуванні NLS_CHARACTERSET. Якщо на цьому ж сервері є інші екземпляри бази даних, ви можете бути обмежені ними; і навпаки, оскільки вам належить поділитися налаштуваннями. Таке поле може зберігати будь-які дані, які можна закодувати за допомогою цього набору символів, і нічого іншого . Так, наприклад, якщо набір символів - MS-1252, ви можете зберігати лише такі символи, як англійські літери, жменька наголошених букв та кілька інших (наприклад, € та -). Ваш додаток буде корисним лише для декількох місцевостей, які не зможуть працювати ніде в світі. З цієї причини це вважається поганою ідеєю.

NVARCHAR - Дані зберігаються в кодуванні Unicode. Кожна мова підтримується. Гарна ідея.

А як щодо місця для зберігання? VARCHAR, як правило, ефективний, оскільки набір символів / кодування був розроблений на замовлення для конкретної локалі. Поля NVARCHAR зберігають або в кодуванні UTF-8, або UTF-16, базуючи налаштування NLS досить іронічно. UTF-8 дуже ефективний для "західних" мов, при цьому все ще підтримує азіатські мови. UTF-16 дуже ефективний для азіатських мов, при цьому все ще підтримує "західні" мови. Якщо вас турбує простір для зберігання даних, виберіть параметр NLS, щоб змусити Oracle використовувати UTF-8 або UTF-16 у відповідних випадках.

А як щодо швидкості обробки? Більшість нових платформ кодування використовують Unicode вродженим способом (Java, .NET, навіть C ++ std :: wstring з років тому!), Тому якщо поле бази даних є VARCHAR, це змушує Oracle конвертувати між наборами символів під час кожного читання або запису, не так добре. Використання NVARCHAR уникає перетворення.

Підсумок: Використовуйте NVARCHAR! Це дозволяє уникнути обмежень і залежностей, чудово підходить для місця для зберігання і, як правило, найкраще і для продуктивності.


42
Це дійсно гарна відповідь, за винятком того, що питання стосується sql-сервера.
стимули

21

nvarchar зберігає дані як Unicode, тому, якщо ви збираєтеся зберігати багатомовні дані (більше однієї мови) у стовпчику даних, вам потрібен варіант N.


16

Мої два центи

  1. Індекси можуть вийти з ладу, коли не використовуються правильні типи даних:
    У SQL Server: Коли у вас є індекс над стовпцем VARCHAR і представляєте його рядком Unicode, SQL Server не використовує індекс. Те саме відбувається, коли ви представляєте BigInt індексованому стовпцю, що містить SmallInt. Навіть якщо BigInt досить малий, щоб бути SmallInt, SQL Server не в змозі використовувати індекс. З іншого боку, у вас немає цієї проблеми (при наданні SmallInt або Ansi-коду до індексованого стовпця BigInt від NVARCHAR).

  2. Типи даних можуть відрізнятися між різними СУБД (Система управління DataBase):
    Знайте, що кожна база даних має дещо різні типи даних, і VARCHAR не означає скрізь однакові. У той час як SQL Server має VARCHAR та NVARCHAR, база даних Apache / Derby має лише VARCHAR, а VARCHAR - у Unicode.


Але, звичайно, якщо ви правильно пишете свій код (тобто використовуєте параметризовані запити тощо), то точка 1 становить менший ризик.
Пол

14

В основному nvarchar зберігає символи Unicode, а varchar зберігає символи Unicode.

"Юнікоди" означає 16-бітну схему кодування символів, що дозволяє коди з багатьох інших мов, таких як арабська, іврит, китайська, японська, кодуватися в одному наборі символів.

Це означає, що unicodes використовує 2 байти на символ для зберігання, а ununicodes використовує для зберігання лише один байт на символ. Що означає, що для зберігання унікодів потрібна подвійна ємність порівняно з не-унікодами.


10

Ти правий. nvarcharзберігає дані Unicode, varcharзберігаючи однобайтові символьні дані. Крім відмінностей зберігання ( nvarcharпотрібно в два рази більше місця для зберігання , як varchar), який ви вже згадувалося, основна причина переваги nvarcharбільш varcharбуде інтернаціоналізація (тобто зберігання рядків в інших мовах).


10

Я б сказав, це залежить.

Якщо ви розробляєте настільний додаток, де ОС працює в Unicode (як і всі поточні системи Windows), а мова вродже підтримує Unicode (рядки за замовчуванням Unicode, як у Java або C #), тоді перейдіть до nvarchar.

Якщо ви розробляєте веб-додаток, де рядки надходять як UTF-8, а мова - PHP, яка все ще не підтримує Unicode на самому собі (у версіях 5.x), то varchar, ймовірно, стане кращим вибором.


9

Хоча NVARCHARзберігається Unicode, вам слід врахувати за допомогою порівняння, також ви можете використовувати VARCHARта зберігати свої дані місцевих мов.

Тільки уявіть собі наступний сценарій.

Порівняння вашої БД є персидським, і ви зберігаєте значення типу "علی" (перська мова Ali) у VARCHAR(10)типі даних. Проблем немає, і СУБД використовує лише три байти для зберігання.

Однак, якщо ви хочете перенести свої дані в іншу базу даних і побачити правильний результат, у вашій базі даних пункту призначення повинно бути таке ж порівняння, як ціль, яка є персидською в цьому прикладі.

Якщо ваше цільове порівняння відрізняється, ви бачите деякі знаки запитання (?) У цільовій базі даних.

Нарешті, пам’ятайте, якщо ви використовуєте величезну базу даних, яка використовується для вашої місцевої мови, я б рекомендував використовувати місце, а не занадто багато пробілів.

Я вважаю, що дизайн може бути різним. Це залежить від середовища, в якому ви працюєте.


8

Я переглянув відповіді, і багато хто, здається, рекомендують використовувати nvarcharбільше varchar, тому що простір вже не є проблемою, тому немає шкоди в тому, щоб Unicode не мав зайвого місця для зберігання. Ну, це не завжди вірно, коли ви хочете застосувати індекс над стовпцем. SQL Server має обмеження в 900 байт щодо розміру поля, яке можна індексувати. Тож якщо у вас є, varchar(900)ви все одно можете його індексувати, але ні varchar(901). З nvarchar, кількість символів зменшиться вдвічі, тому ви можете проіндексувати до nvarchar(450). Тож якщо ви впевнені, що вам це не потрібно nvarchar, я не рекомендую його використовувати.

Взагалі в базах даних я рекомендую дотримуватися потрібного вам розміру, тому що ви завжди можете розширити. Наприклад, колега по роботі одного разу подумав, що в використанні nvarchar(max)для стовпчика немає ніякої шкоди , оскільки у нас взагалі немає проблем із зберіганням. Пізніше, коли ми намагалися застосувати індекс до цього стовпця, SQL Server це відхилив. Якби він почав з рівних varchar(5), ми могли б згодом просто розширити його до того, що нам потрібно, без такої проблеми, яка вимагатиме від нас скласти план міграції поля, щоб виправити цю проблему.


7

nVarchar допоможе вам зберігати символи Unicode. Це шлях, якщо потрібно зберігати локалізовані дані.


7

Якщо один байт використовується для зберігання символу, існує 256 можливих комбінацій, і тим самим ви можете зберегти 256 різних символів. Збір - це шаблон, який визначає символів та правила, за якими вони порівнюються та сортуються.

1252, що є латинським1 (ANSI), є найпоширенішим. Однобайтові набори символів також недостатні для зберігання всіх символів, які використовуються багатьма мовами. Наприклад, деякі азіатські мови мають тисячі символів, тому вони повинні використовувати два байти на символ.

Unicode стандарт

Коли в мережі використовуються системи, що використовують кілька сторінок коду, керувати зв’язком стає важко. Для стандартизації речей консорціум ISO та Unicode представив Unicode . Unicode використовує два байти для зберігання кожного символу. Тобто 65,536 різних символів можна визначити, тому майже всі символи можуть бути покриті Unicode. Якщо два комп'ютери використовують Unicode, кожен символ буде представлений однаково, і перетворення не потрібно - це ідея Unicode.

SQL Server має дві категорії типів даних символів:

  • не-Unicode (char, varchar та text)
  • Unicode (nchar, nvarchar і ntext)

Якщо нам потрібно зберегти дані символів з кількох країн, завжди використовуйте Unicode.


6

Я повинен сказати , що тут (я розумію , що я , ймовірно , збираюся відкрити себе до опрацювання!), Але , безумовно , єдиний раз , коли NVARCHARнасправді більш корисним (зверніть увагу на більш там!) , Чим VARCHARколи все сортування на все залежних систем і всередині самої бази даних однакові ...? Якщо ні, то перетворення зіставлення має відбутися в будь-якому випадку, і це робить VARCHARтак само життєздатним, як і NVARCHAR.

Щоб додати до цього, деякі системи баз даних, такі як SQL Server (до 2012 року), мають розмір сторінки приблизно. 8К. Отже, якщо ви дивитесь на зберігання даних, які можна шукати, не містять у собі щось подібне до поля TEXTчи NTEXTполя, то ви отримуєте VARCHARповний простір у 8 кб, тоді як NVARCHARлише 4 кб (подвійний байт, подвійний пробіл).

Я гадаю, підсумовуючи, використання будь-якого залежить від:

  • Проект або контекст
  • Інфраструктура
  • Система баз даних

6

Дотримуйтесь різницю між типом даних VARCHAR сервера Sql та типом даних NVARCHAR . Тут ви могли бачити дуже описово.

Загаломvarcar зберігає дані як Unicode, тому, якщо ви збираєтеся зберігати багатомовні дані (більше однієї мови) у стовпці даних, вам потрібен N варіант.


Це дуже корисне посилання, але ваша відповідь не означає набагато більше: посилання.
RubberDuck

ckuhn203, я не збираюся розповідати вам про це
Pradeep Kesharwani

6

Основна відмінність між Varchar(n)і nvarchar(n): введіть тут опис зображення

VarcharРозмір (змінної довжини, не символів Unicode) розмір до 8000. 1. Це тип даних змінної довжини

  1. Використовується для зберігання символів, що не належать до Unicode

  2. Займає 1 байт місця для кожного символу

введіть тут опис зображення

Nvarchar: Дані символів Unicode змінної довжини.

1. Це тип даних змінної довжини

2. Використовується для зберігання символів Unicode.

  1. Дані зберігаються в кодуванні Unicode. Кожна мова підтримується. (наприклад, арабська, німецька, хінді та ін.)

6

Джеффрі Л Уітлідж з оцінкою репутації ~ 47000 рекомендує використовувати nvarchar

Соломон Руцький з оцінкою репутації ~ 33200 рекомендує: НЕ завжди використовуйте NVARCHAR. Це дуже небезпечне і часто затратне ставлення / підхід.

Які основні відмінності у продуктивності між типами даних varchar і nvarchar SQL Server?

https://www.sqlservercentral.com/articles/disk-is-cheap-orly-4

Обидві особи з такою високою репутацією, що обирає розробник бази даних навчального сервера?

У відповідях та коментарях щодо питань щодо ефективності є багато попереджень, якщо ви не послідовні у виборі.

Є коментарі про / кон nvarchar для виконання.

Існують коментарі pro / con varchar для продуктивності.

У мене є особлива вимога до таблиці з багатьма сотнями стовпців, що саме по собі, мабуть, незвично?

Я вибираю varchar, щоб уникнути наближення до обмеження розміру запису 8060 байт таблиці SQL * сервера 2012 року.

Використання nvarchar для мене перевищує цю межу в 8060 байт.

Я також думаю, що мені слід зіставити типи даних пов’язаних таблиць коду з типами даних первинної центральної таблиці.

Я бачив використання стовпчика varchar у цьому місці роботи, уряді Південної Австралії, попередніми досвідченими розробниками баз даних, де кількість рядків таблиць складе кілька мільйонів і більше (і дуже мало колонок nvarchar, якщо такі є, у цих дуже великих таблиці), тому, можливо, очікувані обсяги рядків даних стають частиною цього рішення.


1

nvarcharє безпечним для використання порівняно з varcharтим, щоб зробити наш код помилкою (тип невідповідності), оскільки nvarcharдозволяє також символи Unicode. Коли ми використовуємо whereумову в запиті на SQL Server, і якщо ми використовуємо =оператор, він кілька разів видасть помилку. Ймовірна причина цього - наш стовпчик карти буде визначений у varchar. Якби ми визначили це в nvarcharцій проблемі, мого не відбудеться. Все ж ми дотримуємось varcharі уникаємо цього питання, а краще використовувати LIKEключове слово, а не =.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.