2012-03-18 20 views
10

He leído mucho sobre esto.¿Cuál es el punto de COLLATIONS para columnas nvarchar (Unicode)?

Aún así algunas preguntas:

No estoy hablando de mayúsculas y minúsculas aquí ...

  • Si tengo un char (ש por ejemplo) y que se almacena en nvarchar - que puede contener cualquier cosa , ¿Por qué necesitaría collation aquí?

  • Si soy "Facebook" y necesito la capacidad de almacenar all caracteres de idiomas all, ¿Cuál es la relación entre el cotejo y mis columnas nvarchar?

Gracias de antemano.

+5

Una intercalación no dice [directamente] qué se puede almacenar. Una intercalación determina el orden y la igualdad. Por ejemplo, algunas intercalaciones no distinguen entre mayúsculas y minúsculas o son insensibles a los acentos, mientras que otras no lo son. –

+0

@pst si almacené 'ש' y hago 'ordenar por', así que debe ordenar por sus caracteres que incluyen' ש'. .....no ? –

+0

@ user166390 "Una intercalación no dice [directamente] qué se puede almacenar". no es del todo cierto. Solo es cierto para los campos 'NVARCHAR' /' NCHAR'. Para los campos 'VARCHAR' y' CHAR', Collation determina qué se puede almacenar allí, ya que contiene el LCID que determina la Página de códigos. –

Respuesta

8

Almacenar y representar caracteres es una cosa, y saber cómo ordenarlos y compararlos es otro.

Los datos Unicode, almacenados en XML y N -los tipos prefijados en SQL Server, pueden representar todos los caracteres en todos los idiomas (en su mayor parte, y ese es su objetivo) con un único juego de caracteres. Por lo tanto, para XML/NCHAR/NVARCHAR datos (estoy omitiendo NTEXT ya que no debería utilizarse), las intercalaciones no cambian los caracteres que se pueden almacenar. Para CHAR y VARCHAR de datos, las configuraciones que hacen afectan lo que puede ser almacenado como cada punto de intercalación a un código particular de página, lo que determina lo que puede ser almacenada en valores de 128 - 255.

Ahora, si bien hay un orden predeterminado orden para todos los personajes, que no puede funcionar en todos los idiomas y culturas. Hay muchos idiomas que comparten algunos/muchos/todos los caracteres, pero tienen reglas diferentes sobre cómo ordenarlos. Por ejemplo, la letra "C" viene antes que la letra "D" en la mayoría de los alfabetos que usan esas letras. En inglés de EE. UU., Una combinación de "C" y "H" (es decir, "CH" como dos letras separadas) aparecería naturalmente antes de cualquier secuencia que comience con una "D".Sin embargo, en unos pocos idiomas, la combinación de dos letras "CH" es especial y ordena después "D":

IF ( N'CH' COLLATE Czech_CI_AI > N'D' COLLATE Czech_CI_AI 
    AND N'C' COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI 
    AND N'CI' COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI 
    ) PRINT 'Czech_CI_AI'; 

IF ( N'CH' COLLATE Czech_100_CI_AI > N'D' COLLATE Czech_100_CI_AI 
    AND N'C' COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI 
    AND N'CI' COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI 
    ) PRINT 'Czech_100_CI_AI'; 

IF ( N'CH' COLLATE Slovak_CI_AI > N'D' COLLATE Slovak_CI_AI 
    AND N'C' COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI 
    AND N'CI' COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI 
    ) PRINT 'Slovak_CI_AI'; 

IF ( N'CH' COLLATE Slovak_CS_AS > N'D' COLLATE Slovak_CS_AS 
    AND N'C' COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS 
    AND N'CI' COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS 
    ) PRINT 'Slovak_CS_AS'; 

IF ( N'CH' COLLATE Latin1_General_100_CI_AS > N'D' COLLATE Latin1_General_100_CI_AS 
    AND N'C' COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS 
    AND N'CI' COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS 
    ) PRINT 'Latin1_General_100_CI_AS' 
ELSE PRINT 'Nope!'; 

Devuelve:

Czech_CI_AI 
Czech_100_CI_AI 
Slovak_CI_AI 
Slovak_CS_AS 
Nope! 

Para ver ejemplos de reglas de clasificación a través varias culturas, vean: Collation Charts.

Además, en algunos idiomas, ciertas letras o combinaciones de letras equivalen a otras letras de manera que no lo hacen en la mayoría de los demás idiomas. Por ejemplo, solo en danés, una "å" equivale a "aa". Sin embargo, la "A" no equivale a un solo "a":

IF (N'aa' COLLATE Danish_Greenlandic_100_CI_AI = N'å' COLLATE Danish_Greenlandic_100_CI_AI 
AND N'a' COLLATE Danish_Greenlandic_100_CI_AI <> N'å' COLLATE Danish_Greenlandic_100_CI_AI 
    ) PRINT 'Danish_Greenlandic_100_CI_AI'; 

IF ( N'aa' COLLATE Danish_Norwegian_CI_AI = N'å' COLLATE Danish_Norwegian_CI_AI 
    AND N'a' COLLATE Danish_Norwegian_CI_AI <> N'å' COLLATE Danish_Norwegian_CI_AI 
    ) PRINT 'Danish_Norwegian_CI_AI'; 

IF ( N'aa' COLLATE Latin1_General_100_CI_AI = N'å' COLLATE Latin1_General_100_CI_AI 
    AND N'a' COLLATE Latin1_General_100_CI_AI <> N'å' COLLATE Latin1_General_100_CI_AI 
    ) PRINT 'Latin1_General_100_CI_AI' 
ELSE PRINT 'Nope!'; 

devoluciones:

Danish_Greenlandic_100_CI_AI 
Danish_Norwegian_CI_AI 
Nope! 

Todo esto es muy complejo, y ni siquiera he mencionado el manejo de derecha idiomas a la izquierda (hebreo y árabe), chino, japonés, combinación de caracteres, etc.

Si desea conocer a fondo las reglas, consulte Unicode Collation Algorithm (UCA). Los ejemplos anteriores se basan en ejemplos de esa documentación, aunque no creo que se hayan implementado todas las reglas en el UCA, especialmente porque las intercalaciones de Windows (intercalaciones no comenzando con SQL_) se basan en Unicode 5.0 o 6.0, dependiendo en qué sistema operativo está utilizando y la versión de .NET Framework que está instalada (consulte SortVersion para obtener más información).

Así que eso es lo que hacen las Collations. Si desea ver todas las intercalaciones que están disponibles, simplemente ejecute lo siguiente:

SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name]; 
6

Si tiene un char, no hay pedido. Pero si ordena, por ejemplo, NOMBRES DE PERSONAS: diferentes caracteres especiales en diferentes idiomas se ordenan de forma diferente dependiendo de la intercalación.

primero una intercalación puede ser sensible a mayúsculas y minúsculas; muestra todo B antes que b, y los segundos caracteres especiales tienen reglas especiales según la intercalación.

La documentación es bastante buena sobre eso.

+0

¿Cómo puede sql ordenar inglés, árabe, hebreo juntos? no hay una lógica común ...? por favor explique –

+0

Puede, si es ignorante. Y use por ejemplo el orden de la fortaleza inglesa en todas partes. Sally esto no es necesariamente correcto. http://www.sqlservercentral.com/blogs/rocks/2012/01/09/revised-difference-between-collation-sql_latin1_general_cp1_ci_as-and-latin1_general_ci_as/ tiene un ejemplo (español). ¿Crees que los MS son idiotas? http://msdn.microsoft.com/en-us/library/ms144250.aspx tiene todas las intercalaciones y MUCHAS de ellas son específicas del idioma. ¿Crees que lo hacen sin una razón? No, a veces la posición de los caracteres especiales en el orden de clasificación depende del idioma. – TomTom

6

Creo que el cartel original se confunde entre las PÁGINAS DE CÓDIGO y las COLOCACIONES.

La "n" en nvarchar/nchar le permite almacenar texto utilizando el conjunto de números Unicode que es lo suficientemente grande como para incorporar todos los caracteres en todos los idiomas (en principio de todos modos) con un número único. Esto en sí mismo no está relacionado con intercalaciones. nvarchar/nchar no utiliza las PÁGINAS DE CÓDIGO para codificar/decodificar el significado de cada código de carácter.

Las intercalaciones definen el orden de los caracteres y las variantes de caracteres que deben tratarse como idénticas. nvarchar/nchar SÍ usa COLLATIONS para definir estas distinciones.