¿Por qué se considera malo mezclar intercalaciones de columnas en una sola base de datos?

11

Hay dos razones que me llevan a hacer esta pregunta:

tSQLt
El marco de prueba de T-SQL tSQLt lo considera un problema de "Alta gravedad" cuando existen columnas con una intercalación no predeterminada. El autor de la prueba declara lo siguiente:

NO estoy sugiriendo que cada columna de cadena debe tener una clasificación que coincida con la clasificación predeterminada para la base de datos. En cambio, sugiero que cuando sea diferente, debería haber una buena razón para ello.

Sin embargo, la gravedad de la prueba fallida es, como se mencionó, considerada alta.

Octopus Deploy
Al configurar el servidor Octopus Deploy, la configuración falla con un error FATAL durante la inicialización de la instancia de OctopusServer. El artículo relacionado con el mensaje de error no explica por qué esto es un requisito, sino que simplemente establece que será un requisito para futuras implementaciones, desde Octopus incluida la versión 3.8.

Como nota al margen, el paquete de herramientas CI de RedGate, DLM Automation Suite , admite implementaciones con diferentes clasificaciones sin quejas.

La recomendación de mantener todas las intercalaciones de columnas en el valor predeterminado de la base de datos me parece más una guía o una mejor práctica. ¿Por qué algunos lo consideran un error tan grave?

krystah
fuente
Te refieres a las encarnaciones tSQLt de las pruebas de SQL Cop. Como las pruebas tSQLt pasan o fallan, estas tienen que ofrecer un valor predeterminado recomendado. Se espera que los usuarios adapten las pruebas SQLCop a sus propios requisitos, ya que no son más que procedimientos almacenados en el esquema SQLCop recogido por el marco tSQLt.
David Atkinson

Respuestas:

19

La recomendación de mantener todas las intercalaciones de columnas en el valor predeterminado de la base de datos me parece más una guía o una mejor práctica.

Tienes toda la razón aquí.

¿Por qué algunos lo consideran un error tan grave?

Por la misma razón que a menudo escuchará / leerá que " nunca debe usar:"

  • CURSORES
  • GOTO declaraciones
  • SQLCLR
  • WITH (NOLOCK)
  • etc, etc, etc.

Algunas características / opciones / tecnologías son más complicadas que otras y generalmente requieren más conocimiento por parte del usuario porque las posibilidades de meterse en problemas al usarlas son mucho mayores que las posibilidades de no tener ningún problema. Por lo tanto, es más fácil tener reglas generalizadas contra tales cosas para la población en general. De hecho, al escribir "Normas de codificación" en el trabajo, siempre tendré una regla para nuncauso CURSORES, pero los uso yo mismo porque sé tanto "cuándo" usarlos y "cómo" usarlos de manera efectiva. Pero no se debe esperar que las personas que solo ocasionalmente escriben consultas sepan eso. Esto también es similar a "no edite el Registro a menos que sepa absolutamente lo que está haciendo", o las reglas que establecemos como padres para nuestros hijos (muy pequeños) en los que debemos decirles que no hagan algo simplemente porque son no es capaz de atravesar las complejidades de cuándo está bien hacer una cosa en particular o cómo hacerlo.

En el caso de las intercalaciones, este es un tema muy complejo y confuso, y puede encontrarse con ambos errores duros (estos son un problema, pero no tanto, ya que son obvios y, por lo tanto, lo suficientemente fáciles de solucionar) y "extraños" comportamiento donde es difícil explicar por qué las cosas están actuando de la manera en que lo están (por qué algunos elementos se filtran o no, fuera de las expectativas, O por qué la clasificación actúa fuera de las expectativas). Y, lamentablemente, parece haber una gran cantidad de información errónea flotando alrededor que fomenta la confusión masiva. De hecho, estoy trabajando en un proyecto para aumentar en gran medida el conocimiento general de intercalaciones y codificaciones, etc. y espero contrarrestar la información errónea y los mitos, pero aún no estoy listo para publicarlo (cuando lo haga, actualizaré esto con un enlace).

Para la recopilación, debe usar lo que tenga más sentido para el caso de negocios. La noción de no mezclar intercalaciones en una tabla o base de datos es un enfoque predeterminado, pero si observa las intercalaciones utilizadas para las diversas columnas de las vistas del catálogo del sistema, notará que se utilizan diversas intercalaciones. Por lo tanto, estoy de acuerdo con la cita principal en la pregunta de que SI las colaciones van a ser diferentes, debería ser intencional, pero no hay nada intrínsecamente malo en ello.


Con respecto a esto de la pregunta (énfasis agregado):

Al configurar el servidor de implementación de Octopus, la configuración falla con un error FATAL durante la inicialización de la instancia de OctopusServer. El artículo relacionado con el mensaje de error no explica por qué es un requisito.

Revisé la página de documentación vinculada y de hecho explica por qué es un requisito. He copiado la información pertinente de esa documentación a continuación:

Debe asegurarse de cambiar también la clasificación de todos los objetos en la base de datos de Octopus, de lo contrario, pueden producirse errores al modificar la base de datos durante las actualizaciones de la versión de Octopus. Los nuevos objetos creados usarán la intercalación actualizada y, al intentar (por ejemplo) realizar uniones SQL entre estos y los objetos existentes utilizando la intercalación original, pueden producirse errores de coincidencia de intercalación.

Están diciendo que su código, en la base de datos Octopus, tiene uniones entre columnas de cadenas y probablemente podría introducir un nuevo código en una actualización futura que tenga uniones adicionales en nuevas columnas de cadenas. A las nuevas columnas, ya sea vía CREATE TABLEo ALTER TABLE ... ADD, se les asignará la Clasificación predeterminada de la base de datos si elCOLLATEla palabra clave no se especificó para las nuevas columnas de cadena. Y las uniones entre columnas de cadenas que no tienen la misma clasificación generarán un error de discrepancia de clasificación. También parecen estar permitiendo al usuario elegir su propia clasificación (posiblemente para acomodar diferentes configuraciones regionales) ya que dicen en la parte superior que el único requisito es que la clasificación no distinga entre mayúsculas y minúsculas. Y dado que no se garantiza que la Clasificación de la base de datos en la que vive su código sea siempre la misma, no pueden usar la COLLATEpalabra clave para forzar la misma Clasificación en todas las columnas de cadenas nuevas (bueno, técnicamente pueden, pero eso requiere Dinámico SQL, por lo que no es fácil de tratar al generar scripts de actualización). Si pudieran usar la COLLATEpalabra clave, entonces podríanevite que la clasificación predeterminada de la base de datos sea diferente a las columnas de cadena. Eso evitaría los errores duros de "No coincidencia de colación", pero aún dejaría abierta la posibilidad de operaciones de comparación que involucren una de esas columnas de cadena y una cadena literal o variable que resulte en un comportamiento "extraño", ya que usaría la Colación de la columna y no la Base de datos Colación. Por supuesto, eso podría muy bien ser un comportamiento esperado. Pero como se trata de una aplicación de terceros, el comportamiento debe ser el que pretendían, en lugar de una posibilidad de 50/50 entre a) lo que el usuario quería (o no objetó) yb) lo que el usuario considera un error (y luego desperdicia el tiempo de soporte del proveedor en una búsqueda y / o blogs sobre cómo su software tiene errores).

Solomon Rutzky
fuente
oye, ¿alguna noticia sobre ese proyecto sobre Colaciones?
Yaroslav
10

En una frase corta: COLLATION define la clasificación y la comparación .

Entonces, la clasificación determina las reglas que SQL Server usa para comparar y ordenar datos de caracteres. Estas reglas tienen en cuenta el idioma / la configuración regional y también pueden ser sensibles a mayúsculas y minúsculas, acento, Kana y ancho. Los sufijos de intercalación identifican la regla (in) sensibilidad del diccionario: _CS (distingue entre mayúsculas y minúsculas), _CI (no distingue entre mayúsculas y minúsculas), _AS (distingue por el acento), _AI (insensible por acento) y _KS (distingue entre Kana). Las intercalaciones binarias, identificadas por los sufijos _BIN (binario) y _BIN2 (punto de código binario), son sensibles en todos los aspectos.

Las diferentes intercalaciones ciertamente exigirán soluciones alternativas para evitar errores de "no se pueden resolver conflictos de intercalación" y pueden matar el rendimiento debido a las expresiones no compatibles que se pueden conocer . Tratar con diferentes colaciones puede ser una pesadilla (he estado allí), por eso la recomendación de elegir una y seguir con ella.

Más referencias:

Yaroslav
fuente
1

Como con muchas cosas, en versiones anteriores de SQL podría causar problemas bastante importantes. Ver este artículo de SQL7 / 2000

SqlServerClation central

Ahora es mucho más robusto, y hay situaciones en las que se justifica en sistemas más modernos, pero todavía hay algunas advertencias bastante interesantes para cambiarlo.

Aquí hay otra serie útil sobre versiones más modernas. Por Dan Guzman, quien creo que publica aquí regularmente para que pueda hablar pronto :)

SQL Collation Hell

En resumen, la compatibilidad, la estandarización y los posibles resultados de rendimiento son las principales razones para no utilizar la intercalación mixta.

Ollie
fuente
0

La transferencia de datos entre intercalaciones puede cambiar los datos si es char (texto de 8 bits) en lugar de nchar (16 bits).

Creo que desde esta página https://the.agilesql.club/blogs/Blogs/Ed-Elliott/What-collation-variables-take-on-inT-SQL que cuando una variable se asigna con texto de una tabla, es traducido implícitamente a / tratado como la recopilación de la base de datos actual. Pero, ¿qué sucede con el texto en la variable cuando te mueves a una base de datos diferente? ¿Se vuelven a traducir esos bytes (si es necesario) a la nueva clasificación?

Aprendí un truco de clasificación para eliminar los acentos de letras "latinas" y dejé solo el texto ASCII, que necesitaba porque nuestro software de terceros se estaba ahogando con los acentos: puse el texto en una clasificación que solo contiene ASCII y el alfabeto griego moderno; Collate SQL_Latin1_General_CP1253_CI_AI. "Slán" acentos en las letras romanas! ;-)

¡Pero malas noticias si hubiera querido conservarlas!

Robert Carnegie
fuente