提问人:stimms 提问时间:9/28/2008 最后编辑:Peter Mortensenstimms 更新时间:7/21/2022 访问量:1499820
varchar 和 nvarchar 有什么区别?
What is the difference between varchar and nvarchar?
答:
nVarchar 将帮助您存储 Unicode 字符。如果要存储本地化数据,这是要走的路。
nvarchar 将数据存储为 Unicode,因此,如果要在数据列中存储多语言数据(多种语言),则需要 N 变体。
varchar:可变长度、非 Unicode 字符数据。数据库排序规则确定使用哪个代码页存储数据。
nvarchar:可变长度的 Unicode 字符数据。依赖于数据库排序规则进行比较。
掌握了这些知识后,请使用与您的输入数据匹配的任何一个(ASCII v. Unicode)。
评论
float
int
我总是使用 nvarchar,因为它允许我正在构建的任何东西都能承受我扔给它的几乎任何数据。我的 CMS 系统是偶然的,因为我使用了 nvarchar。如今,任何新应用程序都不应该真正关心所需的空间量。
评论
"never"
你是对的。 存储 Unicode 数据,同时存储单字节字符数据。除了您已经提到的存储差异(需要两倍的存储空间)之外,首选的主要原因是国际化(即以其他语言存储字符串)。nvarchar
varchar
nvarchar
varchar
nvarchar
varchar
列可以存储任何 Unicode 数据。列限制为 8 位代码页。有些人认为应该使用它,因为它占用的空间更少。我相信这不是正确的答案。代码页不兼容是一种痛苦,而 Unicode 是解决代码页问题的良方。如今,由于磁盘和内存价格低廉,因此真的没有理由再浪费时间在代码页上乱七八糟了。nvarchar
varchar
varchar
所有现代操作系统和开发平台都在内部使用 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编码中。如果同一服务器上有其他数据库实例,您可能会受到它们的限制;反之亦然,因为您必须共享设置。此类字段可以存储可以使用该字符集进行编码的任何数据,而不能存储其他任何数据。例如,如果字符集是 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!它避免了限制和依赖关系,适用于存储空间,通常也最适合性能。
评论
nvarchar 主要存储 Unicode 字符,varchar 存储非 Unicode 字符。
“Unicodes”是指 16 位字符编码方案,允许将来自许多其他语言(如阿拉伯语、希伯来语、中文、日语)的字符编码为单个字符集。
这意味着 unicodes 每个字符使用 2 个字节来存储,而非 unicodes 每个字符仅使用一个字节来存储。这意味着与非 Unicode 相比,Unicode 需要双倍的存储容量。
我的两分钱
未使用正确的数据类型时,索引可能会失败: 在 SQL Server 中:
如果对 VARCHAR 列有索引并向其提供 Unicode 字符串,则 SQL Server 不会使用该索引。当您将 BigInt 呈现给包含 SmallInt 的索引列时,也会发生同样的事情。即使 BigInt 足够小,可以成为 SmallInt,SQL Server 也无法使用该索引。反之,您不会遇到此问题(当向索引的 BigInt 或 NVARCHAR 列提供 SmallInt 或 Ansi-Code 时)。数据类型可能因不同的 DBMS(数据库管理系统)而异:
要知道每个数据库的数据类型略有不同,并且 VARCHAR 并不意味着任何地方都一样。虽然 SQL Server 具有 VARCHAR 和 NVARCHAR,但 Apache/Derby 数据库只有 VARCHAR,而 VARCHAR 采用 Unicode。
评论
我不得不在这里说(我意识到我可能会向 slating 敞开心扉!),但可以肯定的是,唯一一次实际上比所有依赖系统和数据库本身中的所有排序规则都相同时更有用(注意那里更多!)......?如果不是,那么无论如何都必须进行排序规则转换,因此与 一样可行。NVARCHAR
VARCHAR
VARCHAR
NVARCHAR
除此之外,一些数据库系统,如 SQL Server(2012 年之前)的页面大小约为 8K。因此,如果您正在考虑存储未保存在 or 字段中的可搜索数据,那么将提供完整的 8k 空间,而仅提供 4k(双倍的字节,双倍的空间)。TEXT
NTEXT
VARCHAR
NVARCHAR
我想,总而言之,两者的使用都取决于:
- 项目或上下文
- 基础设施
- 数据库系统
遵循 Sql Server VARCHAR 和 NVARCHAR 数据类型之间的区别。在这里,你可以以一种非常描述性的方式看到。
通常nvarchar 将数据存储为 Unicode,因此,如果要在数据列中存储多语言数据(多种语言),则需要 N 变体。
评论
如果使用单个字节来存储字符,则有 256 种可能的组合,因此您可以保存 256 个不同的字符。排序规则是定义字符以及比较和排序字符的规则的模式。
1252,即拉丁语1(ANSI),是最常见的。单字节字符集也不足以存储许多语言使用的所有字符。例如,某些亚洲语言有数千个字符,因此每个字符必须使用两个字节。
Unicode 标准
当在网络中使用使用多个代码页的系统时,管理通信变得困难。为了标准化,ISO 和 Unicode 联盟引入了 Unicode。Unicode 使用两个字节来存储每个字符。也就是说,可以定义 65,536 个不同的字符,因此几乎所有字符都可以用 Unicode 覆盖。如果两台计算机使用 Unicode,则每个符号都将以相同的方式表示,并且不需要转换 - 这就是 Unicode 背后的想法。
SQL Server 有两类字符数据类型:
- 非 Unicode(char、varchar 和 text)
- Unicode(nchar、nvarchar 和 ntext)
如果我们需要保存来自多个国家/地区的字符数据,请始终使用 Unicode。
虽然存储Unicode,但您应该考虑借助排序规则,也可以使用和保存本地语言的数据。NVARCHAR
VARCHAR
想象一下以下场景。
数据库的排序规则是波斯语,并且在数据类型中保存一个值,例如“علی”(阿里的波斯语写作)。没有问题,DBMS只使用三个字节来存储它。VARCHAR(10)
但是,如果要将数据传输到另一个数据库并查看正确的结果,则目标数据库必须具有与目标相同的排序规则,在本例中为波斯语。
如果目标排序规则不同,则会在目标数据库中看到一些问号 (?)。
最后,请记住,如果您使用的是用于本地语言的大型数据库,我建议您使用位置而不是使用太多空格。
我相信设计可以有所不同。这取决于您工作的环境。
我看了一下答案,许多人似乎建议使用 over,因为空间不再是问题,因此启用 Unicode 以获得很少的额外存储空间并没有什么坏处。好吧,当您想在列上应用索引时,这并不总是正确的。SQL Server 对可编制索引的字段的大小限制为 900 个字节。因此,如果您有一个,您仍然可以索引它,但不能.使用 时,字符数减半,因此最多可以编制索引。因此,如果您确信自己不需要,我不建议使用它。nvarchar
varchar
varchar(900)
varchar(901)
nvarchar
nvarchar(450)
nvarchar
一般来说,在数据库中,我建议坚持使用您需要的大小,因为您始终可以扩展。例如,一位同事曾经认为,使用色谱柱没有坏处,因为我们的存储完全没有问题。后来,当我们尝试对此列应用索引时,SQL Server 拒绝了这一点。但是,如果他从 even 开始,我们可以简单地将其扩展到我们需要的内容,而不会出现这样的问题,这需要我们制定一个现场迁移计划来解决这个问题。nvarchar(max)
varchar(5)
和 之间的主要区别在于:Varchar(n)
nvarchar(n)
Varchar
(可变长度、非 Unicode 字符数据)大小最大为 8000。
- 它是一种可变长度数据类型
- 用于存储非 Unicode 字符
- 每个字符占用 1 个字节的空间
Nvarchar
:可变长度的 Unicode 字符数据。
- 它是一种可变长度数据类型
- 用于存储 Unicode 字符。
- 数据以 Unicode 编码存储。每 支持语言。(例如阿拉伯语、德语、印地语等语言)
nvarchar
为了使我们的代码没有错误(类型不匹配),使用起来是安全的,因为也允许 Unicode 字符。
当我们在 SQL Server 查询中使用条件并且使用运算符时,它会多次抛出错误。可能的原因是我们的映射列将在 中定义。如果我们在这个问题中定义它,我不会发生。尽管如此,我们仍然坚持并避免这个问题,我们最好使用关键字而不是.varchar
nvarchar
where
=
varchar
nvarchar
varchar
LIKE
=
评论
声誉评分为 ~47000 的 Jeffrey L Whitledge 建议使用 nvarchar
声誉得分为 ~33200 的 Solomon Rutzky 建议:不要总是使用 NVARCHAR。这是一种非常危险,而且往往代价高昂的态度/方法。
varchar 和 nvarchar SQL Server 数据类型之间的主要性能差异是什么?
https://www.sqlservercentral.com/articles/disk-is-cheap-orly-4
两人都有这么高的声誉,一个学习SQL Server数据库的开发人员会选择什么呢?
如果选择不一致,则在有关性能问题的答案和评论中会有许多警告。
有评论赞成/反对 nvarchar 的性能。
有评论赞成/反对 varchar 的性能。
我对包含数百列的表有特殊要求,这本身可能很不寻常?
我选择 varchar 是为了避免接近 SQL*server 2012 的 8060 字节表记录大小限制。
对我来说,使用 nvarchar 超出了这个 8060 字节的限制。
我还认为我应该将相关代码表的数据类型与主中心表的数据类型相匹配。
我曾看到,在南澳大利亚州政府这个工作地点,以前有经验的数据库开发人员使用了 varchar 列,其中表行数将达到数百万或更多(在这些非常大的表中,如果有的话,nvarchar 列很少),所以也许预期的数据行量成为这个决定的一部分。
自 SQL Server 2019 以来,varchar 列支持 UTF-8 编码。
因此,从现在开始,区别在于大小。
在转化为速度差异的数据库系统中。
更少的数据 = 更少的 IO + 更少的内存 = 更高的速度。阅读上面的文章了解数字。
从现在开始,在 UTF8 中使用 varchar!
仅当您的数据百分比很大,字符范围在 2048 - 16383 和 16384 – 65535 之间时,您才必须进行测量
评论
varchar
仅用于另一方面,用于 和 字符。它们之间的其他一些区别如下。non-Unicode characters
nvarchar
unicode
non-unicode
VARCHAR 与 NVARCHAR
瓦尔查尔 | 内瓦查尔 | |
---|---|---|
字符数据类型 | 可变长度、非 Unicode 字符 | 可变长度,Unicode 和非 Unicode 字符,如日语、朝鲜语和中文。 |
最大长度 | 为止8,000 characters |
为止4,000 characters |
字符大小 | 每个字符占用1 byte |
占用每个 Unicode/非 Unicode 字符2 bytes |
存储大小 | 实际长度(以字节为单位) | 实际长度的 2 倍(以字节为单位) |
用法 | 当数据长度为可变或可变长度列时使用,并且实际数据始终小于容量 | 由于仅存储,仅当需要 Unicode 支持(如日语汉字或朝鲜韩文字符)时才使用。 |
varchar 适用于存储非 unicode,这意味着有限的字符。虽然 nvarchar 是 varchar 的超集,因此除了我们可以使用 varchar 存储哪些字符外,我们还可以在不忽略函数的情况下存储更多字符。
有人评论说,现在存储/空间不是问题。即使空间对一个人来说不是问题,确定最佳数据类型也应该是一个要求。
这不仅与存储有关!“数据移动”,你就会明白我想要去哪里!
与此线程中的一些过时的答案相反,varchar 可以存储 Unicode 字符,如果您想使用 UTF-8,这也是您的不二之选。 解决方案是将数据库排序规则设置为Latin1_General_100_CI_AS_SC_UTF8
CREATE DATABASE [TestUTF-8] COLLATE Latin1_General_100_CI_AS_SC_UTF8
GO
USE [TestUTF-8]
GO
-- using varchar works
DECLARE @XML xml = '<?xml version="1.0" encoding="utf-8"?>
<test>
<status>Success ✅</status>
</test>
'
-- using nvarchar will fail (XML parsing: line 1, character 38, unable to switch the encoding)
-- DECLARE @XML xml = N'<?xml version="1.0" encoding="utf-8"?>
-- <test>
-- <status>Success ✅</status>
-- </test>
-- '
SELECT [status] = c.c.value('(./status)[1]', 'varchar(max)')
FROM @XML.nodes('/test') c(c)
评论