Хранилище NVarchar vs Varchar storage на SQL Server

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

Однако он утверждает, что поле NVARCHAR (1000) будет просто содержать необходимое количество байтов.

Я исследовал это как можно лучше, как здесь, так и вокруг Интернета, но я не могу найти ничего, чтобы поддержать это, и в документации по SQL Server не упоминается об этом где-нибудь, что я могу найти.

Ответ 1

Из MSDN:

varchar [(n | max)]

Строковые данные с переменной длиной, не-Юникодом. n определяет длину строки и может быть значением от 1 до 8000. max указывает, что максимальный размер хранилища составляет 2 ^ 31-1 байта (2 ГБ). Размер хранилища - это фактическая длина введенных данных + 2 байта.

nvarchar [(n | max)]

Строковые данные с переменной длиной Unicode. n определяет длину строки и может быть значением от 1 до 4000. max указывает, что максимальный размер хранилища составляет 2 ^ 31-1 байта (2 ГБ). Размер памяти в байтах в два раза превышает фактическую длину введенных данных + 2 байта.

и

Каждый столбец не нуль varchar (max) или nvarchar (max) требует 24 байтов дополнительного фиксированного распределения, которое рассчитывается против предела строки в 8,060 байт во время операции сортировки,

Чтобы проверить размер сохраненных данных, вы можете использовать DATALENGTH

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

Вы можете выполнить этот простой тест, чтобы проверить длину и укусы, используемые для хранения данных varchar и nvarchar:

CREATE TABLE #temp (
    id int IDENTITY(1,1) NOT NULL,
    vColumn varchar(1000) NULL,
    nvColumn nvarchar(1000) NULL
)


INSERT INTO #temp VALUES
('something',N'something'),
('more','more'),
('',''),
('Autem excepturi omnis neque doloribus dolore. Saepe deleniti optio non ratione nesciunt esse ducimus. Nulla quia voluptatem aliquid omnis ex deleniti. Rerum minima unde officia est voluptatum esse dolorem aut. Sed est voluptas laboriosam. Dolore sint necessitatibus architecto sit eius ut molestiae eum.Sit sunt in dolores nihil. Numquam et nihil quo vel iusto. Commodi rem sint magnam qui perspiciatis. Accusantium sit adipisci neque. Nihil itaque quam quia. Est sapiente ut perferendis quia rerum. Quibusdam non et perferendis vel maxime est voluptates. Dolor deserunt qui iusto est. Et deleniti quia hic dicta ut quia. Dolore ducimus aspernatur quam nostrum commodi. Sequi cupiditate ipsa tempore. Velit dolorem eaque aspernatur sed numquam placeat excepturi odit. Accusantium officia sequi voluptas facilis ut eum necessitatibus id. Libero qui rerum et amet veniam architecto. Voluptatibus ad labore expedita. Mollitia ut soluta accusantium qui nam sunt nostrum. Aliquid aut voluptas accusamus v.',
N'Autem excepturi omnis neque doloribus dolore. Saepe deleniti optio non ratione nesciunt esse ducimus. Nulla quia voluptatem aliquid omnis ex deleniti. Rerum minima unde officia est voluptatum esse dolorem aut. Sed est voluptas laboriosam. Dolore sint necessitatibus architecto sit eius ut molestiae eum.Sit sunt in dolores nihil. Numquam et nihil quo vel iusto. Commodi rem sint magnam qui perspiciatis. Accusantium sit adipisci neque. Nihil itaque quam quia. Est sapiente ut perferendis quia rerum. Quibusdam non et perferendis vel maxime est voluptates. Dolor deserunt qui iusto est. Et deleniti quia hic dicta ut quia. Dolore ducimus aspernatur quam nostrum commodi. Sequi cupiditate ipsa tempore. Velit dolorem eaque aspernatur sed numquam placeat excepturi odit. Accusantium officia sequi voluptas facilis ut eum necessitatibus id. Libero qui rerum et amet veniam architecto. Voluptatibus ad labore expedita. Mollitia ut soluta accusantium qui nam sunt nostrum. Aliquid aut voluptas accusamus v.')

SELECT  id,
        vColumn,
        LEN(vColumn) vLen,
        DATALENGTH( vColumn) as vLength,
        nvColumn,
        LEN(nvColumn) nvLen,
        DATALENGTH( nvColumn) as nvLength
FROM #temp

DROP TABLE #temp

Будет выводиться:

id  vColumn             vLen    vLength     nvColumn            nvLen   nvLength
1   something           9       9           something           9       18
2   more                4       4           more                4       8
3                       0       0                               0       0
4   Autem excepturis... 1000    1000        Autem excepturi...  1000    2000

В основном n в вышеприведенных операторах определяется LENGTH (количество символов) строки.

DATALENGTH для nvarchar в два раза больше, чем varchar.

Ответ 2

Похоже, есть путаница между CHAR и VARCHAR.

CHAR/NCHAR - фиксированная длина, поэтому они всегда будут содержать количество байтов, как определено. например если вы создаете таблицу с полем типа CHAR (10), каждая строка будет содержать 10 байтов, независимо от того, вводите ли вы значение, которое содержит меньше символов или нет. Остальная часть длины заполняется пробелами.

VARCHAR/NVARCHAR - это переменная длина, и количество используемых байтов будет зависеть от значения, которое он содержит. например если вы создаете таблицу с полем типа VARCHAR (10), каждая строка может быть другого размера, в зависимости от длины значения, содержащегося в этом столбце.

Ответ 3

Nvarchar хранит данные UNICODE. Если у вас есть требования к хранению UNICODE или многоязычные данные, выбор nvarchar. Хранилища Varchar ASCII и должен быть вашим типом данных для нормального использования. Что касается использования памяти, nvarchar использует 2 байта на символ, тогда как varchar использует 1.

Источник - https://dba.stackexchange.com/info/36081/write-differences-between-varchar-and-nvarchar