Подтвердить что ты не робот

Разница между VARCHAR2 (10 CHAR) и NVARCHAR2 (10)

Я установил 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)
4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

    NVARCHAR2 данных NVARCHAR2 использует AL16UTF16 символов 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

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

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

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

Ответ 4

nVarchar2 - это Unicode-хранилище.

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

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

Ответ 5

Интересно, действуют ли NVARCHAR2 (1) и VARCHAR2 (1) по-другому относительно значения null/empty?

От тестирования, похоже, похоже.

Можно получить некоторые сюрпризы

то есть. сравнение пустой строки в!= 'Y' не вернет пустые строки строк. т.е. пустая строка не имеет и не равна "Y"...

нужна функция обертки nvl
например и nvl (верхний (WP. "OW_IS_MISRUN" ), 'N')!= 'Y'

выберите кол-(*) из "DATA_HUB". "OW_WELL_PERFORATION" WP где WP.UWI = 17038046

7

выберите count (*) из "DATA_HUB". "OW_WELL_PERFORATION" WP где WP.UWI = 17038046 и верхний (WP. "OW_IS_MISRUN" )!= 'Y'

1

выберите count (*) из "DATA_HUB". "OW_WELL_PERFORATION" WP где WP.UWI = 17038046 и верхний (WP. "OW_IS_MISRUN" ) = 'Y'

2

выберите count (*) из "DATA_HUB". "OW_WELL_PERFORATION" WP где WP.UWI = 17038046 и nvl (верхний (WP. "OW_IS_MISRUN" ), 'N')!= 'Y'

5