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. Linux应急响应总结——更新中

    Linux应急响应 用户信息 方向 查看可登录的用户: cat /etc/passwd | grep /bin/bash awk -F: '{if($7!="/usr/sbin/nologi ...

  2. 动态规划问题(四)最长双音序列长度(LBS)

    问题描述 ​ 以一个乱序的数组,求它的最长双音序列长度.双音序列指该序列先递增,再递减. ​ 如: 对于序列 {1, 11, 2, 10, 4, 5, 2, 1},它的最长双音序列长度为 6, 对于序 ...

  3. 为什么匿名内部类可以实例化并实现抽象方法?lambda表达式是简化了匿名内部类的实现过程吗?

    为什么匿名内部类可以实例化并实现抽象方法? 在Java中,接口是一种特殊的抽象类型,它只定义了一个或多个抽象方法.接口不能被实例化,但是我们可以使用匿名内部类来实现接口并创建一个具体的对象. 匿名内部 ...

  4. Karmada 结合 coreDNS 插件实现跨集群统一域名访问

    本文分享自华为云社区<Karmada 结合 coreDNS 插件实现跨集群统一域名访问>,作者:云容器大未来 . 在多云与混合云越来越成为企业标配的今天,服务的部署和访问往往不在一个 K8 ...

  5. 3步带你搞定华为云编译构建CodeArts Build “新手村任务”

    华为云编译构建(CodeArts Build)基于云端大规模并发加速,为客户提供高速.低成本.配置简单的混合语言构建能力,帮助客户缩短构建时间,提升构建效率. 本文将给各位开发者带来华为云CodeAr ...

  6. DarkMode(4):css滤镜 颜色反转实现深色模式

    在<DarkMode(1):产品应用深色模式分析>提过,单纯反转是不行的.但是,把不需要反转的,在反转过来.或者用js,给想要反转的,加上反转样式,再对其他的做微调.这样个人觉得,开发成本 ...

  7. 高性能 Jsonpath 框架,Snack3 v3.2.44 发布

    Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表示,ONode也 ...

  8. Vue 多环境配置

    没有使用 package.json 进行配置 ,改配置时不需要重新打包 Vue 多环境配置 package.json settings.js window.environment="dev& ...

  9. 使用formdata在vue和django之间传递文件

    在前端页面中如果有文件或者图片需要上传的场景下,通用做法是使用formdata将文件从前端传输到后台,在后台上传文件并将url保存在数据库. 当前项目是使用vue + Element UI + dja ...

  10. mysql--ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

    问题背景: 1.在授权机器上连接mysql 8.0的数据库,账号.密码都没有问题,报错 2.使用 navicat工具连接8.0版本,报错 排查思路: 可能是创建用户没有指定插件使用了8.0自带的插件, ...