UTF-8或UTF-16或UTF-32或UCS-2

我正在设计一个新的CMS,但想设计它以满足我未来的所有需求,如多语言内容,所以我认为Unicode(UTF-8)是最好的解决方案

但通过一些搜索,我得到了这篇文章

http://msdn.microsoft.com/en-us/library/bb330962%28SQL.90%29.aspx#intlftrql2005_topic2

所以我现在很困惑现在使用UTF-8 / UTF-16 / UTF-32 / UCS-2

这对于多语言内容和性能等更好。

PS:我正在使用Asp.net和c#以及SqlServer 2005

提前致谢

这不是问题,因为你说:

我正在使用Asp.net和c#以及SqlServer 2005

SqlServer在一些以XML为中心的地方使用UTF-16(ntext,nvarchar,nchar)和UTF-8,而不会做任何奇怪的事情。

C#在其所有字符串中使用UTF-16,在处理流和文件时使用工具进行编码…

ASP.NET默认使用UTF-8,很难想象它不是一个好的选择(即使使用亚洲语言,这些语言的文本简洁性与具有特殊含义的名称和符号的事实相结合)在HTML,CSS,javascript,大多数XML应用程序和你将要发送的其他流中,从U + 0000到U + 007F的范围,使得UTF-16优于UTF-8的优势在该范围内不如使用纯文本亚洲语言)。

SqlServer的UTF-16和C#以及ASP.NET在读写时所做的UTF-8之间的谈话是通过默认设置为您完成的,但由于这是您可以随时更改的一位,因此我的答案将使用UTF-8。 你真的会使用-8和-16的混合物,但大多数时候你都不会注意到(你注意到你已经这样做了)。

如果仅仅因为许多过时的示例将人类消费的文本放在varchar,text或char字段中,那么SQL Server就不那么容易了。 纯粹用于代码(例如,所有ISO国家代码都在char(2)的范围内,因此nchar(2)只会浪费空间),只有nvarchar,ntext和nchar用于人们而不是机器的东西才能读写。

所以我现在很困惑现在使用UTF-8 / UTF-16 / UTF-32 / UCS-2

这对于多语言内容和性能等更好。

UCS-2已过时:它不再代表每个Unicode字符。 UTF-8,UTF-16和UTF-32都可以。 但为什么有三种不同的方法来编码相同的字符?

因为在过去,程序员对字符串做了两个很大的假设。

  1. 该字符串由8位代码单元组成。
  2. 那个1个字符= 1个代码单元。

多语言文本(或者甚至是单语文本,如果该语言恰好是中文,日文或韩文)的问题在于这两个假设的组合限制为256个字符。 如果您需要表示更多,则需要删除其中一个假设。

保持假设#1和丢弃假设#2可以得到可变宽度或多字节编码 。 今天,最流行的可变宽度编码是UTF-8。

删除假设#1并保持假设#2可以为您提供宽字符编码 。 Unicode和UCS-2最初设计为使用16位固定宽度编码,允许65,536个字符。 Unicode的早期采用者,例如Sun(用于Java)和Microsoft(用于NT)使用UCS-2。

然而,几年后,人们意识到即使对每个人来说还不够,所以扩展了Unicode代码范围。 现在,如果您需要固定宽度编码,则必须使用UTF-32。

但Sun和微软已经编写了大量基于16位字符的API,并且并不热衷于为32位重写它们。 幸运的是,在最初的65,536个字符的“基本多语种平面”中仍然存在2048个未分配字符块,可以将其指定为“代理”以成对使用以表示补充字符:UTF-16编码forms。 不幸的是,UTF-16 既不符合原来的两个假设:它既不是非8位也是可变宽度。

综上所述:

当假设8位代码单元很重要时,请使用UTF-8。

这适用于:

  • Unix系统上的文件名和相关的OS调用,它具有允许可变宽度编码的传统,但不能接受字符串中的'\x00字节,因此不能使用UTF-16或UTF-32。 事实上,UTF-8最初为基于Unix的操作系统而设计的(Plan 9)。
  • 围绕八位字节流设计的通信协议。
  • 任何需要与US-ASCII二进制兼容的东西,但对127以上的字节值没有特殊处理。

当假定固定宽度编码很重要时,请使用UTF-32。

当您关心字符的属性而不是它们的编码时,这很有用,例如ctypes.hisdigittoupperctypes.h函数的Unicode等价物。

当假设不重要,但您的平台曾经使用过UCS-2时,请使用UTF-16。

您是在为Windows编写,还是为其设计的.NET框架? 对于Java? 那么UTF-16是你的默认字符串类型; 不妨用它。

由于您使用的是C#,因此所有字符串都将以UTF-16编码。 ASP.NET将以UTF-8编码实际的HTML页面,但这是在幕后完成的,您无需关心。

尺寸考虑

三种UTF编码forms需要不同的内存量来表示一个字符:

  • 字符U + 0000到U + 007F(ASCII)需要UTF-8中的1个字节,UTF-16中的2个字节或UTF-32中的4个字节。
  • 字符U + 0080到U + 07FF(IPA符号,希腊语,西里尔语,亚美尼亚语,希伯来语,阿拉伯语,叙利亚语,塔那语,NKo)需要UTF-8中的2个字节,UTF-16中的2个字节或UTF-32中的4个字节。
  • 字符U + 0800到U + FFFF(BMP的其余部分,主要用于亚洲语言)需要UTF-8中的3个字节,UTF-16中的2个字节或UTF-32中的4个字节。
  • 字符U + 10000到U + 10FFFF在所有三种编码forms中都需要4个字节。

因此,如果您想节省空间,如果您的角色大多是ASCII,则使用UTF-8;如果您的角色大多是亚洲人,则使用UTF-16。

首先,忘掉UCS-2:它已经过时了。 它仅包含Unicode字符的子集。 忘记UTF-32:它非常庞大且非常冗余。 它对数据传输没有用。

在网页中,如果您处理的大部分语言都是西式语言(拉丁语,西里尔语,希腊语等),那么最经济的就是UTF-8。 但如果带宽和加载时间不是问题,那么你也可以使用UTF-16。 只需确保在处理byte[]时始终知道数据的格式。 并且不要尝试转换为过时的8位字符集,如ISO-8859或Windows-1252,因为如果你这样做会丢失数据。

在C#代码中,您的string对象将在内部使用UTF-16,并且您无法对此做任何事情。 因此,您的正常字符串操作(例如, Substring() )不受您选择的输出格式的影响。 有人可能会说,这使得编码为UTF-16的性能更高,但如果你要通过互联网传输它,那就不值得了,因为传输更大的UTF-16的成本超过了微小的处理收益。

在SQL Server中,您应该使用nvarchar(...)

UTF-8或UTF-16都是不错的选择。 它们都允许您访问所有Unicode代码点,而不会为每个字符使用4个字节。

您的选择将受到您使用的语言及其对这些格式的支持的影响。 我相信UTF-8在ASP.NET整体上表现最好,但它取决于你在做什么。

UTF-8通常是一个很好的选择,因为它只能使用只需要ASCII的代码,而UTF-16则不能。 它也是表示主要由我们的英文字母组成的内容的最有效方式,同时在需要时仍然允许完整的Unicode库。 选择UTF-16的一个很好的理由是,如果您的语言/框架本身使用它,或者您将主要使用非ASCII字符,例如亚洲语言。

唉我认为问题是(正如他在开头所说)他有SQL Server 2005,如果我是正确的仍然使用UCS2,因为它的N数据类型的编码(NVARCHAR和co)

他可能不得不忍受带来或升级到更新版本的SQL Server的限制。 通常情况下,如果您开始转储UTF-16,即.NET中使用的标准unicode,您将看到的是,如上所述,某些字符将丢失并替换为? 数据库表中的标记。

快速说明:基本上所有内容都可以用unicode 字符集表示 。 UTF-8只是一种能够代表该集合中所有字符的编码

UCS-2不再是一个可以使用的东西了。 它不能容纳超出U + FFFF的字符。

其余三个中的哪一个取决于您要对文本执行何种操作。 UTF-8(通常,并非总是!)将占用代表相同数据的磁盘上较少的空间,并且是ASCII的严格超集,因此它可能会减少所需的转码量。 但是,您无法索引字符串或在常量时间内查找其长度。

UTF-32允许您查找字符串的长度并在恒定时间内对其进行索引。 它不像UTF-8那样是ASCII的超集。 它还要求每个代码点有4个字节,但是,磁盘空间很便宜。