概述

SQL Server长期以来一直以nchar,nvarchar和ntext数据类型的形式支持Unicode字符,这些字符仅限于UTF-16。可以将UTF-8数据放入nchar和nvarchar列中,但这 通常很乏味,即使 在SQL Server 2014 SP2中添加了通过BCP和BULK INSERT的UTF-8支持之后。最终结果是要支付Unicode的存储和内存需求,因为即使部分或全部为ASCII,仍然必须将所有数据存储为Unicode。

在SQL Server 2019中,有新的UTF-8排序规则,可让您节省存储空间,同时仍可享受兼容性和原生存储UTF-8数据的好处。与Unicode压缩类似(但不完全相同),您只需为实际需要该字符的字符支付额外的存储空间。但是,实际的存储影响是什么?这如何影响内存授予和查询性能?

测试过程

各种归类,代码页和UTF格式都有许多含义。我觉得专家可以撰写20个部分的文章系列,但仍然没有完成。实际上,所罗门·鲁兹基(Solomon Rutzky)已经写了很多有关这些主题的文章,最近 一篇有关SQL Server 2019中对UTF-8支持的文章 –这表明您可能不应该使用此功能,并且您应该专注于使用UTF-8列的排序规则应该主要是关于兼容性,而不是存储空间或性能。

因为我知道尽管有 Solomon的建议,人们仍然会使用它,所以我只想专注于特定的UTF-8排序规则,以及与传统Unicode列中存储的UTF-16数据相比,空间和内存要求有何不同。我将比较压缩与不压缩以及列值的各种百分比(以及表中行的百分比)与非ASCII数据的比较。

首先,让我们看一下一个表,该表包含具有三个不同排序规则的列,并查看当我们向其中插入数据时的外观。我为该查询拍摄了屏幕截图,因为我知道其中一些Unicode字符在到达您的设备时无法很好地转换:

共有三列,第一列使用标准Latin1_General归类,第二列包含具有补充字符(SC)的Latin1_General,第三列使用新的Latin1_General UTF-8归类。我分别插入了希腊字符,亚洲字符和表情符号(当然是加拿大国旗!),然后再插入一些其他ASCII字符。这是每个值的LEN()和DATALENGTH()的结果:

显然,您可以看到长度基本相同,唯一的不同是表情符号在第一次排序时需要四个字节(请参阅 Greg Low的这篇文章,以了解为什么这是字节而不是字符)。但是,使用UTF-8归类时,实际存储几乎总是相同或更低(再次,除了一个例外,这次亚洲字符需要一个额外的字节)。我为您省去了一个悬念:通过行和页面压缩以及类似的#temp表,所有结果都是相同的。

另外,上面的代码示例中的注释表明,即使目标类型是varchar,您仍然需要在字符串文字上使用N前缀。原因是SQL Server将首先尝试解释字符串的值,如果N不存在,则部分Unicode数据会丢失。

尝试这个:

DECLARE @t TABLE (t varchar(10) COLLATE Latin1_General_100_CI_AI_SC_UTF8);
INSERT @t(t) VALUES('h'),(N'h');
SELECT t FROM @t;
t
----
?
h

在玩这个游戏的过程中,我还发现了另一种现象,可能与排序规则完全无关,但仍然很有趣。当使用Unicode字符串的varbinary表示形式时(例如一堆poo表情符号,0x3DD8A9DC),可以根据语句中的其他内容来不同地解释它们。在此示例中,我要执行三个不同的批处理:

(1)直接插入varbinary值;

(2)直接插入值,并在单独的语句中,将值转换为nvarchar后插入;

(3)将值和转换后的值插入同一条语句中:

DECLARE @t TABLE (t varchar(10) COLLATE Latin1_General_100_CI_AI_SC_UTF8);
INSERT @t(t) VALUES(0x3DD8A9DC);
SELECT t FROM @t;
GO -- 1DECLARE @t TABLE (t varchar(10) COLLATE Latin1_General_100_CI_AI_SC_UTF8);
INSERT @t(t) VALUES(0x3DD8A9DC);
INSERT @t(t) VALUES(CONVERT(nvarchar(10),0x3DD8A9DC));
SELECT t FROM @t;
GO -- 2DECLARE @t TABLE (t varchar(10) COLLATE Latin1_General_100_CI_AI_SC_UTF8);
INSERT @t(t) VALUES(0x3DD8A9DC),(CONVERT(nvarchar(10),0x3DD8A9DC));
SELECT t FROM @t;
GO -- 3

结果让我感到困惑:

在使用不同的语句执行插入的情况下,两个解释都正确。但是,当使用VALUES()将两行插入在一起时,两者都以某种方式转换为nvarchar。涉及VALUES()的行为,可能与归类无关,但在以后的技巧中,我将不得不对此进行研究。同时,如果要将脚本从一种形式更改为另一种形式,请注意这一点。

回到原来的调查;如果我们大规模尝试该怎么办?我编写了一个脚本,该脚本为一堆表生成CREATE TABLE语句,这些表具有用于校对,压缩和实际存储多少非ASCII数据的各种设置。具体来说,这将创建81个表,这些表具有以下组合:

  • 压缩(行,页,无);
  • 排序规则(Latin1_General_100_CI_AI,Latin1_General_100_CI_AI _SC和Latin1_General_100_CI_AI _SC_UTF8);
  • 包含UTF-8数据的行百分比(0%,50%,100%);和,
  • 每行是UTF-8数据的字符数(0个字符,25个字符和50个字符):
CREATE TABLE #cmp(cmp varchar(4));
INSERT #cmp VALUES('ROW'),('PAGE'),('NONE');
CREATE TABLE #coll(coll varchar(8));
INSERT #coll VALUES(''),('_SC'),('_SC_UTF8');
CREATE TABLE #row(rowconf varchar(9));
INSERT #row VALUES('0  % UTF8'),('50 % UTF8'),('100% UTF8');
CREATE TABLE #char(charconf varchar(7));
INSERT #char VALUES('0 UTF8'),('25 UTF8'),('50 UTF8');
SELECT N'CREATE TABLE dbo.' + QUOTENAME(N'UTF8Test' + coll.coll + N'_' + cmp.cmp + N'_' + rowconf + N'_' + charconf) + N'
(id int IDENTITY(1,1) NOT NULL,the_column ' + CASE coll.coll WHEN '_SC_UTF8' THEN N'' ELSE N'n' END + N'varchar(512)' END + N' COLLATE Latin1_General_100_CI_AI' + coll.coll + N',CONSTRAINT ' + QUOTENAME(N'pk_UTF8Test_' + coll.coll + N'_' + cmp.cmp + N'_' + rowconf + N'_' + charconf) + N' PRIMARY KEY CLUSTERED(id) WITH (DATA_COMPRESSION = ' + cmp.cmp + N')
);' FROM #cmp AS cmp, #coll AS coll, #row AS rowconf, #char AS charconf;

该脚本产生81行输出,并具有如下表定义(当然,它们不是漂亮的脚本):

CREATE TABLE dbo.[UTF8Test_ROW_0  % UTF8_0 UTF8]
(id int IDENTITY(1,1) NOT NULL,the_column nvarchar(200) COLLATE Latin1_General_100_CI_AI,CONSTRAINT [pk_UTF8Test__ROW_0  % UTF8_0 UTF8] PRIMARY KEY CLUSTERED(id)WITH (DATA_COMPRESSION = ROW)
);
CREATE TABLE dbo.[UTF8Test_SC_ROW_0  % UTF8_0 UTF8]
(id int IDENTITY(1,1) NOT NULL,the_column nvarchar(200) COLLATE Latin1_General_100_CI_AI_SC,CONSTRAINT [pk_UTF8Test__SC_ROW_0  % UTF8_0 UTF8] PRIMARY KEY CLUSTERED(id)WITH (DATA_COMPRESSION = ROW)
);
CREATE TABLE dbo.[UTF8Test_SC_UTF8_ROW_0  % UTF8_0 UTF8]
(id int IDENTITY(1,1) NOT NULL,the_column varchar(200) COLLATE Latin1_General_100_CI_AI_SC_UTF8,CONSTRAINT [pk_UTF8Test__SC_UTF8_ROW_0  % UTF8_0 UTF8] PRIMARY KEY CLUSTERED(id)WITH (DATA_COMPRESSION = ROW)
);… 78 more tables …

复制,粘贴,执行,现在您有81个表,可以生成INSERT语句以类似的方式进行填充。这里涉及更多逻辑,因此脚本更加丑陋-我们希望在每个表中插入10,000行,但是这些行是部分或全部填充(或未填充)Unicode数据的值的混合。我在这里有加拿大国旗,并在该位置添加了注释,以防它无法在您的浏览器中正确显示:

DECLARE @sql nvarchar(max) = N'SET NOCOUNT ON;';
SELECT @sql += N'
WITH n AS (SELECT n = 1 UNION ALL SELECT n+1 FROM n WHERE n < 10000)
INSERT dbo.' + QUOTENAME(N'UTF8Test' + coll.coll + N'_' + cmp.cmp + N'_' + rowconf + N'_' + charconf) + N'(the_column) SELECT b FROM (SELECT b = REPLICATE(N''												

UTF-8支持对SQL Server 2019的影响相关推荐

  1. 微软宣布SQL Server 2019免费支持Java

    在 2018 年 9 月的时候,微软就宣布与领先的 Java 开源贡献者和发行商 Azul Systems 建立新的合作伙伴关系.这一关系允许所有 Azure 客户在微软和 Azul 联合提供的支持下 ...

  2. 微软 SQL Server 2019 将免费支持 Java;Rancher Labs获2500万美元融资;腾讯云进军日本市场……...

    关注并标星星CSDN云计算 极客头条:速递.最新.绝对有料.这里有企业新动.这里有业界要闻,打起十二分精神,紧跟fashion你可以的! 每周三次,打卡即read 更快.更全了解泛云圈精彩news g ...

  3. 微软宣布 SQL Server 2019 免费支持 Java

    在 2018 年 9 月的时候,微软就宣布与领先的 Java 开源贡献者和发行商 Azul Systems 建立新的合作伙伴关系.这一伙伴关系允许所有 Azure 客户在微软和 Azul 联合提供的支 ...

  4. 华为在 5G 初期不考虑盈利;​网易发布数据中台;微软 SQL Server 2019 免费支持 Java | 极客头条...

    快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...

  5. 数据库SQL Server 2019安装向导的“功能选择”详细说明(微软官方资料)

    使用SQL Server 2019安装向导的"功能选择" SQL Server 页上的复选框为您的 SQL Server 安装选择组件. 安装 SQL Server 功能 在 &q ...

  6. Visual Studio Code连接SQL SERVER 2019

    Visual Studio Code连接SQL SERVER 2019 Visual Studio Code 是一个运行于 OS X.Windows 和 Linux 之上的多种编程语言支持的IDE,基 ...

  7. mysql 2005开发版,SQL server 2019 开发版下载

    SQL server 2019 亮点 分析所有类型的数据 使用内置有 Apache Spark 的 SQL Server 2019,跨关系.非关系.结构化和非结构化数据进行查询,从所有数据中获取见解, ...

  8. 微软发布 SQL Server 2019 新版本

    2019 年 11 月 4 日,微软在美国奥兰多举办的 Ignite 大会上发布了关系型数据库 SQL Server 的新版本.与之前版本相比,新版本的 SQL Server 2019 具备以下重要功 ...

  9. 如何在SQL Server 2019中添加数据敏感度分类的命令

    作者 | Jordan Sanders 翻译 | 火火酱.责编 | 晋兆雨 头图 | CSDN付费下载于视觉中国 为了确保数据库安全性和完整性,数据库管理员日常需要运行多种操作.因此,无论在何种情况下 ...

最新文章

  1. 事件绑定在IE下this是window的问题
  2. Python字符串方法用示例解释
  3. Android应用开发:页面跳转和数据传递
  4. 非科班通过几个月的培训入行人工智能现实吗?
  5. Ayoub and Lost Array
  6. 第三次学JAVA再学不好就吃翔(part51)--String类的转换功能
  7. XSS-Game level 8
  8. shell十三问-3) 別人 echo、你也 echo ,是问 echo 知多少
  9. layuiadmin上手好难_日语中“上手”和“得意”、“下手”和“苦手”到底怎么区别?...
  10. 关于大学生是否沉迷游戏的报告
  11. 如何防止Tensorflow分配整个GPU内存?
  12. 对接企业支付宝的流程(电脑和手机)
  13. 勇敢面对人生的苦难,时光不负赶路人
  14. 天翼云,不要来,千万不要来!开始统计工时,安装监控软件,减少福利!
  15. 【火影之卡卡西动漫主题】
  16. 色彩理论之彩虹CMYK值
  17. cad展点kszd小程序_cad实现批量展坐标点方法介绍
  18. Sketch for UX Design Sketch UX设计教程 Lynda课程中文字幕
  19. 欺骗的艺术----(9)
  20. 苹果笔记本有uefi启动吗_联想和华硕笔记本重装系统时新BIOS无法设置u盘启动怎么办...

热门文章

  1. audible 有声书_如何在iPhone或iPad上购买Kindle或Audible书
  2. ExecuteNoneQuery、ExecuteScalar和ExecuteReader用法和区别
  3. Locating and Editing Factual Associations in GPT翻译
  4. 电脑访问网络的原理之白话篇
  5. nginx配置以及rewrite规则
  6. 画出烟熏眼妆的6大要点,清纯小女生谨记
  7. 【设计杂志的软件】名编辑电子杂志大师教程 | 添加本地视频
  8. 自动化技术之airtest安装使用教程
  9. MySQL查询时给字段赋默认值
  10. java怎么给按钮自定义位置_Java按钮的自定义