varchar和nvarchar有什么区别?

仅仅是nvarchar支持多字节字符吗?如果是这样,除了存储问题之外,使用varchars真的有任何意义吗?

1379796 次浏览

nVarchar将帮助您存储Unicode字符。如果您想存储本地化数据,这是可行的方法。

nvarchar将数据存储为Unicode,因此,如果您要在数据列中存储多语言数据(多种语言),则需要N个变体。

var char:可变长度的非Unicode字符数据。数据库排序规则确定数据存储使用的代码页。

n var char:可变长度的Unicode字符数据。依赖于数据库排序规则进行比较。

有了这些知识,使用与您的输入数据匹配的任何一个(ASCII v. Unicode)。

我总是使用nvarchar,因为它允许我构建的任何东西都能承受我扔给它的任何数据。我的CMS系统偶然使用中文,因为我使用了nvarchar。如今,任何新的应用程序都不应该真正关心所需的空间量。

你是对的。nvarchar存储Unicode数据,而varchar存储单字节字符数据。除了存储差异(nvarchar需要两倍于varchar的存储空间),你已经提到了,选择nvarchar而不是varchar的主要原因是国际化(即存储其他语言的字符串)。

nvarchar列可以存储任何Unicode数据。varchar列仅限于8位代码页。有些人认为应该使用varchar,因为它占用的空间更少。我相信这不是正确的答案。代码页不兼容是一种痛苦,Unicode是解决代码页问题的方法。如今磁盘和内存都很便宜,真的没有理由再浪费时间在代码页上了。

所有现代操作系统和开发平台都在内部使用Unicode。通过使用nvarchar而不是varchar,您可以避免每次读取或写入数据库时进行编码转换。转换需要时间,并且容易出错。从转换错误中恢复是一个不平凡的问题。

如果您正在与仅使用ASCII的应用程序交互,我仍然建议在数据库中使用Unicode。操作系统和数据库排序算法将更好地与Unicode一起工作。Unicode在与其他系统交互时避免了转换问题。您将为未来做好准备。您可以始终验证您的数据对于您必须维护的任何遗留系统都被限制为7位ASCII,即使在享受完整Unicode存储的一些好处的同时。

我会说,这取决于。

如果你开发一个桌面应用程序,其中操作系统使用Unicode(就像所有当前的Windows系统一样)并且语言本身支持Unicode(默认字符串是Unicode,就像Java或C#一样),那么去nvarchar。

如果您开发一个Web应用程序,其中字符串以UTF-8的形式出现,并且语言是PHP,它本身仍然不支持Unicode(在5. x版本中),那么varchar可能是更好的选择。

这取决于Oracle的安装方式。在安装过程中,会设置NLS_CHARACTERSET选项。您可以通过查询SELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET'找到它。

如果您的NLS_CHARACTERSET是像UTF8这样的Unicode编码,那就太好了。使用VARCHAR和NVARCHAR几乎是相同的。现在停止阅读,继续阅读。否则,或者如果您无法控制Oracle字符集,请继续阅读。

VARCHAR-数据以NLS_CHARACTERSET编码存储。如果同一服务器上有其他数据库实例,您可能会受到它们的限制;反之亦然,因为您必须共享设置。

NVARCHAR-数据以Unicode编码存储。支持每种语言。好主意。

存储空间呢?VARCHAR通常是有效的,因为字符集/编码是为特定区域设置定制的。NVARCHAR字段以UTF-8或UTF-16编码存储,具有讽刺意味的是,基于NLS设置。UTF-8对“西方”语言非常有效,同时仍然支持亚洲语言。UTF-16对亚洲语言非常有效,同时仍然支持“西方”语言。如果担心存储空间,请选择NLS设置使Oracle根据需要使用UTF-8或UTF-16。

处理速度怎么样?大多数新的编码平台原生使用Unicode(Java,. NET,甚至C++std::wstring从几年前!),所以如果数据库字段是VARCHAR,它会强制Oracle在每次读写时在字符集之间转换,不太好。使用NVARCHAR避免了转换。

底线:使用NVARCHAR!它避免了限制和依赖关系,适合存储空间,通常也最适合性能。

主要nvarchar存储Unicode字符,varchar存储非Unicode字符。

“Unicode”是指16位字符编码方案,允许来自许多其他语言(如阿拉伯语,希伯来语,中文,日语)的字符以单个字符集编码。

这意味着Unicode每个字符使用2个字节来存储,而非Unicode每个字符仅使用1个字节来存储。这意味着与非Unicode相比,Unicode需要双倍的存储容量。

我的两分钱

  1. 索引在不使用正确的数据类型时可能会失败:
    在SQL服务器中:当您在VARCHAR列上有一个索引并为其提供一个Unicode字符串时,SQL服务器不会使用该索引。当您向包含SmallInt的索引列提供BigInt时,也会发生同样的事情。即使BigInt足够小,可以成为SmallInt,SQL服务器也无法使用该索引。另一种方法没有这个问题(当向索引的BigInt ot NVARCHAR列提供SmallInt或Ansi-Code时)。

  2. 不同DBMS(数据库管理系统)之间的数据类型可能不同:
    要知道每个数据库都有略微不同的数据类型,VARCHAR并不意味着到处都一样。虽然SQL服务器有VARCHAR和NVARCHAR,但Apache/Derby数据库只有VARCHAR,而VARCHAR是Unicode中的。

我必须在这里说(我意识到我可能会对自己敞开心扉!),但可以肯定的是,只有当NVARCHAR实际上更多有用时(注意那里的更多!)而不是VARCHAR时,所有依赖系统和数据库本身中的所有排序规则都是相同的……?如果不是,那么排序规则转换无论如何都必须发生,因此使VARCHARNVARCHAR一样可行。

除此之外,一些数据库系统,例如SQL服务器(2012年之前)的页面大小约为8K。因此,如果您希望存储可搜索的数据,而不是保存在TEXTNTEXT字段中,那么VARCHAR提供了完整8k的空间,而NVARCHAR只提供了4k(字节翻倍,空间翻倍)。

我想,总结一下,使用任何一个都取决于:

  • 项目或背景
  • 基础设施
  • 数据库系统

按照Sql Server VARCHAR和NVARCHAR数据类型之间的区别。在这里你可以看到一个非常描述性的方式。

在Generalnvarchar中,数据存储为Unicode,因此,如果您要在数据列中存储多语言数据(多种语言),则需要N个变体。

如果使用一个字节来存储一个字符,则有256种可能的组合,因此您可以保存256个不同的字符。排序规则是定义字符的模式以及对它们进行比较和排序的规则。

1252是最常见的Latin1(ANSI)。单字节字符集也不足以存储许多语言使用的所有字符。例如,一些亚洲语言有数千个字符,所以它们必须使用每个字符两个字节。

Unicode标准

当使用多个代码页的系统在网络中使用时,管理通信变得困难。为了标准化,ISO和Unicode联盟引入了Unicode。Unicode使用两个字节来存储每个字符。也就是说,可以定义65,536个不同的字符,因此几乎所有的字符都可以用Unicode覆盖。如果两台计算机使用Unicode,每个符号都将以相同的方式表示,不需要转换——这就是Unicode背后的想法。

SQL服务器有两类字符数据类型:

  • 非Unicode(char、varchar和text)
  • Unicode(nchar、nvarchar和ntext)

如果我们需要保存来自多个国家的字符数据,请始终使用Unicode。

虽然NVARCHAR存储Unicode,但您应该考虑通过排序规则的帮助,您也可以使用VARCHAR并保存本地语言的数据。

想象一下下面的场景。

您的数据库的排序规则是波斯语的,并且您在VARCHAR(10)数据类型中保存了一个类似 'علی' (波斯语写入阿里)的值。没有问题,DBMS只使用三个字节来存储它。

但是,如果您想将数据传输到另一个数据库并查看正确的结果,您的目标数据库必须具有与此示例中的目标波斯语相同的排序规则。

如果您的目标排序规则不同,您会在目标数据库中看到一些问号(?)。

最后,请记住,如果您使用的是一个用于使用本地语言的大型数据库,我建议使用位置而不是使用太多空格。

我相信设计可以不同。这取决于你工作的环境。

我看了一下答案,许多人似乎建议使用nvarchar而不是varchar,因为空间不再是问题,所以启用Unicode以获得少量额外存储没有坏处。嗯,当你想在你的列上应用索引时,这并不总是正确的。SQLServer对你可以索引的字段的大小有900个字节的限制。所以如果你有一个varchar(900),你仍然可以索引它,但不是varchar(901)。使用nvarchar,字符数减半,所以你可以索引到nvarchar(450)。所以如果你确信你不需要nvarchar,我不建议使用它。

一般来说,在数据库中,我建议保持需要的大小,因为你总是可以扩展的。例如,工作中的一个同事曾经认为一个列使用nvarchar(max)没有坏处,因为我们的存储根本没有问题。后来,当我们试图对这个列应用索引时,SQLServer拒绝了这一点。但是,如果他从varchar(5)开始,我们可以简单地将其扩展到我们需要的大小,而不会出现这样的问题,并且需要我们做一个字段迁移计划来解决这个问题。

Varchar(n)nvarchar(n)的主要区别是:

在此处输入图片描述

Varchar(可变长度,非Unicode字符数据)大小最多为8000。

  1. 它是一种可变长度的数据类型
  2. 用于存储非Unicode字符
  3. 为每个字符占用1个字节的空间

在此处输入图片描述

Nvarchar:可变长度的Unicode字符数据。

  1. 它是一种可变长度的数据类型
  2. 用于存储Unicode字符。
  3. 数据以Unicode编码存储。每个支持语言(例如阿拉伯语,德语,印地语等语言)

为了使我们的代码没有错误(类型不匹配),与varchar相比,nvarchar是安全的,因为nvarchar也允许Unicode字符。当我们在SQL服务器查询中使用where条件时,如果我们使用=运算符,它会抛出一些错误。可能的原因是我们的映射列将在varchar中定义。如果我们在nvarchar中定义它,这个问题就不会发生。仍然我们坚持varchar并避免这个问题,我们最好使用LIKE关键字而不是=

杰弗里L惠特利奇与~47000声誉评分建议使用nvarchar

声誉评分为~33200的所罗门·鲁茨基建议:不要总是使用NVARCHAR。这是一种非常危险的,而且往往代价高昂的态度/方法。

varchar和nvarcharSQL服务器数据类型之间的主要性能差异是什么?

https://www.sqlservercentral.com/articles/disk-is-cheap-orly-4

两个人都有这么高的声誉,一个学习sql服务器数据库的开发人员会选择什么?

如果您的选择不一致,则在答案和评论中会有许多关于性能问题的警告。

有评论pro/con nvarchar的性能。

有评论pro/con varchar的性能。

我对包含数百列的表有一个特殊的要求,这本身可能是不寻常的?

我选择varchar是为了避免接近SQL*server 2012的8060字节表记录大小限制。

对我来说,使用nvarchar超过了这个8060字节的限制。

我还认为应该将相关代码表的数据类型与主中心表的数据类型相匹配。

我已经看到在这个工作场所,南澳大利亚政府,以前有经验的数据库开发人员使用varchar列,其中表行数将达到数百万或更多(在这些非常大的表中,很少有nvarchar列,如果有的话),所以可能预期的数据行量成为这个决定的一部分。

SQLServer 2019 varchar列支持UTF-8编码。

因此,从现在开始,区别在于大小。

在转换为速度差异的数据库系统中。

更少的数据=更少的IO+更少的内存=一般来说更快。阅读上面的文章了解数字。

VARCHAR在UTF8从现在开始!

只有当您的数据很大比例的字符范围为2048-16383和16384-65535时,您才必须测量

varchar仅用于non-Unicode characters,而nvarchar用于unicodenon-unicode字符。下面给出了它们之间的一些其他区别。

VARCHAR vs. NVARCHAR

存储大小
VARCHARNVARCHAR
字符数据类型可变长度,非Unicode字符可变长度,包括Unicode和非Unicode字符,例如日语、韩语和中文。
最大长度8,000 characters4,000 characters
字符大小每个字符占用1 byte每个Unicode/非Unicode字符占用2 bytes
存储大小实际长度(以字节为单位)2倍实际长度(以字节为单位)
用法当数据长度是可变的或可变长度的列时使用,如果实际数据总是小于容量由于仅用于存储,仅在需要Unicode支持时使用,例如日语汉字或韩语韩语字符。

varchar适合存储非Unicode,这意味着有限的字符。而nvarchar是varchar的超集,因此我们可以使用varchar存储哪些字符,我们可以存储更多而不会忽略功能。

有人评论说,存储/空间现在不是问题。即使空间不是一个问题,识别最佳数据类型也应该是一个要求。

这不仅仅是关于存储!“数据移动”,你知道我在哪里!