indexación contra cadenas que no distinguen entre mayúsculas y minúsculas, pero el caso de los datos persiste. ¿Cómo funciona esto realmente?
En realidad, este no es un comportamiento específico de SQL Server, es simplemente cómo funcionan estas cosas en general.
Entonces, los datos son los datos. Si usted está hablando de un índice concreto, los datos debe ser almacenado, ya que es otra cosa sería necesaria una consulta en la tabla principal cada vez para obtener el valor real, y no habría ninguna posibilidad de un índice de cobertura (en al menos no para los tipos de cadena).
Los datos, ya sea en la tabla / índice agrupado o en el índice no agrupado, no contienen ninguna información de clasificación / clasificación. Es simplemente datos. La intercalación (reglas y sensibilidades locales / culturales) son solo metadatos adjuntos a la columna y se usan cuando se llama a una operación de clasificación (a menos que sea anulada por unCOLLATE
cláusula), que incluiría la creación / reconstrucción de un índice. Las reglas definidas por una intercalación no binaria se utilizan para generar claves de clasificación, que son representaciones binarias de la cadena (las claves de clasificación no son necesarias en las intercalaciones binarias). Estas representaciones binarias incorporan todas las reglas locales / culturales y sensibilidades seleccionadas. Las claves de clasificación se utilizan para colocar los registros en su orden correcto, pero no se almacenan en el índice o la tabla. No están almacenados (al menos no he visto estos valores en el índice y me dijeron que no están almacenados) porque:
- No son realmente necesarios para la clasificación, ya que de todos modos estarían simplemente en el mismo orden que las filas de la tabla o índice. Pero, el orden físico del índice es solo ordenar, no comparar.
- Si bien almacenarlos podría hacer que las comparaciones sean más rápidas, también aumentaría el índice, ya que el tamaño mínimo para un solo carácter es de 5 bytes, y eso es solo "sobrecarga" (de la estructura de la clave de clasificación). La mayoría de los caracteres son de 2 bytes cada uno, más 1 byte si hay acento, más 1 byte si está en mayúscula. Por ejemplo, "e" es una clave de 7 bytes, "E" y "é" son 8 bytes, y "É" es una clave de 9 bytes. Por lo tanto, no vale la pena almacenarlos al final.
Hay dos tipos de intercalaciones: SQL Server y Windows.
servidor SQL
Las intercalaciones de SQL Server (aquellas con nombres que comienzan con SQL_
) son la forma anterior de clasificación / comparación anterior a SQL Server 2000 (aunque todavíaSQL_Latin1_General_CP1_CI_AS
es la instalación predeterminada en los sistemas operativos de inglés de EE. UU., Por desgracia). En este modelo anterior, simplista y no Unicode, cada combinación de configuración regional, página de códigos y las diversas sensibilidades reciben una asignación estática de cada uno de los caracteres en esa página de códigos. A cada personaje se le asigna un valor (es decir, clasificar el peso) para indicar cómo se compara con los demás. Las comparaciones en este modelo parecen hacer una operación de dos pasos:
- Primero, elimina todos los acentos (de modo que " ü " se convierte en " u "), expande caracteres como " Æ " en " A " y " E ", luego realiza una ordenación inicial para que las palabras estén en un orden natural (cómo lo haría Espere encontrarlos en un diccionario).
- Luego, va carácter por carácter para determinar la igualdad en función de estos valores subyacentes por cada carácter. Esta segunda parte es lo que describe Mustaccio en su respuesta .
Las únicas sensibilidades que se pueden ajustar en estas intercalaciones son: "mayúsculas y minúsculas" ("ancho", "tipo kana" y "selector de variación" no están disponibles). Además, ninguna de estas colaciones admite caracteres suplementarios (lo cual tiene sentido ya que son específicos de Unicode y estas colaciones solo se aplican a datos que no son Unicode).
Este enfoque se aplica solo a VARCHAR
datos que no son Unicode . Cada combinación única de configuración regional, página de códigos, mayúsculas y minúsculas tiene una "ID de clasificación" específica, que puede ver en el siguiente ejemplo:
SELECT COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CI_AS', 'SortID'), -- 52
COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CS_AS', 'SortID'), -- 51
COLLATIONPROPERTY(N'Latin1_General_100_CI_AS', 'SortID'); -- 0
La única diferencia entre las dos primeras colaciones es la sensibilidad a mayúsculas y minúsculas. La tercera intercalación es una intercalación de Windows y, por lo tanto, no tiene una tabla de asignación estática.
Además, estas clasificaciones deben clasificarse y compararse más rápido que las clasificaciones de Windows debido a que son simples búsquedas de caracteres para clasificar el peso. Sin embargo, estas intercalaciones también son mucho menos funcionales y generalmente deben evitarse si es posible.
Ventanas
Las intercalaciones de Windows (aquellas con nombres que no comienzan con SQL_
) son la forma más nueva de ordenar / comparar (comenzando en SQL Server 2000). En este modelo Unicode más nuevo y complejo, cada combinación de configuración regional, página de códigos y las diversas sensibilidades no reciben una asignación estática. Por un lado, no hay páginas de códigos en este modelo. Este modelo asigna un valor de clasificación predeterminado a cada carácter, y luego cada localidad / cultura puede reasignar los valores de clasificación a cualquier número de caracteres. Esto permite que múltiples culturas usen los mismos personajes de diferentes maneras. Esto tiene el efecto de permitir que varios idiomas se ordenen naturalmente usando la misma clasificación si no usan los mismos caracteres (y si uno de ellos no necesita reasignar ningún valor y simplemente puede usar los valores predeterminados).
Los valores de clasificación en este modelo no son valores únicos. Son una matriz de valores que asignan pesos relativos a la letra base, cualquier signo diacrítico (es decir, acentos), mayúsculas y minúsculas, etc. Si la intercalación distingue entre mayúsculas y minúsculas, se utiliza la parte de "mayúsculas" de esa matriz, de lo contrario se ignora ( por lo tanto, insensible). Si la intercalación es sensible al acento, se usa la porción "diacrítica" de la matriz, de lo contrario se ignora (por lo tanto, insensible).
Las comparaciones en este modelo son una operación de varios pasos:
- Primero, la cadena se normaliza de modo que se igualen varias formas de representar el mismo carácter. Por ejemplo, " ü " podría ser un solo carácter / punto de código (U + 00FC). También puede combinar una " u " sin acento (U + 0075) con una Diaéresis combinada " ̈ " (U + 0308) para obtener: " ü ", que no solo se ve igual cuando se procesa (a menos que haya un problema con su fuente), pero también se considera que es la misma que la versión de un solo carácter (U + 00FC), a menos que utilice una intercalación binaria (que compara bytes en lugar de caracteres). La normalización divide el carácter individual en varias piezas, que incluyen expansiones para caracteres como " Æ " (como se indicó anteriormente para las intercalaciones de SQL Server).
- La operación de comparación en este modelo va carácter por carácter por cada sensibilidad . Las claves de clasificación para las cadenas se determinan aplicando los elementos apropiados de cada conjunto de valores de clasificación de caracteres en función de qué sensibilidades son "sensibles". Los valores de la clave de clasificación están ordenados por todas las sensibilidades primarias de cada carácter (el carácter base), seguidas por todas las sensibilidades secundarias (peso diacrítico), seguidas por el peso de mayúsculas y minúsculas de cada carácter, y así sucesivamente.
- La ordenación se realiza en función de las claves de ordenación calculadas. Con cada sensibilidad agrupada, puede obtener un orden de clasificación diferente del que obtendría con una intercalación de SQL Server equivalente al comparar cadenas de varios caracteres, y los acentos están involucrados, y la intercalación es sensible al acento (y aún más si la intercalación es también distingue entre mayúsculas y minúsculas).
Para obtener más detalles sobre esta clasificación, eventualmente publicaré una publicación que muestre los valores de clave de clasificación, cómo se calculan, las diferencias entre SQL Server y las intercalaciones de Windows, etc. Pero por ahora, vea mi respuesta a: Clasificación sensible acentuada ( tenga en cuenta que la otra respuesta a esa pregunta es una buena explicación del algoritmo oficial Unicode, pero SQL Server utiliza un algoritmo personalizado, aunque similar, e incluso una tabla de peso personalizada).
Todas las sensibilidades se pueden ajustar en estas intercalaciones: "mayúsculas", "acento", "ancho", "tipo kana" y "selector de variación" (a partir de SQL Server 2017, y solo para las intercalaciones japonesas). Además, algunas de estas intercalaciones (cuando se usan con datos Unicode) admiten caracteres suplementarios (a partir de SQL Server 2012). Este enfoque se aplica tanto a los datos NVARCHAR
como a los VARCHAR
datos (incluso los datos que no son Unicode). Se aplica a VARCHAR
datos que no son Unicode convirtiendo primero el valor a Unicode internamente y luego aplicando las reglas de clasificación / comparación.
Tenga en cuenta:
- No existe una clasificación universal predeterminada para SQL Server. Hay un valor predeterminado de instalación que difiere según la configuración regional / de idioma actual del sistema operativo en el momento de la instalación (que desafortunadamente es
SQL_Latin1_General_CP1_CI_AS
para los sistemas de inglés de EE. UU., Por lo tanto , vote por esta sugerencia ). Esto se puede cambiar durante la instalación. Esta clasificación a nivel de instancia establece la clasificación para la base de [model]
datos, que es la plantilla utilizada al crear nuevas bases de datos, pero la clasificación se puede cambiar al ejecutar CREATE DATABASE
especificando la COLLATE
cláusula. Esta clasificación a nivel de base de datos se usa para literales variables y de cadena, así como el valor predeterminado para columnas nuevas (¡y alteradas!) Cuando COLLATE
no se especifica la cláusula (que es el caso del código de ejemplo en la pregunta).
- Para obtener más información sobre intercalaciones / codificaciones / Unicode, visite: Información de intercalaciones