ChatGPT解决这个技术问题 Extra ChatGPT

SQL Server 中的 char、nchar、varchar 和 nvarchar 有什么区别?

nvarchar 是什么意思?

SQL Server 中的 charncharvarcharnvarchar 有什么区别?


s
shA.t

只是为了澄清......或总结......

nchar 和 nvarchar 可以存储 Unicode 字符。

char 和 varchar 不能存储 Unicode 字符。

char 和 nchar 是固定长度的,即使您没有用完所有空间,也会为您指定的字符数保留存储空间。

varchar 和 nvarchar 是可变长度的,只会用完您存储的字符的空格。它不会像 char 或 nchar 那样保留存储空间。

ncharnvarchar 将占用两倍的存储空间,因此仅当您需要 Unicode 支持时才使用它们可能是明智之举。


char 和 varchar 并不意味着存储 unicode,但是通过一些额外的编码技巧和额外的逻辑,您仍然可以滥用 [var]char 字段来存储 unicode。
n... 版本是否占用两倍的存储空间 as my answer shows 取决于排序规则
预留存储有什么好处?
最后一点:在大多数情况下,使用 Unicode nchar 和 nvarchar 仍然更好,更好的排序规则,用户的灵活性,消除了未来的兼容性问题。顺便说一句,对于这种情况,存储空间不是问题,因为在没有 Unicode 的情况下使用排序规则很麻烦,而且未来内存速率将继续下降
@BenCaine char(20) 将使用 20 个字节(假设是 8 位排序规则); varchar(20) 将使用 len(data)+2 字节,即 22 用于 20 字节数据,但仅 12 用于 10 字节数据。额外的两个字节是长度记录。如果您的数据始终是全长,则使用 char,因为它可以节省空间并且可能更快。请永远不要使用 varchar(1),或者任何小于 varchar(4) 的东西。 varchar 格式的单个字符使用三个字节,因此 char(3) 永远不会使用比 varchar(3) 更多的空间。
C
Community

到目前为止,所有答案都表明 varchar 是单字节,nvarchar 是双字节。这实际上是 depends on collation 的第一部分,如下图所示。

DECLARE @T TABLE
(
C1 VARCHAR(20) COLLATE Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS,
C2 NVARCHAR(20)COLLATE  Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS
)

INSERT INTO @T 
    VALUES (N'中华人民共和国',N'中华人民共和国'),
           (N'abc',N'abc');

SELECT C1,
       C2,
       LEN(C1)        AS [LEN(C1)],
       DATALENGTH(C1) AS [DATALENGTH(C1)],
       LEN(C2)        AS [LEN(C2)],
       DATALENGTH(C2) AS [DATALENGTH(C2)]
FROM   @T  

退货

https://i.stack.imgur.com/jhMMM.png

请注意, 字符在 VARCHAR 版本中仍然没有表示,而是被 ? 默默替换。

在该排序规则中,实际上仍然没有可以用单个字节表示的汉字。唯一的单字节字符是典型的西方 ASCII 字符集。

因此,可以从 nvarchar(X) 列插入到 varchar(X)to fail with a truncation error(其中 X 表示两个实例中相同的数字)。

SQL Server 2012 添加了支持 UTF-16 的 SC(补充字符)排序规则。在这些排序规则中,单个 nvarchar 字符可能占用 2 或 4 个字节。


我一直在寻找的那种答案。也为像我这样的人节省时间 - 非英文文本翻译为“中华人民共和国”translate.google.com/#auto/en/…
C
Community

nchar 和 char 的运行方式几乎完全相同,nvarchar 和 varchar 也是如此。它们之间的唯一区别是 nchar/nvarchar 存储 Unicode 字符(如果您需要使用扩展字符集则必不可少),而 varchar 不存储。

因为 Unicode 字符需要更多存储空间,所以 nchar/nvarchar 字段占用两倍的空间(例如,在 SQL Server 的早期版本中,nvarchar 字段的最大大小为 4000)。

此问题与 this one 重复。


你忘了一件事:nchar 使用固定长度,所以 nchar(10) 总是需要接收十个字符。 varchar(10) 确实是 Unicode,可以接受任意数量的字符,最多 10 个字符。另见msdn.microsoft.com/en-us/library/ms186939.aspx
D
Dimuthu

只是为了添加更多内容:nchar - 在数据中添加尾随空格。 nvarchar - 不向数据添加尾随空格。

因此,如果您要通过“nchar”字段过滤数据集,您可能需要使用 RTRIM 删除空格。例如,名为 BRAND 的 nchar(10) 字段存储单词 NIKE。它在单词的右侧添加了 6 个空格。因此,过滤时,表达式应为: RTRIM(Fields!BRAND.Value) = "NIKE"

希望这对那里的人有所帮助,因为我刚刚挣扎了一会儿!


每个选项都在我的 SQL Server 中添加尾随空格...:/
P
PeterAllenWebb

我试图总结和纠正现有答案:

首先,charnchar 将始终使用固定数量的存储空间,即使要存储的字符串小于可用空间,而 varcharnvarchar 将仅使用与原来一样多的存储空间需要存储该字符串(加上两个字节的开销,大概是为了存储字符串长度)。所以请记住,“var”的意思是“变量”,就像在变量空间中一样。

要理解的第二个要点是,ncharnvarchar 使用 恰好 每个字符两个字节存储字符串,而 charvarchar 使用由排序规则代码页确定的编码, 通常每个字符正好是一个字节(尽管有例外,见下文)。通过每个字符使用两个字节,可以存储非常广泛的字符,因此这里要记住的基本事项是,当您需要国际化支持时,ncharnvarchar 往往是更好的选择,您可能会这样做.

现在有一些更好的观点。

首先,ncharnvarchar始终使用 UCS-2 存储数据。这意味着每个字符将使用两个字节,并且基本多语言平面 (BMP) 中的任何 Unicode 字符都可以由 ncharnvarchar 字段存储。但是,不能存储 任何 Unicode 字符。例如,根据维基百科,埃及象形文字的代码点不在 BMP 范围内。因此,有可以用 UTF-8 表示的 Unicode 字符串和不能存储在 SQL Server ncharnvarchar 字段中的其他真正的 Unicode 编码,用埃及象形文字编写的字符串就是其中之一。幸运的是,您的用户可能不会在该脚本中编写代码,但请记住这一点!

其他张贴者强调的另一个令人困惑但有趣的一点是,如果排序规则代码页需要,charvarchar 字段可能对某些字符使用每个字符两个字节。 (Martin Smith 举了一个很好的例子,他展示了 Chinese_Traditional_Stroke_Order_100_CS_AS_KS_WS 如何表现出这种行为。检查一下。)

更新: 从 SQL Server 2012 开始,终于有了 code pages for UTF-16,例如 Latin1_General_100_CI_AS_SC,它可以真正覆盖整个 Unicode 范围。


s
sth

char:定长字符数据,最大长度为8000个字符。

nchar:固定长度的 unicode 数据,最大长度为 4000 个字符。

字符 = 8 位长度

NChar = 16 位长度


char 不能有 8 位长度。不必存储长度,固定长度最长可达8000个字符。
R
Rasel

nchar[(n)](民族特色)

固定长度的 Unicode 字符串数据。

定义字符串长度,并且必须是 1 到 4,000 之间的值。

存储大小是 n 字节的两倍。

nvarchar [(n | max)](民族性格各异。)

可变长度的 Unicode 字符串数据。

n 定义字符串长度,可以是 1 到 4,000 之间的值。

max 表示最大存储大小为 2^31-1 字节(2 GB)。

存储大小(以字节为单位)是输入数据实际长度的两倍 + 2 个字节

char [(n)](字符)

固定长度的非 Unicode 字符串数据。

n 定义字符串长度,并且必须是 1 到 8,000 之间的值。

存储大小为 n 字节。

varchar [(n | max)](字符不同)

可变长度、非 Unicode 字符串数据。

n 定义字符串长度,可以是 1 到 8,000 之间的值。

max 表示最大存储大小为 2^31-1 字节(2 GB)。

存储大小是输入数据的实际长度 + 2 个字节。


J
Jason Kresowaty

nchar(10) 是长度为 10 的固定长度 Unicode 字符串。nvarchar(10) 是最大长度为 10 的可变长度 Unicode 字符串。通常,如果所有数据值都是 10 个字符,则使用前者,后者如果长度不同。


错误的比较 - 问题涉及 nchar 和 varchar,而不是 nchar 和 nvarchar。
W
Wim ten Brink

The differences 是:

n[var]char 存储 unicode,而 [var]char 仅存储单字节字符。 [n]char 需要精确长度的固定数量的字符,而 [n]varchar 接受不超过定义长度的可变数量的字符。

另一个区别是长度。 nchar 和 nvarchar 都可以长达 4,000 个字符。 char 和 varchar 最长可达 8000 个字符。但是对于 SQL Server,您还可以使用 [n]varchar(max) 最多可以处理 2,147,483,648 个字符。 (2 GB,带符号的 4 字节整数。)


V
Venkataraman R

nchar 需要比 nvarchar 更多的空间。

例如,

一个 nchar(100) 将始终存储 100 个字符,即使您只输入 5,剩余的 95 个字符将用空格填充。在 nvarchar(100) 中存储 5 个字符将节省 5 个字符。


不完全正确,因为您需要用最多 100 个字符填充 char(100)。例如,当您在数据库中存储电话号码或具有固定长度的订单号码时,您将使用它。由于字段长度是固定的,因此您无法将其填充到最大字符数。但是,当您的所有数据是每条记录 100 个字符时,char(100) 将比 varchar(100) 占用更少的存储空间,因为它不需要长度指示:每个值正好是 100 个字符。
M
Manu

nchar 是固定长度的,可以保存 unicode 字符。它每个字符使用两个字节存储。

varchar 是可变长度的,不能保存 unicode 字符。它每个字符使用一个字节存储。


错误的。 Unicode 可以为每个字符使用 1 到 4 个字节(通常)。此外,varchar 可以保存 unicode,但它不被识别为 unicode。因此,对于 unicode 存储,varchar 被认为是不可靠的。 (特别是因为访问该字段的代码可能会错误地翻译它。)
@Alex:我认为你的观点是正确的,但我仍然不同意你的观点。您的意思是,如果 long 恰好小于 2^32,则 int 可以保持 long。这不仅“不可靠”,而且是一种固有的限制,无法覆盖整个价值范围。
@Workshop Alex:错了。编码为 UCS-2 的 Unicode(恰好是 SQL Server 使用的编码)将每个字符恰好存储在两个字节中,请参阅 msdn.microsoft.com/en-us/library/bb330962%28v=sql.90%29.aspx: SQL Server stores Unicode in the UCS-2 encoding scheme... UCS-2 is a fixed-length encoding that represents all characters as a 16-bit value (2 bytes)。 SQL Server 2008 可以使用 SCSU 压缩,但仍然是 UCS-2 编码的 Unicode 字符串的压缩:msdn.microsoft.com/en-us/library/ee240835.aspx
G
Gustavo Rubio

NVARCHAR 可以存储 Unicode 字符,每个字符占用 2 个字节。


错误的! Unicode 每个字符使用 1 到 4 个字节!很多人都忘记了!即使使用 UTF-16 也可能导致某些字符占用 4 个字节而不是 2 个字节,尽管常见的长度是 2 个字节。 Unicode 的某些其他子格式可能占用甚至超过 4 个字节!
@WimtenBrink - 问题是关于 SQL Server 和 nvarchar 每个字符总是占用 2 个字节。
@Wim,您是对的,Unicode 有几种编码可以产生不同数量的字节。但是 SQL Server 没有为您提供有关 Unicode 编码的选择。 2012 年之前的 SQL Server 仅使用 UCS-2,两个字节宽,因此 Martin 在写答案时是正确的。正如上面的其他答案所说,SQL Server 2012 现在提供 UTF-16,因此许多字符(Unicode 基本多语言平面中的字符)两个字节,其他字符四个字节。