SQL Server中NVarchar存储与Varchar存储的区别

15

我刚刚得知一个同事告诉我,如果你在数据库中为VARCHAR字段分配一个长度,例如VARCHAR(1000),那么数据库将强制每行保留1000字节的空间,无论是否需要。

然而,他声称一个NVARCHAR(1000)字段只会占用所需的字节数。

我已经尽力查找了这个问题,在这里和网络上都没有找到任何支持这一说法的内容,SQL Server帮助文档也没有提到这一点。


2
没有错,VARCHAR 只存储基于数据所需的字节数。 - Pரதீப்
nvarchar 用于存储 Unicode 语言或符号,而 varchar 用于存储文本格式。 - Saeed ur Rehman
https://dev59.com/O3VC5IYBdhLWcg3w0EoD - Deep
2
http://sqlhints.com/2011/12/23/difference-between-varchar-and-nvarchar/ - Pரதீப்
2
我猜你的同事把 VARCHARCHAR 搞混了。即使你的字符串只有 5 个字符,CHAR(100) 也会始终创建一个大小为 100 的字符串值。而 VARCHAR 不会这样做。这就是 VAR 的含义(变量)。 - Jens
3个回答

32

根据 MSDN 文档:

varchar [ ( n | max ) ]

可变长度的非 Unicode字符串数据。n 定义了字符串长度,可以是 1 到 8,000 的值。max 表示最大存储大小为 2^31-1 字节(2 GB)。存储大小是实际输入数据的长度加上 2 字节。

nvarchar [ ( n | max ) ]

可变长度的Unicode字符串数据。n 定义了字符串长度,可以是 1 到 4,000 的值。max 表示最大存储大小为 2^31-1 字节(2 GB)。存储大小(以字节为单位)是输入的实际数据长度的两倍再加上 2 个字节。

另外:

每个非空的varchar(max)nvarchar(max)列需要额外固定分配24个字节,这在排序操作期间计入8,060字节行限制。

您可以使用DATALENGTH来检查存储数据的大小:

返回用于表示任何表达式所使用的字节数。

您可以进行简单的测试以检查存储varcharnvarchar数据所使用的长度和字节数:

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决定了字符串的长度(字符数)。

nvarchar的数据长度是varchar的两倍。


非常感谢,我有一种感觉就是在读这个,但直到现在才真正明白。 - Ben W
此外,我建议您查看这个问题[链接](https://dev59.com/xXVC5IYBdhLWcg3w7Vxq)。我可以说那里给出的答案让我了解了关于这些数据类型的很多知识,并带领我进行了更深入的研究。 - gofr1

10

简洁准确。完美答案。 - pim

7
似乎在CHAR和VARCHAR之间存在混淆。
CHAR/NCHAR是固定长度的,因此它们始终将保持定义的字节数。例如,如果您创建一个类型为CHAR(10)的字段的表,则每行将保持10个字节,无论您输入包含较少字符的值还是不包含。剩余的长度用空格填充。
VARCHAR/NVARCHAR是可变长度的,并且使用的字节数取决于其包含的列的值。例如,如果您创建一个类型为VARCHAR(10)的字段的表,则每行可能具有不同的大小,具体取决于该列中保存的值的长度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接