SQL Server 2019 (15.x) 完全支持广泛使用的 UTF-8 字符编码作为导入或导出编码,以及作为字符串数据的数据库级别或列级别排序规则。 UTF-8 受 char 和 varchar 数据类型支持,并在创建对象的排序规则或将其更改为带有 UTF8 后缀的排序规则时启用。 例如,将 LATIN1_GENERAL_100_CI_AS_SC 更改为 LATIN1_GENERAL_100_CI_AS_SC_UTF8 。

UTF-8 仅适用于支持增补字符的 Windows 排序规则,如 SQL Server 2012 (11.x) 中所述。 nchar 和 nvarchar 数据类型仅支持 UCS-2 或 UTF-16 编码,并保持不变。

Azure SQL 数据库和 Azure SQL 托管实例还支持数据库和列级别的 UTF-8,而 SQL 托管实例也在服务器级别支持 UTF-8。

UTF-8 与 UTF-16 的存储差异

Unicode 联盟为每个字符都分配一个唯一码位(介于 000000-10FFFF 之间的值)。 使用 SQL Server 2019 (15.x) 时,UTF-8 和 UTF-16 编码都可用来表示整个范围:

  • 如果使用 UTF-8 编码,ASCII 范围(000000-00007F)内的字符需要 1 个字节,介于 000080 和 0007FF、000800 和 00FFFF 以及 0010000 和 0010FFFF 之间的码位分别需要 2、3 和 4 个字节。
  • 如果使用 UTF-16 编码,介于 000000 和 00FFFF 以及 0010000 和 0010FFFF 之间的码位分别需要 2 和 4 个字节。

下表列出了各个字符范围和编码类型的编码存储字节:

展开表
代码范围(十六进制) 代码范围(十进制) 使用 UTF-8 时的存储字节1 使用 UTF-16 时的存储字节1
000000–00007F 0–127 1 2
000080–00009F
0000A0–0003FF
000400–0007FF
128–159
160–1,023
1,024–2,047
2 2
000800–003FFF
004000–00FFFF
2,048–16,383
16,384–65,535
3 2
010000–03FFFF2

040000–10FFFF2
65,536–262,1432

262,144–1,114,1112
4 4

1存储字节是指编码字节长度,而不是数据类型在磁盘上的存储大小。 若要详细了解磁盘上的存储大小,请参阅 nchar 和 nvarchar,以及 char 和 varchar

2增补字符的码位范围。

提示

通常认为,在 CHAR(n) 和 VARCHAR(n) 或在 NCHAR(n) 和 NVARCHAR(n) 中,n 定义字符数 。 这是因为在示例 CHAR(10) 列中,可以使用排序规则(如 Latin1_General_100_CI_AI)存储在 0-127 范围内的 10 ASCII 字符,因为此范围内的每个字符仅使用 1 个字节。

但是,在 CHAR(n) 和 VARCHAR(n) 中,n 以字节数 (0-8,000) 定义字符串大小,而在 NCHAR(n) 和 NVARCHAR(n) 中,n 以字节对 (0-4,000) 定义字符串大小 。 n 不会定义可存储的字符数。

如你所见,选择适当的 Unicode 编码和数据类型可以节省大量存储或增加当前存储占用,具体视使用的字符集而定。 例如,如果使用启用了 UTF-8 的拉丁语排序规则(如 Latin1_General_100_CI_AI_SC_UTF8),则 CHAR(10) 列可存储 10 个字节,并且可保留 0-127 范围内的 10 ASCII 字符。 但只可保留 5 个 128-2047 范围内的字符和 3 个 2048-65535 范围内的字符。 相比之下,由于 NCHAR(10) 列存储 10 个字节对(20 个字节),因此该列可保留 10 个 0-65535 范围内的字符。

在选择是要将 UTF-8 编码还是 UTF-16 编码用于数据库或列前,请先考虑要存储的字符串数据的分布情况:

  • 如果它主要在 ASCII 范围 0-127 内(如英语),使用 UTF-8 和 UTF-16 时每个字符分别需要 1 个和 2 个字节。 UTF-8 具有存储优势。 如果使用已启用 UTF-8 的排序规则将包含在 0-127 范围内的 ASCII 字符的现有列数据类型从 NCHAR(10) 更改为 CHAR(10),则会减少 50% 的存储需求。 之所以会有这种减少是因为,NCHAR(10) 需要 20 个字节进行存储,而 CHAR(10) 相比则需要 10 个字节用于相同的 Unicode 字符串表示形式。
  • 如果超出 ASCII 范围(几乎所有拉丁字母语言以及希腊语、西里尔文、科普特语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语、它拿语和西非书面文),使用 UTF-8 和 UTF-16 时每个字符都需要 2 个字节。 在这种情况下,可比较的数据类型(例如,char 与 nchar 之间)没有显著的存储差异。
  • 如果它主要是东亚语言(如韩语、中文和日语),使用 UTF-8 和 UTF-16 时每个字符分别需要 3 个和 2 个字节。 UTF-16 具有存储优势。
  • 使用 UTF-8 和 UTF-16 时,介于 010000 和 10FFFF 范围内的字符都需要 4 个字节。 在这种情况下,可比较的数据类型(例如,char 与 nchar 之间)没有存储差异。

有关其他注意事项,请参阅编写国际化 Transact-SQL 语句

转换为 UTF-8

因为在 CHAR(n) 和 VARCHAR(n) 或在 NCHAR(n) 和 NVARCHAR(n) 中,n 定义字节存储大小,而不定义可以存储的字符数,所以确定必须转换的数据类型大小很重要,这可以避免数据被截断 。

例如,考虑定义为 NVARCHAR(100) 的列,该列存储了 180 个字节的日语字符。 在本示例中,当前使用 UCS-2 或 UTF-16 对列数据进行编码,每个字符使用 2 个字节。 将列类型转换为“VARCHAR(200)”不足以防止数据被截断,因为新的数据类型只能存储 200 个字节,而使用 UTF-8 编码时,日语字符需要 3 个字节。 因此,必须将列定义为 VARCHAR(270),以避免由于数据截断而丢失数据。

因此,在将现有数据转换为 UTF-8 之前,需要事先知道列定义的预计字节大小,并相应地调整新数据类型的大小。 请参阅数据示例 GitHub 中的 Transact-SQL 脚本或 SQL 笔记本,其中使用 DATALENGTH 函数和 COLLATE 语句来确定现有数据库中 UTF-8 转换操作的正确数据长度要求。

要更改现有表中的列排序规则和数据类型,请使用设置或更改列排序规则中所述的一种方法。

要更改数据库排序规则(默认允许新对象继承数据库排序规则)或更改服务器排序规则(默认允许新数据库继承系统排序规则),请参阅本文的相关任务部分。

[转帖]SQLServer的UTF8支持的更多相关文章

  1. 为Gradle添加UTF-8支持

    gradle默认使用系统字符编码,大多数中文系统是使用GBK编码 但程序员绝大部分都是使用UTF-8写各类java文件以及其他资源文件 编译时很容易报错,比如下面的错误: ”警告:编码 GBK 的不可 ...

  2. [转帖] sqlserver CAL 授权模式下 只能够有20个core的使用问题

    http://www.cnblogs.com/diabloxl/p/3623640.html?utm_source=tuicool&utm_medium=referral 公司这边性能组老师进 ...

  3. Source Insight 3.X utf8支持插件震撼发布

    继上次SI多标签插件之后,因为公司内部编码改为utf8编码,因此特意做了这个Source Insight 3.X utf8插件. 下载地址:[点我] 安装说明: 解压msimg32.dll sihoo ...

  4. [转帖]SQLSERVER的兼容级别

    SQL Server数据库的兼容级别 http://www.cnblogs.com/sosoft/archive/2017/07/08/sqljrjb.html 改天尝试一下 在SQLSERVER20 ...

  5. 使用的SQLServer版本不支持数据类型“datetime2“

    快速解决方法: 原因,在使用ado.net entity的时候,entity使用的数据库是sqlserver 2008, 但后来实际使用中使用的数据库是sqlserver 2005, 操作DateTi ...

  6. Source Insight 3.X utf8支持插件更新

    [更新内容] 修复了当UTF8文件外部改变时,SI无法检测到的bug. 实现 [下载地址] 点我 [计划] 未来(无限长)优化utf8编码检测规则,提高准确度.

  7. [转帖]SQLSERVER 使用触发器实现 禁用sa用户 在非本机登录

    原贴地址: https://blog.csdn.net/reblue520/article/details/51580102 具体的方法为: 创建一个触发器 CREATE TRIGGER forbid ...

  8. [转帖]SQLSERVER 查看服务器信息的命令

    SELECT SERVERPROPERTY('ServerName') AS ServerName SELECT SERVERPROPERTY('BuildClrVersion') AS BuildC ...

  9. SQLServer客户端连接工具(支持2000,20005,2008)

    绿色版本, 体积小(不到2M), 支持数据库版本2000 2005 2008 界面仿最经典的SQLServer2000: 下载地址:http://download.csdn.net/detail/gg ...

  10. [转帖]Sqlserver BCP 的用法

    SQL Server中bcp命令的用法以及数据批量导入导出 http://www.cnblogs.com/xwdreamer/archive/2012/08/22/2651180.html 我这边使用 ...

随机推荐

  1. 『Flutter』开篇

    什么是 Flutter Flutter 是由 Google 开发的开源框架 Flutter 用于构建跨平台的移动应用程序 Flutter 它允许开发者使用同一套代码来同时为 IOS 和 Android ...

  2. ASR项目实战-交付过程中遇到的疑似内存泄漏问题

    基于Kaldi实现语音识别时,需要引入一款名为OpenFST的开源软件,本文中提到的内存问题,即和这款软件相关. 考虑到过程比较曲折,内容相对比较长,因此先说结论. 在做长时间的语音识别时,集成了Ka ...

  3. [VMware]ESXI下硬盘的两种直通方式

    文章来自:https://rmbz.net/archives/vmware-esxi-passthrough 最近再搞ESXI,把原来的"黑群晖"改成ESXI:因为群晖里有数据,为 ...

  4. Spring表达式语言(SPEL)学习(01)

    算术运算 @Test public void test01() { // 定义解析器 ExpressionParser parser = new SpelExpressionParser(); // ...

  5. 揭秘Spring事务失效场景分析与解决方案

    在Spring框架中,事务管理是一个核心功能,然而有时候会遇到事务失效的情况,这可能导致数据一致性问题.本文将深入探讨一些Spring事务失效的常见场景,并提供详细的例子以及解决方案. 1. 跨方法调 ...

  6. 2023-05-28:为什么Redis单线程模型效率也能那么高?

    2023-05-28:为什么Redis单线程模型效率也能那么高? 答案2023-05-28: 1.C语言实现,效率高 C语言程序运行速度快,因为其相较于其他高级语言更加接近底层机器.由于C语言直接操作 ...

  7. GaussDB(for Redis)双活容灾支持4大应用场景,为业务安全保驾护航

    摘要:GaussDB(for Redis)的双活解决方案,支持同域主备.同域双主.异地主备.异地双主四大应用场景,提供了安全可靠的容灾能力. 一场火灾引发的思考 2021年3月10日,欧洲某云服务提供 ...

  8. “互联网+”大赛之智慧校园 赛题攻略:你的智慧校园,WeLink帮你来建

    摘要:本赛题的核心就是借助华为云WeLink的中台服务能力/开发工具等,结合学校的具体的高价值场景,开发出WeLink小程序,方便师生的学习与生活. 本文分享自华为云社区<"互联网+& ...

  9. 结MySQL 的一些知识点:MySQL 安装

    MySQL 安装 所有平台的 MySQL 下载地址为: MySQL 下载 . 挑选你需要的 MySQL Community Server 版本及对应的平台. **注意:**安装过程我们需要通过开启管理 ...

  10. Solon2 接口开发: 实战 Gateway 模式效果

    1.效果预览 网关 @Mapping("/api/v3/app/**") @Component public class ApiGateway3x extends UapiGate ...