只是nvarchar
支持多字节字符吗?如果是这样的话,除了存储问题之外,使用 真的有什么意义varchars
吗?
20 回答
列可以nvarchar
存储任何 Unicode 数据。一varchar
列仅限于 8 位代码页。有些人认为varchar
应该使用它,因为它占用的空间更少。我相信这不是正确的答案。代码页不兼容是一件痛苦的事,而 Unicode 是解决代码页问题的方法。现在有了便宜的磁盘和内存,真的没有理由再浪费时间在代码页上乱搞了。
所有现代操作系统和开发平台都在内部使用 Unicode。通过使用nvarchar
而不是varchar
,您可以避免每次读取或写入数据库时进行编码转换。转换需要时间,并且容易出错。从转换错误中恢复是一个不平凡的问题。
如果您正在与仅使用 ASCII 的应用程序交互,我仍然建议在数据库中使用 Unicode。操作系统和数据库排序算法将更好地与 Unicode 配合使用。Unicode 在与其他系统交互时避免了转换问题。你将为未来做准备。对于您必须维护的任何遗留系统,您始终可以验证您的数据是否仅限于 7 位 ASCII,即使在享受完整 Unicode 存储的一些好处的同时。
我总是使用 nvarchar,因为它允许我正在构建的任何东西承受我扔给它的几乎任何数据。我的 CMS 系统不小心做了中文,因为我使用了 nvarchar。如今,任何新应用程序都不应该真正关心所需的空间量。
这取决于 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,因此,如果您要在数据列中存储多语言数据(多于一种语言),则需要 N 变体。
我的两分钱
如果不使用正确的数据类型,索引可能会失败:
在 SQL Server 中:当您在 VARCHAR 列上创建索引并将其呈现为 Unicode 字符串时,SQL Server 不会使用该索引。当您将 BigInt 呈现给包含 SmallInt 的索引列时,也会发生同样的事情。即使 BigInt 小到足以成为 SmallInt,SQL Server 也无法使用索引。相反,您没有这个问题(当向索引的 BigInt ot NVARCHAR 列提供 SmallInt 或 Ansi-Code 时)。不同 DBMS(数据库管理系统)之间的数据类型可能有所不同:
要知道每个数据库的数据类型略有不同,而 VARCHAR 并不意味着在所有地方都相同。SQL Server 有 VARCHAR 和 NVARCHAR,而 Apache/Derby 数据库只有 VARCHAR,而 VARCHAR 是 Unicode。
主要是nvarchar存储 Unicode 字符,varchar存储非 Unicode 字符。
“Unicodes”是指 16 位字符编码方案,允许将来自许多其他语言(如阿拉伯语、希伯来语、中文、日语)的字符编码为单个字符集。
这意味着 unicodes 每个字符使用 2 个字节来存储,而非 unicodes 每个字符只使用一个字节来存储。这意味着与非 unicode 相比,unicode 需要双倍的存储容量。
你是对的。nvarchar
存储 Unicode 数据,同时varchar
存储单字节字符数据。除了您已经提到的存储差异(nvarchar
需要两倍的存储空间)之外,首选的varchar
主要原因是国际化(即以其他语言存储字符串)。nvarchar
varchar
varchar
is used for non-Unicode characters
only 另一方面nvarchar
,同时用于unicode
和non-unicode
字符。下面给出了它们之间的其他一些区别。
VARCHAR 与 NVARCHAR
VARCHAR | NVARCHAR | |
---|---|---|
字符数据类型 | 可变长度的非 Unicode 字符 | 可变长度,Unicode 和非 Unicode 字符,如日语、韩语和中文。 |
最大长度 | 取决于8,000 characters |
取决于4,000 characters |
字符大小 | 1 byte 每个字符占用 |
占用2 bytes 每个 Unicode/非 Unicode 字符 |
存储大小 | 实际长度(以字节为单位) | 2 倍实际长度(以字节为单位) |
用法 | 当数据长度是可变或可变长度列并且实际数据总是远小于容量时使用 | 由于仅用于存储,仅在您需要 Unicode 支持时使用,例如日文汉字或韩文字符。 |
nVarchar 将帮助您存储 Unicode 字符。如果您想存储本地化数据,这是要走的路。
我会说,这取决于。
如果您开发一个桌面应用程序,其中操作系统以 Unicode 工作(就像所有当前的 Windows 系统一样)并且语言本身支持 Unicode(默认字符串是 Unicode,如 Java 或 C#),那么请使用 nvarchar。
如果您开发一个 Web 应用程序,其中字符串以 UTF-8 形式出现,语言是 PHP,它本身仍然不支持 Unicode(在 5.x 版本中),那么 varchar 可能是更好的选择。
虽然NVARCHAR
存储 Unicode,但您应该考虑借助排序规则也可以使用VARCHAR
和保存本地语言的数据。
想象一下下面的场景。
您的数据库的排序规则是波斯语,并且您在数据类型中保存了一个值,例如“علی”(阿里的波斯语书写)VARCHAR(10)
。没有问题,DBMS 只使用三个字节来存储它。
但是,如果您想将数据传输到另一个数据库并查看正确的结果,您的目标数据库必须与目标数据库具有相同的排序规则,在此示例中为波斯语。
如果您的目标排序规则不同,您会在目标数据库中看到一些问号 (?)。
最后,请记住,如果您使用的是用于本地语言的大型数据库,我建议使用位置而不是使用太多空格。
我相信设计可以不同。这取决于您工作的环境。
如果使用单个字节来存储一个字符,则有 256 种可能的组合,从而可以保存 256 个不同的字符。排序规则是定义字符以及比较和排序它们的规则的模式。
1252,即 Latin1 (ANSI),是最常见的。单字节字符集也不足以存储许多语言使用的所有字符。例如,某些亚洲语言有数千个字符,因此每个字符必须使用两个字节。
统一码标准
当在网络中使用使用多个代码页的系统时,管理通信变得困难。为了标准化事物,ISO 和 Unicode 联盟引入了Unicode。Unicode 使用两个字节来存储每个字符。也就是说可以定义 65,536 个不同的字符,所以几乎所有的字符都可以用 Unicode 覆盖。如果两台计算机使用 Unicode,则每个符号都将以相同的方式表示,并且不需要转换——这就是 Unicode 背后的理念。
SQL Server 有两类字符数据类型:
- 非 Unicode(char、varchar 和 text)
- Unicode(nchar、nvarchar 和 ntext)
如果我们需要保存来自多个国家/地区的字符数据,请始终使用 Unicode。
我查看了答案,许多人似乎建议使用nvarchar
over varchar
,因为空间不再是问题,因此启用 Unicode 以获取少量额外存储并没有什么坏处。好吧,当您想在列上应用索引时,情况并非总是如此。SQL Server 对可以索引的字段的大小有 900 个字节的限制。所以如果你有一个varchar(900)
你仍然可以索引它,但不是varchar(901)
. 使用nvarchar
,字符数减半,因此您最多可以索引nvarchar(450)
. 所以如果你确信你不需要nvarchar
,我不建议使用它。
一般来说,在数据库中,我建议坚持你需要的大小,因为你总是可以扩展的。比如同事曾经认为用nvarchar(max)
for列没有什么坏处,因为我们存储完全没有问题。后来,当我们尝试在该列上应用索引时,SQL Server 拒绝了。但是,如果他从 even 开始varchar(5)
,我们可以稍后将其扩展为我们需要的,而不会出现需要我们执行现场迁移计划来解决此问题的问题。
我必须在这里说(我意识到我可能会向自己敞开心扉!),但肯定是唯一比所有排序规则更有用的时候NVARCHAR
(注意那里的更多!)VARCHAR
依赖系统和数据库本身是相同的......?如果不是,那么排序规则转换无论如何都必须发生,因此VARCHAR
与NVARCHAR
.
除此之外,一些数据库系统,例如SQL Server(2012 年之前)的页面大小约为 8K。因此,如果您正在考虑存储未保存在类似TEXT
orNTEXT
字段中的可搜索数据,则VARCHAR
提供完整的 8k 空间,而NVARCHAR
仅提供 4k(双倍字节,双倍空间)。
我想,总而言之,两者的使用取决于:
- 项目或背景
- 基础设施
- 数据库系统
遵循Sql Server VARCHAR 和 NVARCHAR 数据类型之间的区别。在这里,您可以以非常具有描述性的方式看到。
一般来说,nvarchar 将数据存储为 Unicode,因此,如果您要在数据列中存储多语言数据(多于一种语言),则需要 N 变体。
信誉评分约为 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。
有评论 pro/con varchar 以提高性能。
我对具有数百列的表有特殊要求,这本身可能很不寻常?
我选择 varchar 是为了避免接近 SQL*server 2012 的 8060 字节表记录大小限制。
对我来说,使用 nvarchar 超过了这个 8060 字节的限制。
我也在想我应该把相关代码表的数据类型与主中心表的数据类型相匹配。
我已经看到以前经验丰富的数据库开发人员在南澳大利亚政府的这个工作地点使用 varchar 列,其中表的行数将达到数百万或更多(并且在这些非常大的表),因此可能预期的数据行量成为此决定的一部分。
由于 SQL Server 2019 varchar 列支持 UTF-8 编码。
因此,从现在开始,区别在于大小。
在转换为速度差异的数据库系统中。
更小的尺寸 = 更少的 IO + 更少的内存 = 总体上更快的速度。阅读上面的文章了解数字。
从现在开始使用 UTF8中的varchar!
仅当您有大量数据的字符在 2048 - 16383 和 16384 - 65535 范围内时 - 您必须测量
nvarchar
varchar
与使我们的代码无错误(类型不匹配)相比,使用起来更安全,因为nvarchar
也允许使用 unicode 字符。当我们where
在 SQL Server 查询中使用条件并且使用=
运算符时,有时会抛出错误。可能的原因是我们的映射列将定义在varchar
. 如果我们在nvarchar
这个问题中定义它,我不会发生。我们仍然坚持varchar
并避免这个问题,我们最好使用LIKE
关键字而不是=
.