Разница между VARCHAR2 (10 символов) и NVARCHAR2 (10) - PullRequest
52 голосов
/ 22 декабря 2010

Я установил Oracle Database 10g Express Edition (Universal) со стандартными настройками:

SELECT * FROM NLS_DATABASE_PARAMETERS;

NLS_CHARACTERSET               AL32UTF8                                 
NLS_NCHAR_CHARACTERSET         AL16UTF16                                

Учитывая, что типы данных CHAR и NCHAR, похоже, принимают многобайтовые строки, чтоточная разница между этими двумя определениями столбцов?

VARCHAR2(10 CHAR)
NVARCHAR2(10)

Ответы [ 4 ]

85 голосов
/ 22 декабря 2010

Тип данных NVARCHAR2 был введен Oracle для баз данных, которые хотят использовать Unicode для некоторых столбцов, сохраняя другой набор символов для остальной части базы данных (которая использует VARCHAR2). NVARCHAR2 - это тип данных только для Unicode.

Одной из причин, по которой вы можете захотеть использовать NVARCHAR2, может быть то, что ваша БД использует набор символов, отличный от Unicode, и вы все еще хотите иметь возможность хранить данные Unicode для некоторых столбцов без изменения основного набора символов. Другая причина может заключаться в том, что вы хотите использовать два набора символов Unicode (AL32UTF8 для данных, поступающих в основном из Западной Европы, AL16UTF16 для данных, поступающих в основном из Азии, например), потому что разные наборы символов не будут одинаково эффективно хранить одни и те же данные.

Оба столбца в вашем примере (Unicode VARCHAR2(10 CHAR) и NVARCHAR2(10)) смогут хранить одни и те же данные, однако байтовое хранилище будет другим. Некоторые строки могут более эффективно храниться в одной или другой.

Обратите внимание, что некоторые функции не будут работать с NVARCHAR2, см. Этот вопрос SO:

3 голосов
/ 10 января 2019
  • NVARCHAR2 хранит символьные данные переменной длины.При создании таблицы со столбцом NVARCHAR2 максимальный размер всегда указывается в семантике длины символа, которая также является семантикой длины по умолчанию и единственной длины для типа данных NVARCHAR2.

    Данные NVARCHAR2type использует набор символов AL16UTF16, который кодирует данные Unicode в кодировке UTF-16. AL16UTF16 использует 2 bytes для хранения символа .Кроме того, максимальная длина байта NVARCHAR2 зависит от настроенного набора национальных символов.

  • VARCHAR2 Максимальный размер VARCHAR2 может быть в байтах или символах.Его столбец может хранить только символы в наборе символов по умолчанию, в то время как NVARCHAR2 может хранить практически любые символы.Для одного символа может потребоваться до 4 bytes.

Определяя поле как:

  • VARCHAR2(10 CHAR), вы сообщаете Oracle, что он может использовать достаточно местахранить 10 символов, независимо от того, сколько байтов требуется для хранения каждого из них.Для одного символа может потребоваться до 4 bytes.
  • NVARCHAR2(10). Вы говорите, что Oracle может хранить 10 символов с 2 bytes на символ

В итоге:

  • VARCHAR2(10 CHAR) может хранить максимум 10 characters и максимум 40 bytes (зависит от настроенного набора национальных символов).

  • NVARCHAR2(10) может хранить максимум 10 characters и максимум 20 bytes (зависит от настроенного набора национальных символов).

Примечание: Набор символовможет быть UTF-8, UTF-16, ....

Пожалуйста, посмотрите этот урок для более подробной информации.

Хорошего дня!

3 голосов
/ 03 января 2019

Я не думаю, что ответ от Винсента Малграта является правильным.Когда NVARCHAR2 был введен давным-давно, никто даже не говорил о Unicode.

Изначально Oracle предоставил VARCHAR2 и NVARCHAR2 для поддержки локализации.Общие данные (включая PL / SQL) хранились в VARCHAR2, скорее всего US7ASCII в эти дни.Тогда вы можете применить NLS_NCHAR_CHARACTERSET индивидуально (например, WE8ISO8859P1) для каждого вашего клиента в любой стране, не затрагивая общую часть вашего приложения.

В настоящее время набор символов AL32UTF8 является значением по умолчанию, которое полностью поддерживает Unicode.,На мой взгляд, сегодня больше нет причин использовать NLS_NCHAR_CHARACTERSET, то есть NVARCHAR2, NCHAR2, NCLOB.Возможно, единственная причина в том, что вы должны поддерживать в основном азиатские символы, где AL16UTF16 потребляет меньше памяти по сравнению с AL32UTF8.

1 голос
/ 02 декабря 2017

nVarchar2 - это Unicode- only storage.

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

Когда вы указываете varchar2 (10) , вы говорите БД, что будут храниться только 10 байтов данных.Но когда вы говорите nVarchar2 (10) , это означает, что 10 символов будут сохранены.В этом случае вам не нужно беспокоиться о количестве байтов, которое занимает каждый символ.

...