在SQL Server中,何时必须使用NVARCHAR/NCHAR而不是VARCHAR/CHAR? [英] When must we use NVARCHAR/NCHAR instead of VARCHAR/CHAR in SQL Server?
问题描述
我们必须使用Unicode类型时是否有规则?
我见过大多数欧洲语言(德语、意大利语、英语等)在同一数据库中的VARCHAR列中都可以。
我正在寻找类似的东西:
- 如果您有中文-->使用NVARCHAR
- 如果您有德语和阿拉伯语-->使用NVARCHAR
服务器/数据库的排序规则如何?
我不想像这里建议的那样使用Always NVARCHAR What are the main performance differences between varchar and nvarchar SQL Server data types?推荐答案
两个支持率最高的答案都是错误的。它不应与存储不同/多种语言&Quot;有关。支持ñ
、英文等西班牙语字符,仅支持常用的varchar
字段和Latin1_General_CI_AS
COLLATION
,如
简写版本
当COLLATION
确定的ENCODING
不支持所需字符时,请使用NVARCHAR
/NCHAR
。
此外,根据SQL Server的版本,您可以使用特定的COLLATIONs
,如从SQL Server 2019开始提供的Latin1_General_100_CI_AS_SC_UTF8
。在VARCHAR
字段(或整个表/数据库)上设置此排序规则,将使用UTF-8
ENCODING
存储和处理该字段上的数据,从而完全支持UNICODE
字符,从而支持它所包含的任何语言。
要完全理解:
要完全理解我将要解释的内容,必须将UNICODE
、ENCODING
和COLLATION
的概念都非常清楚。如果您不知道,那么首先看一下我对什么是Unicode、编码、排序规则和UTF-8的简单而简明的解释,以及它们是如何相关的";一节和提供的文档链接。此外,我在这里所说的一切都是特定于Microsoft SQL Server
,以及它如何在char
/nchar
和varchar
/nvarchar
字段中存储和处理数据。
假设我们想要在MSSQL Server数据库上存储一个特殊的文本。这可能是Instagram上的一条评论,因为我喜欢Stackoverflow!😍&。
即使ASCII也完全支持纯英语部分,但由于还有一个表情符号,它是UNICODE
标准中指定的字符,我们需要一个支持此Unicode字符的ENCODING
。
COLLATION
确定ENCODING
用于char
/nchar
/varchar
/nvarchar
字段。因此,与许多人认为不同,COLLATION
不仅仅是数据的分类和比较,还包括ENCODING
以及结果:我们的数据将如何存储!
那么,我们如何知道我们的归类使用的编码是什么?使用这个:
SELECT COLLATIONPROPERTY( 'Latin1_General_CI_AI' , 'CodePage' ) AS [CodePage]
--returns 1252
这个简单的SQL为COLLATION
返回Windows Code Page
。Windows Code Page
只不过是到ENCODINGs
的另一个映射。对于Latin1_General_CI_AI
COLLATION
,它返回Windows Code Page
代码1252
,它映射到Windows-1252
ENCODING
。因此,对于
varchar
列,使用Latin1_General_CI_AI
COLLATION
,此字段将使用Windows-1252
ENCODING
处理其数据,并且仅正确存储此编码支持的字符。
如果我们检查Windows-1252 ENCODING
规范Character List for Windows-1252,我们会发现该编码不支持我们的表情符号字符。如果我们仍然尝试:
好的,那么我们如何解决这个问题??实际上,这取决于情况,这很好!
NCHAR
/NVARCHAR
NCHAR
和NVARCHAR
个字段。有些人说它们是UNICODE
个字段。这是错误的!。同样,它取决于字段的COLLATION
和SQLServer版本。
微软的"nchar and nvarchar (Transact-SQL)" documentation非常详细:从SQL Server 2012(11.x)开始,当 使用了启用补充字符(SC)的归类,则这些数据 类型存储完整范围的Unicode字符数据,并使用 UTF-16字符编码。如果指定了非SC归类,则 这些数据类型仅存储支持的字符数据子集 UCS-2字符编码。换句话说,如果我们使用2012年之前的SQL Server,例如SQL Server 2008 R2,则这些字段的
ENCODING
将使用UCS-2 ENCODING
,它支持UNICODE
的子集。但如果我们使用的是SQL Server 2012或更高版本,并定义了一个启用了Supplementary Character
的COLLATION
,则我们的字段将使用完全支持UNICODE
的UTF-16
ENCODING
。
但Whait,还有更多!我们现在可以使用UTF-8了!!
CHAR
/VARCHAR
从SQL Server 2019开始,我们可以使用CHAR
/VARCHAR
字段,但仍完全支持使用UTF-8
ENCODING
!!
来自Microsoft的"char and varchar (Transact-SQL)" documentation:
从SQL Server 2019(15.x)开始,当 使用启用UTF-8的归类,这些数据类型存储完整范围 并使用UTF-8字符编码。如果一个 非UTF-8排序规则,则这些数据类型仅存储 的相应代码页所支持的字符子集 排序规则。同样,换句话说,如果我们使用早于2019年的SQL Server,例如SQL Server2008 R2,我们需要使用前面解释的方法检查
ENCODING
。但是,如果我们使用SQL Server 2019或更高版本,并定义COLLATION
LIKELatin1_General_100_CI_AS_SC_UTF8
,则我们的字段将使用UTF-8
ENCODING
,这是迄今为止最常用和最有效的编码,支持所有UNICODE
字符。
奖金信息:
关于OP对的观察,我看到大多数欧洲语言(德语、意大利语、英语等)在同一数据库中的VARCHAR列中都很好,我想知道原因是很好的: 对于最常见的COLLATIONs
,如默认的Latin1_General_CI_AI
或SQL_Latin1_General_CP1_CI_AS
,ENCODING
对于varchar
字段将是Windows-1252
。如果我们看一下它的documentation,可以看到它支持:
英语、爱尔兰语、意大利语、挪威语、葡萄牙语、西班牙语、瑞典语。加号 还有德语、芬兰语和法语。除IJ字符外的荷兰语
但正如我前面所说,这不是关于语言的问题,而是关于您期望支持/存储什么字符的问题,如表情符号示例中所示,或者像Windows-1252
ENCODING
这样的句子,其中我们同样有通俗易懂的英语,以及希腊字母/字符&omega&Ω;(这是电阻的符号,单位为欧姆),Windows-1252
ENCODING
无法正确处理。
结论:
所以,就是这样!当使用char
/nchar
和varchar
/nvarchar
时,取决于您要支持的字符,以及将确定您的COLLATIONs
和ENCODINGs
可用的SQL Server版本。
什么是Unicode、编码、归类和UTF-8,以及它们之间的关系
注意:以下所有解释均为简化。请参考提供的文档链接,以了解有关这些概念的所有详细信息。
UNICODE
-是一种标准,一种惯例,旨在规范统一有序的表格中的所有字符。在此表中,每个字符都有一个唯一的数字。此数字通常称为字符的code point
。
Unicode不是编码!ENCODING
-是字符和字节/字节序列之间的映射。因此,使用编码将字符转换为字节,反之亦然,从字节转换为字符。其中最流行的是UTF-8
、ISO-8859-1
、Windows-1252
和ASCII
。您可以将其视为转换表(我在这里确实简化了)。COLLATION
-这一点很重要。即使是微软的文档也没有让这一点像它应该的那样清楚。排序规则指定如何对数据进行排序、比较、和存储!。是的,我打赌你没有预料到最后一次,对吧!SQL Server
上的排序规则还确定在该特定char
/nchar
/varchar
/nvarchar
字段上使用的ENCODING
。ASCII ENCODING
-是最早的编码之一。它既是字符表(就像UNICODE
的一个自己的微型版本),也是它的字节映射。因此它不会将一个字节映射到UNICODE
,而是将一个字节映射到它自己的字符表。此外,它始终只使用7位,并支持128个不同的字符。它足以支持所有英文字母的大小写、数字、标点符号和其他一些有限数量的字符。ASCII的问题是,由于它当时只使用7位,而几乎每台计算机都是8位,因此有另外128种可能的字符需要探索,每个人都开始将这个可用&q;字节映射到自己的字符表,从而创建了许多不同的ENCODINGs
。UTF-8 ENCODING
-这是另一个ENCODING
,使用最多(如果不是最多)的ENCODING
之一。它使用可变字节宽度(根据规范,一个字符的长度可以是1到6个字节),并完全支持所有UNICODE
字符。Windows-1252 ENCODING
-也是最常用的ENCODING
之一,在SQL Server上广泛使用。它是固定大小的,所以每个字符都是1字节。它还支持各种语言的许多口音,但不支持现有的所有口音,也不支持UNICODE
。这就是为什么您的varchar
字段支持á
、é
、ñ
字符的原因,即使它没有使用支持的UNICODE
ENCODING
。
资源:
https://blog.greglow.com/2019/07/25/sql-think-that-varchar-characters-if-so-think-again/
https://medium.com/@apiltamang/unicode-utf-8-and-ascii-encodings-made-easy-5bfbe3a1c45a
https://www.johndcook.com/blog/2019/09/09/how-utf-8-works/
https://www.w3.org/International/questions/qa-what-is-encoding
https://en.wikipedia.org/wiki/List_of_Unicode_characters
https://www.fileformat.info/info/charset/windows-1252/list.htm
https://docs.microsoft.com/en-us/sql/t-sql/data-types/char-and-varchar-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/t-sql/data-types/nchar-and-nvarchar-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/t-sql/statements/windows-collation-name-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/t-sql/statements/sql-server-collation-name-transact-sql?view=sql-server-ver15
https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-ver15#SQL-collations
SQL Server default character encoding
https://en.wikipedia.org/wiki/Windows_code_page
这篇关于在SQL Server中,何时必须使用NVARCHAR/NCHAR而不是VARCHAR/CHAR?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!