- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
通过研究针对我的特定应用程序的SQL Server VARCHAR与NVARCHAR的优缺点,我意识到,如果SQL Server本地支持UTF8,那将是理想的选择。几条SO帖子指示不这样做,例如:
Is VARCHAR like totally 1990s?
What are the main performance differences between varchar and nvarchar SQL Server data types?
但是,然后我在SQL Server 2012的MSDN文档中遇到了这篇文章,该文章显示了如何创建UTF8String用户定义的数据类型:
http://msdn.microsoft.com/en-us/library/ff877964(v=sql.110).aspx
似乎UDT会考虑到每个字符8位的空间(内存,磁盘)好处,同时又足够灵活地存储可以用UTF-8表示的任何字符串。那是对的吗?此策略是否有缺点(例如,为每一行执行托管代码的性能成本,等等)?
最佳答案
无论如何,通过SQLCLR创建自定义的用户定义类型都不会让您替换任何本机类型。创建某些东西来处理专用数据非常方便。但是,即使是不同编码的字符串也远非专业化。采用这种方式处理字符串数据将破坏系统的任何可用性,更不用说性能了,因为您将无法使用任何内置的字符串函数。
如果您能够在磁盘空间上节省任何东西,那么这些收益将被整体性能上的损失所抵消。通过将UDT序列化为VARBINARY
来存储它。因此,为了进行任何字符串比较或排序,在“二进制” /“普通”比较之外,您必须将所有其他值一个接一个地转换回UTF-8,然后再进行可以考虑的字符串比较语言差异。并且该转换将需要在UDT中完成。这意味着,与XML数据类型一样,您将创建UDT以保存特定值,然后公开该UDT的方法以接受字符串参数进行比较(即Utf8String.Compare(alias.field1)
,或者,如果为类型,然后输入Utf8string1 = Utf8string2
并让=
运算符获取UTF-8编码的字符串,然后执行CompareInfo.Compare()
。
除了上述考虑之外,您还需要考虑通过SQLCLR API来回传递值会带来成本,尤其是分别使用NVARCHAR(MAX)
或VARBINARY(MAX)
而不是分别使用NVARCHAR(1 - 4000)
和VARBINARY(1 - 4000)
时(请请勿混淆此区别,因为它暗示了有关使用SqlChars
/ SqlBytes
vs SqlString
/ SqlBinary
的任何信息)。
最后(至少在使用UDT方面),请不要忽略被查询的UDT是示例代码的事实。唯一提到的测试是纯功能性的,与可伸缩性或“使用此功能一年后的经验教训”无关。功能测试代码显示在下面的CodePlex页面上,应在进行此决定之前进行查看,因为它可以使您了解如何编写查询才能与其进行交互(这对于字段或两个,但不适用于大多数/所有字符串字段):
http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/Scripts/Test.sql
给定添加的持久计算列和索引的数量,是否真的节省了空间? ;-)
在需要空间(磁盘,内存等)的地方,您有三个选择:
如果您使用的是SQL Server 2008或更高版本,并且在Enterprise Edition上,则可以启用Data Compression。数据压缩可以(但不会“总是”)压缩NCHAR
和NVARCHAR
字段中的Unicode数据。决定因素是:NCHAR(1 - 4000)
和NVARCHAR(1 - 4000)
使用Standard Compression Scheme for Unicode,但仅从SQL Server 2008 R2开始,并且仅用于行内数据,而不用于溢出!这似乎比常规的ROW / PAGE压缩算法要好。
行内(不在LOB或OVERFLOW页中的行外)的NVARCHAR(MAX)
和XML
(我猜也是VARBINARY(MAX)
,TEXT
和NTEXT
)数据可以至少进行PAGE压缩,也许ROW压缩(不确定最后一个)。
任何行外数据,LOB或OVERLOW =无需压缩!
如果使用的版本早于2008,或者未在Enterprise Edition上使用,则可以具有两个字段:一个VARCHAR
和一个NVARCHAR
。例如,假设您存储的URL通常都是基本ASCII字符(值0-127),因此适合VARCHAR
,但有时具有Unicode字符。您的架构可以包括以下3个字段:
...
URLa VARCHAR(2048) NULL,
URLu NVARCHAR(2048) NULL,
URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
AND ([URLa] IS NULL OR [URLu] IS NULL))
);
[URL]
计算列中进行选择。对于插入和更新,您可以通过查看转换是否会改变输入值来确定要使用哪个字段,该值必须为
NVARCHAR
类型:
INSERT INTO TableName (..., URLa, URLu)
VALUES (...,
IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
);
VARCHAR
。
_SC
排序规则仅允许:
_SC
归类,您仍然可以将任何Unicode字符存储到XML或
N
前缀类型中,并在不丢失数据的情况下进行检索。但是,使用较旧的排序规则(即名称中没有版本号)时,所有补充字符都彼此等同。您需要使用
_90
和
_100
归类,它们至少可以使您进行二进制/代码点比较和排序。他们没有考虑语言规则,因为它们没有对补充字符的特定映射(因此也没有权重或规范化规则)。
IF (N'𤪆' = N'𤪆') SELECT N'𤪆' AS [TheLiteral], NCHAR(150150) AS [Generated];
IF (N'𤪆' = N'𤪇') SELECT N'𤪇' AS [TheLiteral], NCHAR(150151) AS [Generated];
IF (N'𤪆' COLLATE Tatar_90_CI_AI = N'𤪇' COLLATE Tatar_90_CI_AI)
SELECT N'𤪇 COLLATE Tatar_90_CI_AI' AS [TheLiteral], NCHAR(150151) AS [Generated];
IF (N'𤪆' = N'?') SELECT N'?';
_SC
结尾的数据库中,只有第一个
IF
语句将返回结果集,并且“ Generated”字段将正确显示字符。
_SC
结尾的默认排序规则,并且该排序规则不是
_90
或
_100
系列排序规则,则前两个
IF
语句返回结果集,其中“ Generated”字段将返回
NULL
,并且“文字”字段正确显示。
VARCHAR
/
CHAR
数据类型中引入了对UTF-8的本机支持。当前有太多的错误需要使用,但是,如果它们已修复,则在某些情况下是一种选择。请参阅我的文章“
Native UTF-8 Support in SQL Server 2019: Savior or False Prophet?”,以详细了解此新功能。
关于sql-server - UTF-8支持,SQL Server 2012和UTF8String UDT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8996002/
本周我将在 Windows Server 2008 上设置一个专用的 SQL Server 2005 机器,并希望将其精简为尽可能简单,同时仍能发挥全部功能。 为此,“服务器核心”选项听起来很有吸引力
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 8 年前。 Improve
我获取了 2014 版本数据库的备份,并尝试在另一台服务器中将其恢复到具有相同名称和登录名的数据库中。此 SQL Server 版本是 2016。 恢复备份文件时,出现此错误: TITLE: Micr
我获取了 2014 版本数据库的备份,并尝试在另一台服务器中将其恢复到具有相同名称和登录名的数据库中。此 SQL Server 版本是 2016。 恢复备份文件时,出现此错误: TITLE: Micr
TFS 是否提供任何增强的方法来存储对 sql server 数据库所做的更改,而不是使用它来对在数据库上执行的 sql 语句的文本文件进行版本控制? 或者我正在寻找的功能是否仅在第 3 方工具(如
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我即将将我的 SQL Server 2012 实例升级到 SQL Server 2014。 我已经克隆了主机 Windows VM 并将其重命名为 foo-2012至 foo-2014 . 重新启动时
我想为 SQL Server 登录授予对数据库的访问权限。我知道 sp_grantdbaccess,但它已被弃用。我可以改用什么以及如何检查登录名是否还没有访问数据库的权限? 场景:UserA 创建数
客户别无选择,只能在接下来的几天内从 sql server 2000 迁移到 2008。测试显示 2005 年的重要功能出现了 Not Acceptable 性能下降,但 2008 年却没有。好消息是
我有一个测试数据库,我需要将其导出到我们客户的测试环境中。 这将是一次性的工作。 我正在使用 SQL Server 2005(我的测试数据库是 SQL Server 2005 Express) 执行此
我需要将一个 CSV 文件导入到 mongoDB 不幸的是我遇到了以下错误: error connecting to host: could not connect to server: se
我以为 R2 是一个补丁/服务包。我一直在寻找下载,但没有看到。因此,我假设 R2 是一个新版本,并且我需要 sqlserver 2008 r2 的安装介质来进行升级? 另外,我需要为新许可证付费吗?
我无法使用 SQL Server Management Studio 连接到 SQL Server。 我有一个连接字符串: 我尝试通过在服务器名中输入 myIP、在登录名中输入 MyID、在密码中
我们希望使用 SQL Server 加密来加密数据库中的几个列。我们还需要在生产和测试环境之间传输数据。看来最好的解决方案是在生产和测试服务器上使用相同的主 key 、证书和对称 key ,以便我可以
有没有可以分析 SQL Server 数据库潜在问题的工具? 例如: a foreign key column that is not indexed 没有 FILL FACTOR 的 uniquei
我正在尝试从我的 SQL 2012 BI 版本建立复制,但我收到一条奇怪的错误消息! "You cannot create a publication from server 'X' because
如果您使用 SQL Server 身份验证 (2005),登录详细信息是否以明文形式通过网络发送? 最佳答案 如您所愿,安全无忧... 您可以相当轻松地配置 SSL,如果您没有受信任的证书,如果您强制
我想将数据从一个表复制到不同服务器之间的另一个表。 如果是在同一服务器和不同的数据库中,我使用了以下 SELECT * INTO DB1..TBL1 FROM DB2..TBL1 (to copy w
我希望得到一些帮助,因为我在这个问题上已经被困了 2 天了! 场景:我可以从我的开发计算机(和其他同事)连接到 SERVER\INSTANCE,但无法从另一个 SQL Server 连接。我得到的错误
我正在尝试从我的 SQL 2012 BI 版本建立复制,但我收到一条奇怪的错误消息! "You cannot create a publication from server 'X' because
我是一名优秀的程序员,十分优秀!