什么时候必须在SQL Server中使用NVARCHAR / NCHAR而不是VARCHAR / CHAR?
-
03-07-2019 - |
题
我们必须使用Unicode类型时是否有规则?
我已经看到大多数欧洲语言(德语,意大利语,英语,......)在VARCHAR列中的同一数据库中都很好。
我正在寻找类似的东西:
- 如果你有中文 - >使用NVARCHAR
- 如果你有德语和阿拉伯语 - >使用NVARCHAR 醇>
服务器/数据库的整理怎么样?
我不想像这里建议的那样使用NVARCHAR varchar和nvarchar SQL Server数据类型之间的主要性能差异是什么?
解决方案
您想要使用NVARCHAR的真正原因是当您在同一列中有不同的语言时,您需要在不解码的情况下解决T-SQL中的列,您希望能够看到数据“本地地”在SSMS中,或者您希望标准化Unicode。
如果将数据库视为哑存储,则完全可以在VARCHAR中存储宽字符串和不同(甚至可变长度)的编码(例如UTF-8)。当您尝试编码和解码时会出现问题,特别是如果不同行的代码页不同。这也意味着SQL Server将无法轻松处理数据,以便在(可能是可变的)编码列上查询T-SQL。
使用NVARCHAR可以避免这一切。
我建议将NVARCHAR用于任何具有用户输入数据的列,该列相对不受约束。
我建议将VARCHAR用于任何自然键列(如车牌,SSN,序列号,服务标签,订单号,机场呼号等),这些列通常由标准或法规或惯例。用户输入的VARCHAR,非常有限(如电话号码)或代码(ACTIVE / CLOSED,Y / N,M / F,M / S / D / W等)。绝对没有理由使用NVARCHAR。
所以对于一个简单的规则:
保证受约束时VARCHAR NVARCHAR否则
其他提示
您必须在任何时候存储多种语言时使用NVARCHAR。我相信你必须将它用于亚洲语言,但不要引用我。
如果您以俄语为例并将其存储在varchar中,则会出现问题,只要您定义了正确的代码页,就可以了。但是,假设你使用默认的英文sql install,那么俄语字符将无法正确处理。如果您使用的是NVARCHAR(),则可以正确处理它们。
修改
好的,让我引用 MSDN ,也许我是具体但你不想在varcar列中存储多于一个代码页,而你不应该
处理文本数据时 存储在char,varchar中, varchar(max)或文本数据类型 最重要的考虑因素 只是来自单一的信息 代码页可以通过验证 系统。 (您可以存储来自的数据 多个代码页,但事实并非如此 推荐。)使用的确切代码页 验证和存储数据取决于 关于列的整理。如果一个 列级排序规则尚未完成 定义,数据库的整理 用来。确定代码页 用于给定列的,你 可以使用COLLATIONPROPERTY 功能,如下所示 代码示例:
还有一些:
这个例子说明了这个事实 许多语言环境,例如格鲁吉亚语和 印地语,没有代码页,因为他们 是仅限Unicode的排序规则。那些 整理不适合 使用char,varchar或的列 文本数据类型
所以格鲁吉亚语或印地语真的需要存储为nvarchar。阿拉伯语也是一个问题:
您可能遇到的另一个问题是 没有时无法存储数据 所有你想要的角色 支持包含在代码中 页。在很多情况下,Windows会考虑 特定的代码页是“最好的” 适合"代码页,这意味着有 不能保证你可以依赖 用于处理所有文本的代码页;它是 只是最好的一个。一个 这方面的例子是阿拉伯语脚本: 它支持多种语言, 包括俾路支,柏柏尔人,波斯人, 克什米尔,哈萨克斯坦,吉尔吉斯,普什图语, 信德,维吾尔,乌尔都语等。所有的 这些语言有额外的 超出阿拉伯语的字符 Windows代码中定义的语言 第1256页。如果您尝试存储 这些额外的角色 具有阿拉伯语的非Unicode列 整理,人物是 转换成问号。
使用Unicode时要记住一些事项,尽管您可以在一个列中存储不同的语言,但只能使用单个排序规则进行排序。有些语言使用拉丁字符,但不像其他拉丁语言那样排序。口音是一个很好的例子,我不能记住这个例子,但是有一种东欧语言,其Y不像英语Y那样。然后有西班牙语ch,西班牙语用户将在h之后进行排序。
总而言之,在处理内部化时,您必须处理所有问题。我认为从一开始就更容易使用Unicode字符,避免额外的转换并占用空间。因此,我先前的发言。
希腊语在N列类型上需要UTF-8:αβγ ;)
我是西班牙语母语人士并且“ch”不是一封信,而是两个“c”字母。和“h”和西班牙字母表是这样的: abcdefghijklmnñ opqrstuvwxyz 我们不期望“ch”在“h”之后但是“我” 除了ñ之外,字母与英文相同。或者在HTML"& ntilde;"
中亚历
<强> TL; DR; 强>结果
Unicode - (nchar,nvarchar和ntext)
非unicode - (char,varchar和text)。
SQL Server中的排序规则提供排序规则,大小写和重音 数据的敏感性属性。与之一起使用的排序规则 字符数据类型(如char和varchar)指示代码页 以及可以为该数据表示的相应字符 类型。
假设您使用的是默认SQL排序规则 SQL_Latin1_General_CP1_CI_AS
,那么以下脚本应该打印出您可以放入 VARCHAR
的所有符号,因为它使用一个字节来存储一个字符(总共256个)如果你没有在打印的列表中看到它 - 你需要 NVARCHAR
。
declare @i int = 0;
while (@i < 256)
begin
print cast(@i as varchar(3)) + ' '+ char(@i) collate SQL_Latin1_General_CP1_CI_AS
print cast(@i as varchar(3)) + ' '+ char(@i) collate Japanese_90_CI_AS
set @i = @i+1;
end
如果您更改排序规则,让我们说日语,您会注意到所有奇怪的欧洲字母变为正常,而某些符号变为?
标记。
Unicode是将代码点映射到字符的标准。因为 它旨在涵盖所有语言的所有字符 世界上,不需要不同的代码页来处理不同的 字符组。如果存储反映多个的字符数据 语言,始终使用Unicode数据类型(nchar,nvarchar和ntext) 而不是非Unicode数据类型(char,varchar和text)。
否则你的排序会很奇怪。