varchar和nvarchar有什么区别?

sti*_*mms 1300 sql-server varchar nvarchar

它只nvarchar支持多字节字符吗?如果是这种情况,除了存储问题之外,还有什么意义varchars吗?

Jef*_*dge 1586

nvarchar列可以存储任何Unicode数据.甲varchar柱被限制为一个8位的代码页.有些人认为varchar应该使用它,因为它占用的空间更少.我相信这不是正确的答案.代码页不兼容性很痛苦,Unicode可以解决代码页问题.现在有了廉价的磁盘和内存,实际上没有理由浪费时间来处理代码页了.

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

如果您与仅使用ASCII的应用程序连接,我仍然建议在数据库中使用Unicode.操作系统和数据库整理算法将更好地与Unicode一起使用.Unicode避免了与其他系统连接时的转换问题.你将为未来做准备.您可以随时验证您的数据是否仅限于7位ASCII,以用于您必须维护的任何遗留系统,即使在享受完整Unicode存储的一些优势的同时也是如此.

  • @MatthewPatrickCashatt - 你可以这样看.但是如果你想象一个光荣的世界,其中所有*文本数据都是Unicode,并且开发人员根本不需要考虑某些内容的编码,并且根本不会发生一整类错误,那么你可以看到根本没有选择. (129认同)
  • [varchar不限于所有归类中的8位代码页](http://stackoverflow.com/a/8250586/73226) (15认同)
  • @PeterAllenWebb - 您可以"存储"任何Unicode数据,因为UTF-16中的代理项对可以存储在UCS-2中,就像它们是字符一样.这将对数据存储和检索透明地工作.现在,您不能做的是在BMP之外获得可靠的案例转换和比较,但我没有对此做出任何声明.因此,如果您有许多要进行处理的Desseret文本,最好在数据库之外执行此操作.但是把它存放在那里就好了.(当然,varchar也不会帮助你!) (9认同)
  • 这是很好的信息.如果我推断选择最终会成为 - 哪种资源更便宜:处理器+开发开销还是存储? (8认同)
  • @Martin Smith - 在这些情况下,varchar带来的微小优势(紧凑型存储)消失了.我猜varchar甚至比我想象的还要糟糕! (8认同)
  • @iValueValue - 所以他们提倡代码页作为数据压缩的手段?如果我要压缩数据,我希望以不损害数据完整性的方式这样做.有很多方法可以做到这一点而不会破坏你的角色数据,因为它会在代码页转换中被破坏.UTF-8将是一个良好的开端. (5认同)
  • @iValueValue - 此外,数据仓库设计一般不会出现在偶尔1GB"浪费"的地方.典型的星型模式旨在通过对数据进行去标准化来浪费*吨*空间.我不喜欢这样的方案,因为它们是对完美的RDBMS系统的误用.但是,假设这样做是个好主意,一旦你决定放弃数据仓库的良好关系数据库设计,拥有大量未压缩的数据几乎不是一个开始担心的问题. (5认同)
  • @PRMan - 您没有说明您的数据库存储了哪种数据,但如果包含人员或地名,那么一个简单的事实就是没有单个(非Unicode)代码页覆盖数据所需的所有字符是正确的.即使对于美国或英国也是如此.当你说你从未有过任何不正确之处时,我想知道你是怎么知道的.你是说由于编码错误,系统从未停止过?我会接受的.你是说没有人抱怨过这个系统会破坏他们的名字吗?我也会接受. (5认同)
  • @PawBaltzersen - 听起来对我来说是正确的.显然,读取400,000个字节所需的时间比读取200,000个字节要长.nvarchar版本没有花费两倍的事实可能部分解释了执行代码页转换所需的额外时间.然而,我的论点并不是Unicode更快.我的论点是它是正确的.对我来说,每次都要快速纠正王牌. (4认同)
  • @JeffreyLWhitledge:评论#1:您认为您的答案是否仍然适用于数据仓库目的?[此页面](http://msdn.microsoft.com/en-us/library/hh146876.aspx) 上的文档建议“仅当值的范围跨越或将跨越多种语言时才使用 nchar 和 nvarchar。”` . 出于数据仓库的目的,不应该考虑磁盘 I/O 和网络带宽吗? (3认同)
  • @JeffreyLWhitledge :评论 #2 :如果你认为 ([link](http://sqlanywhere-forum.sybase.com/questions/9232/sql-anywhere-millionbillion-row-scenario))`“有 10 亿行,每行每个浪费的字节都会花费您 1GB,您还必须备份、恢复和索引。”`您是否仍然认为代码页不兼容是数据类型选择/选择的决定因素? (3认同)
  • 我看到的性能与此完全相反。读取 2k nvarchars 比读取 2k varchars 慢大约三分之一。我正在使用 SSD 来最小化 i/o。所以转换比 i/o 快很多,这在我看来是有道理的,因为转换不依赖于 i/o,而且 i/o 永远是所有这一切中最慢的部分。 (3认同)
  • (续)你是说没有人放弃试图正确输入他们的名字而只是接受了发生的破坏?这可能不会发生.但如果有,那么你无从知晓.我提交你可能不知道你的数据库中有哪些错误.机器保持嗡嗡声,所以数据很好.我还打赌你用白炽灯泡看你的印刷报纸,这一切都很有效. (3认同)
  • "nvarchar列可以存储任何Unicode数据." 虽然很容易从大多数MSSQL文档中获得这种印象,但事实并非如此.内部使用的编码是UCS-2,它只能存储Unicode的"基本多语言平面"中的数据.此平面外的字符无法直接存储在nchar或nvarchar字段中,无需额外处理. (2认同)
  • 在我工作的地方,我们有12000个数据库,每个数据库都有数百万行。这些数据库仅在美国和英国运行。将您正在谈论的那种钱花在存储上是不存在的“正确性”,这很荒谬。我们从来没有过“不正确”的事情。 (2认同)
  • 杰弗里,您能给我们提供一些例子吗?在我所在的地区(斯堪的纳维亚半岛),最关心的通常是选择正确的排序规则(以正确的顺序获得 æ/ä,ø/ö,å)。Varchar 可以很好地存储我们的特殊字符(尽管是两个字节)。由于大约 90-95% 的字符通常是纯 ascii,因此如果我们使用 nvarchar,则意味着近 50% 的字符字段存储零。在我工作的地方,我们实际上确实切换到了 nvarchar,我们的硬件人员提出的第一个问题是“为什么数据库现在的大小是平时的两倍?”。我怀疑我们的举动是一个错误,我很想了解其他情况。 (2认同)

use*_*116 251

varchar:可变长度的非Unicode字符数据.数据库排序规则确定使用哪个代码页存储数据.

nvarchar:可变长度的Unicode字符数据.取决于数据库排序规则进行比较.

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

  • 所以,你知道......它不起作用.这就像将`float`存储到`int`并继续,"确保小数点丢失." 只是不要. (8认同)
  • 是否存在像varchar这样的限制无法存储Unicode数据?它的全部是1和0.我可以将中文内容保存为varchar就好了.我只是指定了它的UTF-8.那怎么工作呢? (5认同)
  • @Nishant迟到_answer_:当然你可以在UTchar中存储UTF-8,但它会破坏SQL Server字符串函数.如果您在应用程序中执行所有搜索/转换,那么您可以这样做(但有什么好处?).只有SS支持的Unicode编码是UCS-2(是的,不是SS2k16之前的UTF-16),并且其字符串函数仅适用于该编码.BTW指数怎么样?如果要存储任意数据,最好使用二进制代码. (3认同)

tag*_*s2k 65

我总是使用nvarchar,因为它允许我正在构建的任何数据,以承受我投入的任何数据.我的CMS系统偶然会中文,因为我使用的是nvarchar.如今,任何新应用程序都不应该真正关注所需的空间量.

  • 为了冒昧地在tags2k的口中说出话题,我认为更准确的说法可能是"任何新的应用程序都应该更加关注所需的空间而不是关于国际化和其他字符集问题". (60认同)
  • 新应用程序不应该关注空间限制的想法有点短视,任何处理中大型企业级数据库的人都会很乐意告诉你,完全不正确. (23认同)
  • @ganders哈尔!你就在那里.广义陈述充其量只是暂时正确的.计算绝对是一个波动和迂回的游戏.我非常关心我在Windows Azure CCP上使用了多少空间.这就是说我"永远不会"在nvarchar上使用varchar.哦,我只是自相矛盾? (3认同)
  • “如今,任何新应用都不应该真正关心所需的空间量。” - 除非您使用免费的云存储,否则付费计划是 $ 可观的跳跃(请参阅 AppHarbor SQL Server 共享计划)。 (2认同)

Jer*_*ank 29

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

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

VARCHAR - 数据存储在NLS_CHARACTERSET编码中.如果同一服务器上有其他数据库实例,则可能受其限制; 反之亦然,因为你必须分享设置.这样的字段可以存储可以使用该字符集编码的任何数据,而不存储其他任何数据.因此,例如,如果字符集是MS-1252,则只能存储英文字母,少数重音字母和其他一些字符(如€和 - ).您的应用程序仅对少数区域设置有用,无法在世界其他任何地方运行.出于这个原因,它被认为是一个坏主意.

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!它避免了限制和依赖性,适用于存储空间,通常也最适合性能.

  • 这是一个非常好的答案,除了问题是关于sql-server. (38认同)

Ale*_*osh 28

自 SQL Server 2019 起,varchar 列支持 UTF-8 编码。

\n

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

\n

在数据库系统中,这会转化为速度上的差异。

\n

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

\n

从现在开始,使用UTF8 的 varchar!

\n

仅当您有很大比例的数据的字符范围为 2048 - 16383 和 16384 \xe2\x80\x93 65535 - 您才必须测量

\n

  • 一个被严重低估的答案。我想知道有多少新数据库将使用 nvarchar,因为工程师只阅读了 2008 年的最佳答案。 (3认同)

Ama*_*ndo 28

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

VARCHAR 与 NVARCHAR

VARCHAR NVARCHAR
字符数据类型 可变长度、非 Unicode 字符 可变长度,包括 Unicode 和非 Unicode 字符,例如日语、韩语和中文。
最大长度 取决于8,000 characters 取决于4,000 characters
字符尺寸 1 byte每个字符占用 占用2 bytes每个 Unicode/非 Unicode 字符
存储大小 实际长度(以字节为单位) 2 倍实际长度(以字节为单位)
用法 当数据长度为可变长度或可变长度列并且实际数据始终小于容量时使用 由于仅用于存储,仅在需要 Unicode 支持(例如日语汉字或韩语朝鲜文字符)时使用。


alb*_*ein 18

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


小智 14

我的两分钱

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

  2. 数据类型可以在不同的DBMS(数据库管理系统)之间变化:
    知道每个数据库的数据类型略有不同,而VARCHAR并不意味着在任何地方都是相同的.虽然SQL Server具有VARCHAR和NVARCHAR,但Apache/Derby数据库仅具有VARCHAR,而VARCHAR具有Unicode.


小智 13

主要是nvarchar存储Unicode字符,varchar存储非Unicode字符.

"Unicodes"意味着16位字符编码方案,允许来自许多其他语言(如阿拉伯语,希伯来语,中文,日语)的字符在单个字符集中编码.

这意味着unicodes每个字符使用2个字节进行存储,非单元只使用每个字符一个字节进行存储.这意味着与非unicode相比,unicodes需要双倍的存储容量.


Mik*_*oss 9

你是对的.nvarchar存储Unicode数据,同时varchar存储单字节字符数据.除了存储差异(nvarchar需要两倍的存储空间varchar),您已经提到的,主要原因宁愿nvarcharvarchar将国际化(在其他语言中即存储字符串).


小智 9

我会说,这取决于.

如果您开发一个桌面应用程序,其中操作系统以Unicode工作(如所有当前的Windows系统),并且语言本身支持Unicode(默认字符串是Unicode,如Java或C#),那么请转到nvarchar.

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


Vij*_* VP 7

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


小智 7

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

想象一下以下场景.

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

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

如果目标归类不同,则会在目标数据库中看到一些问号(?).

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

我相信设计可能会有所不同.这取决于您所处理的环境.


Jit*_*aji 6

如果使用单个字节存储字符,则有256种可能的组合,因此您可以保存256个不同的字符.排序规则是定义字符和比较和排序规则的模式.

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

Unicode标准

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

SQL Server有两类字符数据类型:

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

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


Raf*_*fid 6

我有一个看问题的答案,许多人似乎建议使用nvarcharvarchar,因为空间不是一个问题了,所以在启用Unicode进行一些额外的存储没有坏处.嗯,当你想在列上应用索引时,情况并非总是如此.SQL Server对您可以索引的字段大小的限制为900字节.所以,如果你有一个,varchar(900)你仍然可以索引它,但不是varchar(901).使用时nvarchar,字符数减半,因此您可以索引到最多nvarchar(450).因此,如果您确信自己不需要nvarchar,我建议您不要使用它.

一般来说,在数据库中,我建议坚持你需要的大小,因为你总是可以扩展.例如,一位工作的同事曾经认为使用nvarchar(max)色谱柱没有任何害处,因为我们对存储没有任何问题.稍后,当我们尝试在此列上应用索引时,SQL Server拒绝了此操作.但是,如果他从均匀开始varchar(5),我们可以简单地将其扩展到我们需要的东西,而不会出现需要我们执行现场迁移计划来解决此问题的问题.


Deb*_*ash 6

Varchar(n)和之间的主要区别nvarchar(n)是: 在此处输入图片说明

Varchar(可变长度,非Unicode字符数据)大小最大为8000。1.它是可变长度数据类型

  1. 用于存储非Unicode字符

  2. 每个字符占用1个字节的空间

在此处输入图片说明

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

1.这是一个可变长度的数据类型

2.用于存储Unicode字符。

  1. 数据以Unicode编码存储。支持每种语言。(例如,阿拉伯语,德语,印地语等语言)


Pau*_*aul 5

我必须在这里说(我意识到我可能要对自己敞开心!!),但是可以肯定的是,唯一一次NVARCHAR实际上比所有排序规则都更有用的地方(注意那里更多!)VARCHAR依赖系统和数据库本身内部是相同的...?如果不是这样,则无论如何都必须进行归类转换,因此它VARCHAR与一样可行NVARCHAR

除此之外,某些数据库系统(例如SQL Server(2012年之前))的页面大小约为。8K。因此,如果您要存储未存储在诸如a TEXTNTEXTfield之类的内容中的可搜索数据,则VARCHAR可以提供全部8k的空间,而NVARCHAR仅提供4k(双字节,双倍空间)。

概括地说,我想其中之一的使用取决于:

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


Pra*_*ani 5

遵循Sql Server VARCHAR和NVARCHAR数据类型之间的区别.在这里你可以用一种非常描述的方式看到.

Generalnvarchar将数据存储为Unicode,因此,如果要在数据列中存储多语言数据(多种语言),则需要N变量.


All*_*n F 5

信誉得分约为 47000 的 Jeffrey L Whitledge 推荐使用 nvarchar

Solomon Rutzky 的声誉得分约为 33200 建议:不要总是使用 NVARCHAR。这是一种非常危险且通常代价高昂的态度/方法。

varchar 和 nvarchar SQL Server 数据类型之间的主要性能差异是什么?

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

这么有名气的两个人,学习sql server数据库的开发者选择什么?

如果您的选择不一致,那么关于性能问题的答案和评论中有很多警告。

有关于性能的评论 pro/con nvarchar。

有关于性能的赞成/反对 varchar 评论。

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

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

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

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

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