'COLLATE SQL_Latin1_General_CP1_CI_AS'有什么作用?

问题描述 投票:102回答:5

我有一个SQL查询来在SQLServer中创建数据库,如下所示:

create database yourdb
on
( name = 'yourdb_dat',
  filename = 'c:\program files\microsoft sql server\mssql.1\mssql\data\yourdbdat.mdf',
  size = 25mb,
  maxsize = 1500mb,
  filegrowth = 10mb )
log on
( name = 'yourdb_log',
  filename = 'c:\program files\microsoft sql server\mssql.1\mssql\data\yourdblog.ldf',
  size = 7mb,
  maxsize = 375mb,
  filegrowth = 10mb )
COLLATE SQL_Latin1_General_CP1_CI_AS;
go

它运行正常。

虽然SQL的其余部分很清楚,但我对COLLATE SQL_Latin1_General_CP1_CI_AS的功能感到很困惑。

任何人都可以向我解释这个吗?另外,我想知道以这种方式创建数据库是否是最佳做法?

sql-server database tsql collation
5个回答
214
投票

它设置数据库服务器的排序方式。在这种情况下:

SQL_Latin1_General_CP1_CI_AS

分成有趣的部分:

  1. latin1使服务器使用charset latin 1处理字符串,基本上是ascii
  2. CP1代表Code Page 1252
  3. CI不区分大小写比较所以'ABC'将等于'abc'
  4. AS口音敏感,所以'ü'不等于'你'

附:有关更多详细信息,请务必访问read @solomon-rutzky's answer


45
投票

请注意,接受的答案有点不完整。是的,在最基本的级别Collat​​ion处理排序。但是,所选择的排序规则定义的比较规则在用户查询之外的许多地方用于用户数据。

如果“COLLATE SQL_Latin1_General_CP1_CI_AS做什么?”意思是“COLLATECREATE DATABASE条款做什么?”,然后:

COLLATE {collation_name}语句的CREATE DATABASE子句指定数据库的默认排序规则,而不是服务器;数据库级和服务器级默认Collat​​ions控制不同的东西。

服务器(即实例)级控件:

  • 系统数据库的数据库级排序规则:mastermodelmsdbtempdb
  • 由于控制了tempdb的DB级排序规则,因此它是临时表(全局和本地)中字符串列的默认排序规则,而不是表变量。
  • 由于控制了master的DB级排序,然后是用于服务器级数据的排序,例如数据库名称(即name中的sys.databases列),登录名等。
  • 处理参数/变量名称
  • 处理游标名称
  • 处理GOTO标签
  • 缺少COLLATE子句时,用于新创建的数据库的默认排序规则

数据库级控件:

  • 默认排序规则用于新创建的字符串列(CHARVARCHARNCHARNVARCHARTEXTNTEXT - 但不使用TEXTNTEXT)当列定义中缺少COLLATE子句时。这适用于CREATE TABLEALTER TABLE ... ADD声明。
  • 用于字符串文字(即'some text')和字符串变量(即@StringVariable)的默认排序规则。只有在将字符串和变量与其他字符串和变量进行比较时才会使用此排序规则。将字符串/变量与列进行比较时,将使用列的排序规则。
  • 用于数据库级元数据的排序规则,例如对象名称(即sys.objects),列名称(即sys.columns),索引名称(即sys.indexes)等。
  • 用于数据库级对象的排序规则:表,列,索引等。

也:

  • ASCII是8位编码(对于常见用途;技术上“ASCII”是7位,字符值0 - 127,“ASCII扩展”是8位,字符值0 - 255)。这个群体在各种文化中都是一样的。
  • 代码页是扩展ASCII的“扩展”部分,并控制哪些字符用于值128 - 255.该组在每种文化之间有所不同。
  • Latin1并不意味着“ASCII”,因为标准ASCII仅涵盖0到127的值,并且所有代码页(可以在SQL Server中表示,甚至NVARCHAR)将相同的128值映射到相同的字符。

如果“COLLATE SQL_Latin1_General_CP1_CI_AS做什么?”意思是“这个特殊的整理有什么作用?”,然后:

  • 因为名称以SQL_开头,所以这是SQL Server排序规则,而不是Windows排序规则。这些肯定是过时的,即使没有正式弃用,主要用于SQL Server 2000之前的兼容性。虽然,非常不幸的是SQL_Latin1_General_CP1_CI_AS很常见,因为它是在使用美国英语作为其语言的操作系统上安装时的默认设置。如果可能的话,应该避免这些整理。 Windows排序规则(名称不以SQL_开头的排序规则)更新,更具功能性,在VARCHARNVARCHAR之间对相同的值进行一致排序,并且正在使用其他/更正的排序权重和大写/小写映射进行更新。这些排序规则也没有SQL Server排序规则所具有的潜在性能问题:Impact on Indexes When Mixing VARCHAR and NVARCHAR Types
  • Latin1_General是文化/地区。 对于NCHARNVARCHARNTEXT数据,这决定了用于排序和比较的语言规则。 对于CHARVARCHARTEXT数据(列,文字和变量),这决定了: 用于排序和比较的语言规则。 用于编码字符的代码页。例如,Latin1_General归类使用代码页1252,Hebrew归类使用代码页1255,依此类推。
  • CP{code_page}{version} 对于SQL Server排序规则:CP{code_page},是8位代码页,用于确定哪些字符映射到值128 - 255.虽然双字节字符集(DBCS)有四个代码页,可以使用2字节组合创建更多超过256个字符,这些不适用于SQL Server排序规则。 对于Windows排序规则:{version}虽然不存在于所有排序规则名称中,但是指的是引入排序规则的SQL Server版本(大多数情况下)。名称中没有版本号的Windows排序规则是版本80(意味着SQL Server 2000,因为它是版本8.0)。并非所有版本的SQL Server都带有新的排序规则,因此版本号存在差距。有一些是90(对于SQL Server 2005,版本9.0),大多数是100(对于SQL Server 2008,版本10.0),而小集合有140(对于SQL Server 2017,版本14.0)。 我说“大部分”因为在_SC中结束的排序是在SQL Server 2012(版本11.0)中引入的,但底层数据并不是新的,它们只是添加了对内置函数的补充字符的支持。因此,对于版本90100排序规则存在这些结尾,但仅从SQL Server 2012开始。
  • 接下来,您将获得敏感度,可以是以下任意组合,但始终按此顺序指定: CS =区分大小写或CI =不区分大小写 AS =重音敏感或AI =重音不敏感 KS =假名类型敏感或缺失=假名类型不敏感 WS =宽度敏感或缺失=宽度不敏感 VSS =变体选择器敏感(仅在版本140排序规则中可用)或缺少=变体选择器不敏感
  • 可选的最后一块: _SC在最后意味着“补充字符支持”。 “支持”仅影响内置函数如何解释代理对(这是如何在UTF-16中编码补充字符)。如果最后没有_SC(或者中间是_140_),内置函数看不到单个补充字符,而是看到构成代理对的两个无意义的代码点。此结尾可以添加到任何非二进制,版本90或100排序规则。 最后_BIN_BIN2意味着“二元”排序和比较。数据仍然存储相同,但没有语言规则。这个结局永远不会与5种敏感性或_SC中的任何一种结合。 _BIN是较旧的风格,_BIN2是更新,更准确的风格。如果使用SQL Server 2005或更高版本,请使用_BIN2。有关_BIN_BIN2之间差异的详细信息,请参阅:Differences Between the Various Binary Collations (Cultures, Versions, and BIN vs BIN2)。 从SQL Server 2019开始,_UTF8是一个新选项。它是一个8位编码,允许将Unicode数据存储在VARCHARCHAR数据类型中(但不是已弃用的TEXT数据类型)。此选项仅可用于支持增补字符的排序规则(即名称中带有_SC的版本90或100排序规则,以及版本140排序规则)。还有一个二进制_UTF8整理(_BIN2,而不是_BIN)。 请注意:UTF-8的设计/创建是为了与为8位编码设置但又想支持Unicode的环境/代码兼容。即使有一些场景,与NVARCHAR相比,UTF-8可以节省高达50%的空间,这是一种副作用,并且在许多/大多数操作中具有轻微的性能损失成本。如果您需要兼容性,那么成本是可以接受的。如果你想节省空间,你最好测试一下,再测试一下。测试包括所有功能,而不仅仅是几行数据。请注意,当所有列和数据库本身使用带有VARCHAR排序规则的_UTF8数据(列,变量,字符串文字)时,UTF-8排序规则最佳。对于那些使用它来实现兼容性的人来说,这是一种自然状态,但对于那些希望将其用于节省空间的人来说则不然。使用_UTF8归类与使用非VARCHAR归类或_UTF8数据的NVARCHAR数据混合VARCHAR数据时要小心,因为您可能会遇到奇怪的行为/数据丢失。有关新UTF-8排序规则的更多详细信息,请参阅:Native UTF-8 Support in SQL Server 2019: Savior or False Prophet?

23
投票

CP1表示“代码页1” - 从技术上讲,这转换为代码页1252


15
投票

COLLATE关键字指定您用于字符串值的字符集和规则(顺序,对抗规则)。

例如,在您的情况下,您使用不区分大小写(CI)和重音敏感(AS)的拉丁规则

你可以参考这个Documentation


8
投票

这指定了数据库的默认排序规则。您在数据库中的表中创建的每个文本字段都将使用该排序规则,除非您指定另一个排序规则。

数据库始终具有默认排序规则。如果未指定any,则使用SQL Server实例的默认排序规则。

您使用的排序规则的名称显示它使用Latin1代码页1,不区分大小写(CI)和重音敏感(AS)。此排序规则在美国使用,因此它将包含在美国使用的排序规则。

排序规则决定如何比较文本值的相等性和相似性,以及在排序时如何比较它们。在存储非unicode数据时使用代码页,例如, varchar字段。

© www.soinside.com 2019 - 2024. All rights reserved.