¿Qué hace 'COLLATE SQL_Latin1_General_CP1_CI_AS'?

134

Tengo una consulta SQL para crear la base de datos en SQLServer como se muestra a continuación:

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

Funciona bien

Si bien el resto del SQL está claro, estoy bastante confundido acerca de la funcionalidad de COLLATE SQL_Latin1_General_CP1_CI_AS.

¿Puede alguien explicarme esto? Además, me gustaría saber si crear la base de datos de esta manera es una práctica recomendada.

Trueno
fuente

Respuestas:

246

Establece cómo se ordena el servidor de la base de datos (compara fragmentos de texto). en este caso:

SQL_Latin1_General_CP1_CI_AS

se divide en partes interesantes:

  1. latin1 hace que el servidor trate cadenas usando charset latin 1, básicamente ascii
  2. CP1 significa Código Página 1252
  3. CI comparaciones sin distinción entre mayúsculas y minúsculas para que 'ABC' sea igual a 'abc'
  4. AS sensible al acento, entonces 'ü' no es igual a 'u'

PD Para obtener información más detallada, asegúrese de leer la respuesta de @ solomon-rutzky .

Kris
fuente
11
¿Cuál sería la diferencia entre esto y SQL_Latin1_General_CI_AS. Específicamente, CP1 me hizo preguntarme.
Kad
77
@Kad: Parece que no hay un SQL_Latin1_General_CI_AS. Más bien, hay un Latin1_General_CI_AS. Ver SELECT * FROM fn_helpcollations() where name IN ('SQL_Latin1_General_CP1_CI_AS','Latin1_General_CI_AS','SQL_Latin1_General_CI_AS');. Hay diferencias sutiles con respecto a la clasificación y la comparación entre las dos colaciones. Ver olcot.co.uk/sql-blogs/… .
Riley Major
44
@Kad: CP1 representa la página de códigos 1252. Una página de códigos es una tabla de búsqueda para asignar el valor hexadecimal a un carácter específico en un conjunto de caracteres. CP1 es la abreviatura de CP1252 en la subcultura de Microsoft. Windows es la única plataforma que utiliza CP1252 de forma nativa, ya que es una retención de los días de DOS. Aunque es muy similar a ISO 8859-1, no son lo mismo. Hay diferencias en los caracteres mapeados como el euro y algunos otros que no están en ISO 8859-1.
slartibartfast
respuesta impecable @Kris!
gaurav
@Kris ¿Hay alguna alternativa UTF-8 para SQL_Latin1_General_CP1_CI_AS en SQL2019?
Chanky
72

Tenga en cuenta que la respuesta aceptada es un poco incompleta. Sí, en el nivel más básico, Collation maneja la clasificación. PERO, las reglas de comparación definidas por la Clasificación elegida se usan en muchos lugares fuera de las consultas de los usuarios contra los datos del usuario.

Si "¿Qué hace COLLATE SQL_Latin1_General_CP1_CI_AS?" significa "¿Qué hace la COLLATEcláusula de CREATE DATABASEhacer?", entonces:

La COLLATE {collation_name}cláusula de la CREATE DATABASEdeclaración especifica la clasificación predeterminada de la base de datos , y no el servidor; Las colaciones predeterminadas de nivel de base de datos y nivel de servidor controlan cosas diferentes.

Controles de nivel de servidor (es decir, instancia) :

  • Intercalación de nivel de base de datos para las bases de datos del sistema: master, model, msdb, y tempdb.
  • Debido al control de la Clasificación de nivel DB tempdb, es la Clasificación predeterminada para las columnas de cadena en las tablas temporales (globales y locales), pero no las variables de tabla.
  • Debido al control de la Clasificación de nivel de base de datos master, es la Clasificación utilizada para los datos de nivel de Servidor , como los nombres de la Base de datos (es decir, la namecolumna sys.databases), los nombres de inicio de sesión, etc.
  • Manejo de nombres de parámetros / variables
  • Manejo de nombres de cursor
  • Manejo de GOTOetiquetas
  • Clasificación predeterminada utilizada para las bases de datos recién creadas cuando COLLATEfalta la cláusula

Controles a nivel de base de datos :

  • Intercalación predeterminada utilizado para las columnas de cadena de nueva creación ( CHAR, VARCHAR, NCHAR, NVARCHAR, TEXT, y NTEXT- pero no use TEXTo NTEXT) cuando la COLLATEcláusula no se encuentra en la definición de columna. Esto va para ambos CREATE TABLEy ALTER TABLE ... ADDdeclaraciones.
  • Clasificación predeterminada utilizada para literales de cadena (es decir 'some text') y variables de cadena (es decir @StringVariable). Esta intercalación solo se usa cuando se comparan cadenas y variables con otras cadenas y variables. Al comparar cadenas / variables con columnas, se utilizará la Clasificación de la columna.
  • La clasificación utilizada para metadatos a nivel de base de datos, como nombres de objetos (es decir sys.objects, nombres de columnas (es decir sys.columns), nombres de índice (es decir sys.indexes), etc.
  • La clasificación utilizada para los objetos de nivel de base de datos : tablas, columnas, índices, etc.

También:

  • ASCII es una codificación de 8 bits (para uso común; técnicamente "ASCII" es de 7 bits con valores de caracteres 0 - 127, y "ASCII Extended" es de 8 bits con valores de caracteres 0 - 255). Este grupo es el mismo en todas las culturas.
  • La página de códigos es la parte "extendida" de ASCII extendido y controla qué caracteres se usan para los valores 128 - 255. Este grupo varía entre cada cultura.
  • Latin1no no media "ASCII", ya que ASCII estándar sólo cubre los valores 0 - 127, y todas las páginas de códigos (que se puede representar en SQL Server, e incluso NVARCHAR) Mapa esos mismos 128 valores a los mismos personajes.

Si "¿Qué hace COLLATE SQL_Latin1_General_CP1_CI_AS?" significa "¿Qué hace esta colación en particular?", entonces:

  • Debido a que el nombre comienza con SQL_, esta es una intercalación de SQL Server, no una intercalación de Windows. Estos son definitivamente obsoletos, incluso si no están en desuso oficialmente, y son principalmente para la compatibilidad anterior a SQL Server 2000. Aunque, desafortunadamente, SQL_Latin1_General_CP1_CI_ASes muy común debido a que es el valor predeterminado cuando se instala en un sistema operativo con el inglés de EE. UU. Como idioma. Estas colaciones deben evitarse si es posible.

    Las intercalaciones de Windows (aquellas con nombres que no comienzan SQL_) son más nuevas, más funcionales, tienen una clasificación consistente entre VARCHARy NVARCHARpara los mismos valores, y se actualizan con pesos de clasificación adicionales / corregidos y asignaciones en mayúsculas / minúsculas. Estas intercalaciones tampoco tienen el posible problema de rendimiento que tienen las intercalaciones de SQL Server: Impacto en los índices al mezclar los tipos VARCHAR y NVARCHAR .

  • Latin1_General es la cultura / locale
    • Para NCHAR, NVARCHARy NTEXTdatos esto determina las reglas lingüísticas utilizadas para la clasificación y la comparación.
    • Para CHAR, VARCHARy TEXTdatos (columnas, literales y variables) esto determina:
      • Reglas lingüísticas utilizadas para la clasificación y la comparación.
      • página de códigos utilizada para codificar los caracteres. Por ejemplo, las Latin1_Generalcolaciones usan la página de códigos 1252, las Hebrewcolaciones usan la página de códigos 1255, y así sucesivamente.
  • CP{code_page} o {version}

    • Para las intercalaciones de SQL Server :, CP{code_page}es la página de códigos de 8 bits que determina qué caracteres se asignan a los valores 128 a 255. Si bien hay cuatro páginas de códigos para juegos de caracteres de doble byte (DBCS) que pueden usar combinaciones de 2 bytes para crear más de 256 caracteres, estos no están disponibles para las intercalaciones de SQL Server.
    • Para las intercalaciones de Windows : {version}aunque no está presente en todos los nombres de intercalación, se refiere a la versión de SQL Server en la que se introdujo la intercalación (en su mayor parte). Las intercalaciones de Windows sin número de versión en el nombre son versión 80(es decir, SQL Server 2000, ya que es la versión 8.0). No todas las versiones de SQL Server vienen con nuevas intercalaciones, por lo que hay lagunas en los números de versión. Hay algunos que son 90(para SQL Server 2005, que es la versión 9.0), la mayoría son 100(para SQL Server 2008, versión 10.0), y un conjunto pequeño tiene 140(para SQL Server 2017, versión 14.0).

      Dije "en su mayor parte" porque las intercalaciones que terminan en _SCse introdujeron en SQL Server 2012 (versión 11.0), pero los datos subyacentes no eran nuevos, simplemente agregaron soporte para caracteres suplementarios para las funciones integradas. Entonces, esas terminaciones existen para la versión 90y las 100intercalaciones, pero solo comienzan en SQL Server 2012.

  • A continuación, tiene las sensibilidades, que pueden estar en cualquier combinación de lo siguiente, pero siempre especificadas en este orden:
    • CS= sensible a mayúsculas o CIminúsculas
    • AS= sensible al AIacento o = insensible al acento
    • KS = Kana sensible al tipo o faltante = Kana insensible al tipo
    • WS = sensible al ancho o faltante = insensible al ancho
    • VSS = selector de variación sensible (solo disponible en las colaciones de la versión 140) o falta = selector de variación insensible
  • Opcional última pieza:

    • _SCal final significa "Soporte complementario de caracteres". El "soporte" solo afecta la forma en que las funciones integradas interpretan los pares sustitutos (que es cómo se codifican los caracteres suplementarios en UTF-16). Sin _SCal final (o _140_en el medio), las funciones integradas no ven un solo carácter suplementario, sino que ven dos puntos de código sin sentido que forman el par sustituto. Este final se puede agregar a cualquier intercalación no binaria, versión 90 o 100.
    • _BINo _BIN2al final significa clasificación y comparación "binarias". Los datos aún se almacenan igual, pero no hay reglas lingüísticas. Este final nunca se combina con ninguna de las 5 sensibilidades o _SC. _BINes el estilo más antiguo y _BIN2es el estilo más nuevo y preciso. Si usa SQL Server 2005 o más reciente, use _BIN2. Para obtener detalles sobre las diferencias entre _BINy _BIN2, consulte: Diferencias entre las diversas colaciones binarias (Culturas, versiones y BIN vs BIN2) .
    • _UTF8es una nueva opción a partir de SQL Server 2019. Es una codificación de 8 bits que permite almacenar datos Unicode VARCHARy CHARtipos de datos (pero no el TEXTtipo de datos obsoleto ). Esta opción solo se puede usar en intercalaciones que admiten caracteres suplementarios (es decir, intercalaciones de la versión 90 o 100 con _SCsu nombre y colaciones de la versión 140). También hay una sola _UTF8colación binaria ( _BIN2, no _BIN).

      TENGA EN CUENTA: UTF-8 fue diseñado / creado para ser compatible con entornos / código que están configurados para codificaciones de 8 bits pero que desean admitir Unicode. Aunque hay algunos escenarios en los que UTF-8 puede proporcionar hasta un 50% de ahorro de espacio en comparación NVARCHAR, eso es un efecto secundario y tiene un costo de un ligero impacto en el rendimiento en muchas / la mayoría de las operaciones. Si necesita esto por compatibilidad, entonces el costo es aceptable. Si quieres esto para ahorrar espacio, tienes una mejor prueba y PRUEBA DE NUEVO. Las pruebas incluyen toda la funcionalidad y más que unas pocas filas de datos. Tenga en cuenta que las intercalaciones UTF-8 funcionan mejor cuando TODAS las columnas, y la base de datos en sí, están utilizando VARCHARdatos (columnas, variables, literales de cadena) con un_UTF8colación. Este es el estado natural para cualquiera que use esto por compatibilidad, pero no para aquellos que esperan usarlo para ahorrar espacio. Tenga cuidado al mezclar datos VARCHAR usando una _UTF8intercalación con VARCHARdatos que usan no _UTF8colaciones o NVARCHARdatos, ya que puede experimentar un comportamiento extraño / pérdida de datos. Para obtener más detalles sobre las nuevas intercalaciones UTF-8, consulte: Soporte nativo de UTF-8 en SQL Server 2019: ¿Salvador o falso profeta?

Solomon Rutzky
fuente
55
Si bien voté por esto por contener tanta información y esfuerzo, mi respuesta definitivamente no es incorrecta (las bases de datos almacenan datos, los servidores de bases de datos actúan sobre estos datos, la clasificación está actuando). Elegí la brevedad sobre la precisión matemática completa porque el OP probablemente estaba buscando suficiente información, no toda la información posible.
Kris
44
Hola @ kris Gracias. Para ser justos, no dije que tu respuesta fuera completamente incorrecta, simplemente lamentablemente incompleta. He actualizado para aclarar eso con suerte. Entiendo lo que estás diciendo, pero el OP me preguntó qué hace la COLLATEcláusula CREATE DATABASE. Dijiste una de varias cosas que hace. ¿Por qué supone que el OP solo quiere saber el 10% de la respuesta? Si se presenta toda la información, cada persona puede decidir cuánto tomar. Pero si solo se da alguna información, entonces se tomó la decisión por ellos. Elijo proporcionar tanta información como sea posible porque la mayor parte no se conoce bien. (continuación)
Solomon Rutzky
55
Creo que entiendo lo que quieres decir, pero mi objetivo es proporcionar suficiente información en lugar de demasiada. demasiada información rápidamente se vuelve demasiado complicada para mucha gente. y cuando no proporcione suficiente información para cualquier circunstancia, esperaré preguntas de seguimiento. (Tampoco esperaba tanta atención al tema)
Kris
8
@Kris He querido decir por un tiempo decir "¡Gracias!" por mostrar tal madurez y profesionalismo. Estoy algo acostumbrado a que las personas ofendan personalmente a alguien que dice que están equivocadas, y luego se vuelven "difíciles" (o incluso más difíciles) para interactuar. Pero, su respuesta mesurada a mi, "la respuesta aceptada es INCORRECTA " me inspiró a atenuar mi introducción, y debería servir como ejemplo para otros aquí sobre cómo comunicarse de manera adecuada y productiva 😺.
Solomon Rutzky
44
De nada y agradable escuchar que de alguna manera tuve un impacto positivo, pero disfruto de estar "equivocado", abre oportunidades para aprender cosas nuevas, ¡lo cual es genial!
Kris
24

El CP1 significa 'Página de códigos 1', técnicamente esto se traduce en la página de códigos 1252

Chris Halcrow
fuente
16

La palabra clave COLLATE especifica qué tipo de juego de caracteres y reglas (orden, reglas de confrontación) está utilizando para los valores de cadena.

Por ejemplo, en su caso, está utilizando reglas latinas con mayúsculas y minúsculas ( CI ) y acento ( AS )

Puedes consultar esta documentación

il_guru
fuente
9

Esto especifica la clasificación predeterminada para la base de datos. Cada campo de texto que cree en las tablas de la base de datos utilizará esa intercalación, a menos que especifique una diferente.

Una base de datos siempre tiene una clasificación predeterminada. Si no especifica ninguno, se utiliza la clasificación predeterminada de la instancia de SQL Server.

El nombre de la clasificación que utiliza muestra que utiliza la página de códigos Latin1 1, no distingue entre mayúsculas y minúsculas (CI) y acento (AS). Esta clasificación se usa en los EE. UU., Por lo que contendrá reglas de clasificación que se usan en los EE. UU.

La clasificación decide cómo se comparan los valores de texto para la igualdad y la semejanza, y cómo se comparan al ordenar. La página de códigos se usa cuando se almacenan datos no unicode, por ejemplo, campos varchar.

Guffa
fuente
incorrecto (no puede notespecificar una intercalación, aunque puede aceptar el valor predeterminado) incorrecto (también se utiliza para datos Unicode)
RichardTheKiwi
@Richard aka cyberkiwi: Consulte la documentación: msdn.microsoft.com/en-us/library/ms176061.aspx La especificación de la clasificación es opcional. La página de códigos no se utiliza para almacenar datos Unicode, ya que se almacenan como puntos de código Unicode de 16 bits, no como índices de página de códigos de 8 bits.
Guffa
Leí mal tu respuesta, pero sigue siendo incorrecta. Una base de datos siempre tiene una intercalación predeterminada = intercalación de SERVIDOR , no específicamente Latin1_General_CI_AS. Ahora lo leí mal porque casi esperaba que la declaración fuera sobre la recopilación del SERVIDOR, lo que requiere la aceptación del valor predeterminado en la interfaz de usuario. Para el segundo punto, parece implicar que la intercalación no se usa para ordenar datos unicode (aunque cambie de sortinga storingen las últimas 2 oraciones). Los datos de texto Unicode también obedecen a intercalaciones.
RichardTheKiwi
@Richard aka cyberkiwi: Cambié el párrafo sobre la clasificación predeterminada para que se corresponda con la documentación específica a la que me vinculé. (Difiere según la versión del servidor). Con respecto al segundo punto, no puedo ver cómo podría aclararlo. El texto dice que la página de códigos se usa cuando se almacenan datos no unicode. Una página de códigos no se utiliza para determinar la clasificación, ni para datos unicode ni para datos no unicode.
Guffa