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. 聊聊ChatGLM-6B部署与微调的深入理解

    ChatGLM的部署,主要是两个步骤: 在Github上下载chatglm的库文件 在Hugging Face上下载模型参数与配置文件 ChatGLM包 从Github上看ChatGLM项目文件的结构 ...

  2. [NLP复习笔记] 基于负采样的 Skip-gram 及 SGD 训练公式推导

    1. one-hot 向量 我们先了解一下 \(\text{one-hot}\) 向量.\(\text{one-hot}\) 编码是表示分类变量的常见方法,尤其在数据预处理和机器学习的特征工程中.一个 ...

  3. 深入剖析 Linux Cgroups 子系统:资源精细管理

    本章主要演示以下 cgroups 下各个 subsystem 的作用. 根据难易程度,依次演示了 pids .cpu 和 memory 3 个 subsystem 的使用. 注:本文所有操作在 Ubu ...

  4. 聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(三)

    前言 今天的第三篇,感觉没啥人看呀,难道没有兄弟跟我有同样的整合需求吗???手动 , 本文会简短一些,介绍下 CastleCore 作为代理库的一些缺点甚至是硬伤 异步支持 先上代码 /// < ...

  5. C#/.NET/.NET Core面试宝典(基础版)

    前言 该知识库主要由自己平时学习实践总结.网上优秀文章资料收集(这一部分会标注来源)和社区小伙伴提供三部分组成.欢迎关注我的微信公众号(声明公众号不推广告,纯属个人技术文章分享)回复关键字获取宝库地址 ...

  6. 神经网络基础篇:向量化(Vectorization)

    向量化 向量化是非常基础的去除代码中for循环的艺术,在深度学习安全领域.深度学习实践中,会经常发现自己训练大数据集,因为深度学习算法处理大数据集效果很棒,所以的代码运行速度非常重要,否则如果在大数据 ...

  7. 【玩转鲲鹏DevKit系列】何如快速迁移有源码应用

    本文分享自华为云社区<[玩转鲲鹏DevKit系列]何如快速迁移有源码应用>,作者:华为云社区精选 . 源码(也称源程序)是程序员编写的计算机程序的文本形式,不同的编程语言有不同的语法和规则 ...

  8. webpack性能优化(2):splitChunks用法详解

    之前写的<webpack性能优化(0):webpack性能优化概况-优化构建速度>.<webpack性能优化(1):分隔/分包/异步加载+组件与路由懒加载> 如果使用vue-c ...

  9. Solon:Hello world!

    Solon:Hello world! (一)新建一个 maven 空项目 (二)添加 maven 引用 <dependency> <groupId>org.noear</ ...

  10. Cypress系列(1)-Window下安装Cypress并打开

    Cypress系列(1)-Window下安装Cypress并打开 系统要求 Cypress是一个被安装在你电脑上的桌面应用,你的操作系统需要满足如下条件才能正常安装 Mac OS 10.9+(仅提供6 ...