虽然researching options用于存储可能非常大的SQL Server数据库中的大部分英语但有时不存储的数据,但我倾向于将大多数字符串数据存储为UTF-8编码。
然而,微软之所以选择UCS-2是出于我不完全理解的原因,而这种原因导致我猜测这种倾向。 SQL Server 2012的文档确实显示了如何创建UTF-8 UDT,但是UCS-2的决定可能会遍及SQL Server。
Wikipedia(有趣地指出UCS-2已经过时,支持UTF-16)注意到UTF-8是一个可变宽度字符集,能够编码任何Unicode数据点并且它{{1 }}。因此,感觉任何Unicode字符都可以用UTF-8表示,并且由于大多数文本都是英文,因此表示将几乎是UCS-2的两倍(我知道磁盘“便宜”,但磁盘缓存不是但是,内存与我正在处理的数据大小不相比。当工作集大于可用RAM时,许多操作会以指数方式降级。
游泳UCS-2流可能会遇到什么问题?
答案 0 :(得分:11)
在SQL Server数据库中存储大多数英语但有时不存在的数据可能非常大,我倾向于将大多数字符串数据存储为UTF-8编码。
与允许选择编码的其他一些RDBMS不同,SQL Server以UTF-16(Little Endian)存储Unicode数据 ,以及以8位存储非Unicode数据编码(扩展ASCII,DBCS或EBCDIC),用于字段整理隐含的任何代码页。
Microsoft选择UCS-2是出于我不完全理解的原因
他们决定选择 UCS-2是有道理的,因为UTF-16是在1996年中期推出并在2000年完全指定的。许多其他系统也使用(或使用)它(请参阅:https://en.wikipedia.org/wiki/UTF-16#Usage)。他们决定继续使用它可能更值得怀疑,尽管可能是因为Windows和.NET是UTF-16。 UCS-2和UTF-16之间的字节物理布局是相同的,因此从UCS-2升级到支持UTF-16的系统应该是纯功能的,不需要改变任何现有数据。
嗯,不。通过SQLCLR创建自定义用户定义类型 not ,无论如何,都可以让您替换任何本机类型。创建处理专用数据的东西非常方便。但是,即使是不同的编码,字符串也远非专业化。为您的字符串数据采用这种方式会破坏系统的任何可用性,更不用说性能,因为您无法使用任何内置字符串函数。如果您能够在磁盘空间中保存任何内容,那么这些收益将会被整体性能损失所抹去。存储UDT是通过将其序列化为SQL Server 2012的文档确实显示了如何创建UTF-8 UDT,
VARBINARY
来完成的。因此,为了在"二进制"之外进行任何字符串比较或排序。 /"序数"比较,您必须将所有其他值逐个转换回UTF-8,然后进行可以解释语言差异的字符串比较。
此外,"文档"实际上只是示例代码/概念验证的东西。代码是在2003年(http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/CS/UTF8String/Utf8String.cs)为SQL Server 2005编写的。我看到了一个用于测试功能的脚本,但没有任何涉及性能的脚本。
但UCS-2的决定可能会遍及SQL Server。
是的,非常如此。默认情况下,内置函数的处理仅适用于UCS-2。但是从SQL Server 2012开始,您可以使用其中一个排序规则来处理完整的UTF-16字符集(从Unicode版本5或6开始,具体取决于您的操作系统和.NET Framework版本)。名称以_SC
结尾(即补充字符)。
维基百科...注意到UCS-2已经过时,支持UTF-16
正确。 UTF-16和UCS-2都使用2字节代码点。但是UTF-16成对使用它们中的一些(即代理对)来映射其他字符。用于这些对的代码点在UCS-2中为此目的保留,因此不用于映射到任何可用的符号。这就是您可以在SQL Server中存储任何Unicode字符的原因,它将被正确存储和检索。
维基百科...注意到UTF-8是一个可变宽度字符集,能够编码任何Unicode数据点
正确,但有误导性。是的,UTF-8是可变宽度的,但UTF-16也是微小变量,因为所有补充字符都由两个双字节代码点组成。因此,UTF-16每个符号使用2或4个字节,但UCS-2总是2个字节。但这不是误导性的部分。误导的是暗示任何其他Unicode编码都不能编码所有其他代码点。虽然UCS-2可以保留它们但不能解释它们,但UTF-16和UTF-32都可以映射所有Unicode代码点,就像UTF-8一样。
并且它[ed:UTF-8]为Unicode文本的交换提供了事实上的标准编码。
这可能是真的,但从操作角度来看,它完全无关紧要。
感觉任何Unicode字符都可以用UTF-8
表示
同样,这是真的,但完全不相关,因为UTF-16和UTF-32也映射了所有Unicode代码点。
由于大多数文本都是英文,因此表示将几乎是UCS-2
的两倍
根据具体情况,这很可能是正确的,你关注这种浪费的用法是正确的。但是,正如我在导致这个问题(UTF-8 Support, SQL Server 2012 and the UTF8String UDT)的问题中提到的,如果大多数行可以容纳VARCHAR
但有些行需要NVARCHAR
,那么您可以选择一些方法来减少浪费的空间量。 {1}}。最好的选择是启用ROW COMPRESSION或PAGE COMPRESSION(仅限Enterprise Editon!)。从SQL Server 2008 R2开始,它们允许非MAX NVARCHAR
字段使用"标准压缩方案用于Unicode"这至少与UTF-8一样好,在某些情况下甚至比UTF-8更好。 NVARCHAR(MAX)
字段无法使用此花哨压缩,但其IN ROW数据可以从常规ROW和/或PAGE压缩中受益。请参阅以下内容以获取此压缩的说明以及比较数据大小的图表:原始UCS-2 / UTF-16,UTF-8和UCS-2 / UTF-16,并启用了数据压缩。
SQL Server 2008 R2 - UCS2 compression what is it - Impact on SAP systems
请参阅Data Compression的MSDN页面以获取更多详细信息,因为存在一些限制(除了仅在Enterprise Edition中可用 - 但是从所有版本开始可用于SQL Server 2016,SP1 !!)以及压缩可能会使事情变得更糟的一些情况。
我知道磁盘是"便宜"
该陈述的真实性取决于人们如何定义" disk"。如果您正在谈论商品零件,您可以在商店购买,以便在台式机/笔记本电脑中使用,那么请确定。但是,如果谈到将用于您的生产系统的企业级存储,那么请向任何控制预算的人解释他们不应该拒绝您想要的超过百万美元的SAN,因为它是"廉价" ; - 。)
游泳UCS-2流可能会遇到什么问题?
没有我能想到的。好吧,只要你不遵循任何可怕的建议来做一些事情,比如实现UDT,或者将所有字符串转换为VARBINARY
,或者对所有字符串字段使用NVARCHAR(MAX)
;-) 。但是在你可能担心的所有事情中,使用UCS-2 / UTF-16的SQL Server不应该是其中之一。
但是,如果由于某种原因这个没有UTF-8原生支持的问题非常重要,那么你可能需要找到另一个允许使用UTF-8的RDBMS。
更新2018-10-02
虽然这还不是一个可行的选择,但SQL Server 2019在VARCHAR
/ CHAR
数据类型中引入了对UTF-8的本机支持。目前有太多的bug用于它,但如果它们被修复,那么这是一些场景的一个选项。有关此新功能的详细分析,请参阅我的帖子" Native UTF-8 Support in SQL Server 2019: Savior or False Prophet?&#34 ;.
答案 1 :(得分:0)
“游泳UCS-2流”是什么意思?
以下是您的选择:
不推荐但可能:
请参阅评论,了解这些方法存在的严重缺陷。