Pourquoi le mélange de classements de colonnes dans une seule base de données est-il considéré comme mauvais?


11

Il y a deux raisons qui m'incitent à poser cette question:

tSQLt
Le framework de test T-SQL tSQLt considère qu'il s'agit d'un problème de «haute gravité» lorsqu'il existe des colonnes avec un classement non par défaut. L'auteur du test déclare ce qui suit:

Je ne suggère PAS que chaque colonne de chaîne devrait avoir un classement qui correspond au classement par défaut de la base de données. Au lieu de cela, je suggère que lorsqu'il est différent, il devrait y avoir une bonne raison à cela.

Pourtant, la gravité de l'échec du test est, comme mentionné, considérée comme élevée.

Octopus Deploy
Lors de la configuration du serveur Octopus Deploy, la configuration échoue avec une erreur FATAL lors de l'initialisation de l'instance OctopusServer. L' article relatif au message d'erreur n'explique pas pourquoi il s'agit d'une exigence, mais indique simplement que ce sera une exigence pour les déploiements futurs, à partir d'Octopus version 3.8.

En parallèle, le package d'outils CI de RedGate, la suite DLM Automation , prend en charge les déploiements avec différents classements sans se plaindre.

La recommandation de conserver tous les classements de colonnes à la valeur par défaut de la base de données me semble davantage être des lignes directrices ou des meilleures pratiques. Pourquoi est-il considéré comme une erreur aussi grave par certains?


Vous faites référence aux incarnations tSQLt des tests SQL Cop. Comme les tests tSQLt réussissent ou échouent, ceux-ci doivent proposer une valeur par défaut recommandée. Les utilisateurs sont censés adapter les tests SQLCop à leurs propres besoins car ils ne sont rien de plus que des procédures stockées dans le schéma SQLCop repris par le cadre tSQLt.
David Atkinson

Réponses:


19

La recommandation de conserver tous les classements de colonnes à la valeur par défaut de la base de données me semble davantage être des lignes directrices ou des meilleures pratiques.

Vous avez tout à fait raison ici.

Pourquoi est-il considéré comme une erreur aussi grave par certains?

Pour la même raison que vous entendrez / lirez souvent que "vous ne devriez jamais utiliser:"

  • CURSEURS
  • GOTO déclarations
  • SQLCLR
  • WITH (NOLOCK)
  • etc, etc, etc

Certaines fonctionnalités / options / technologies sont plus compliquées que d'autres et nécessitent généralement plus de connaissances de la part de l'utilisateur car les chances de rencontrer des problèmes lors de son utilisation sont bien plus importantes que les chances de ne rencontrer aucun problème. Ainsi, il est plus facile d'avoir des règles généralisées contre de telles choses pour la population générale. En fait, lors de la rédaction de "Normes de codage" au travail, j'aurai toujours une règle pour ne jamaisutiliser des curseurs, mais je les utilise moi-même parce que je sais à la fois "quand" les utiliser et "comment" les utiliser efficacement. Mais les gens qui n'écrivent qu'occasionnellement des requêtes ne devraient pas savoir cela. Ceci est également similaire à "ne modifiez pas le Registre à moins que vous ne sachiez absolument ce que vous faites", ou des règles que nous établissons en tant que parents pour nos (très jeunes) enfants où nous devons leur dire de ne pas faire quelque chose simplement parce qu'ils sont pas capable de traverser les complexités de quand il est correct de faire une chose particulière ou comment s'y prendre.

Dans le cas des classements, il s'agit d'un sujet très complexe et déroutant, et vous pouvez rencontrer à la fois des erreurs matérielles (il s'agit d'un problème mais moins d'un problème car elles sont évidentes et donc assez faciles à résoudre) et "bizarres". comportement où il est difficile d'expliquer pourquoi les choses agissent comme elles le sont (pourquoi certains éléments sont filtrés, ou non filtrés, en dehors des attentes, OU pourquoi le tri agit en dehors des attentes). Et malheureusement, il semble y avoir une assez grande quantité de désinformation flottant autour de ce qui favorise la confusion de masse. Je travaille actuellement sur un projet visant à augmenter considérablement les connaissances générales sur les classements et les encodages, etc. et, espérons-le, à contrer la désinformation et les mythes, mais je ne suis pas encore prêt à le publier (une fois terminé, je le mettrai à jour avec un lien vers celui-ci).

Pour le classement, vous devez utiliser ce qui a le plus de sens pour l'analyse de rentabilisation. La notion de ne pas mélanger les classements dans une table ou une base de données est une approche par défaut, mais si vous regardez les classements utilisés pour les différentes colonnes des vues du catalogue système, vous remarquerez une variété de classements utilisés. Je suis donc d'accord avec la citation principale dans la question selon laquelle SI les classements vont être différents, cela devrait être intentionnel, mais il n'y a rien de mal en soi.


En ce qui concerne la question (non souligné dans l'original):

Lors de la configuration d'Octopus Deploy Server, l'installation échoue avec une erreur FATAL lors de l'initialisation de l'instance OctopusServer. L'article relatif au message d'erreur n'explique pas pourquoi il s'agit d'une exigence

J'ai vérifié la page de documentation liée et cela explique en effet pourquoi c'est une exigence. J'ai copié les informations pertinentes de cette documentation ci-dessous:

Vous devez vous assurer que vous modifiez également le classement de tous les objets dans la base de données Octopus, sinon des erreurs peuvent se produire lors de la modification de la base de données lors des mises à niveau de la version Octopus. Les nouveaux objets créés utiliseront le classement mis à jour et lorsque vous tenterez (par exemple) d'effectuer des jointures SQL entre ces objets et des objets existants à l'aide du classement d'origine, des erreurs de correspondance incorrecte du classement peuvent se produire.

Ils disent que leur code, dans la base de données Octopus, a des JOIN entre les colonnes de chaînes et pourrait probablement avoir un nouveau code introduit dans une future mise à niveau qui aura des JOIN supplémentaires sur les nouvelles colonnes de chaînes. Les nouvelles colonnes, via CREATE TABLEou ALTER TABLE ... ADD, se verront attribuer le classement par défaut de la base de données si leCOLLATELe mot clé n'a pas été spécifié pour les nouvelles colonnes de chaîne. Et les jointures entre des colonnes de chaînes qui n'ont pas le même classement généreront une erreur d'incompatibilité de classement. Ils semblent également permettre à l'utilisateur de choisir son propre classement (éventuellement pour s'adapter à différents paramètres régionaux), car ils disent tout en haut que la seule exigence est que le classement ne respecte pas la casse. Et comme le classement de la base de données dans lequel se trouve leur code n'est pas garanti d'être toujours le même, ils ne peuvent pas utiliser le COLLATEmot - clé pour forcer le même classement sur toutes les nouvelles colonnes de chaînes (enfin, techniquement, ils le peuvent, mais cela nécessite Dynamic SQL donc pas facile à gérer lors de la génération de scripts de mise à jour). S'ils pouvaient utiliser le COLLATEmot - clé, ils pourraientévitez d'avoir le classement par défaut de la base de données différent des colonnes de chaînes. Cela éviterait les erreurs dures de "non-concordance", mais laisserait toujours ouverte la possibilité d'opérations de comparaison impliquant l'une de ces colonnes de chaîne et un littéral ou une variable de chaîne résultant en un comportement "étrange" car il utiliserait le classement de la colonne et non celui de la base de données. Collation. Bien sûr, cela pourrait très bien être un comportement attendu. Mais comme il s'agit d'une application tierce, le comportement devrait être ce qu'ils voulaient plutôt qu'une chance de 50/50 entre a) ce que l'utilisateur voulait (ou ne s'y était pas opposé) et b) ce que l'utilisateur considérait comme un bogue (et ensuite gaspille le temps de support du vendeur sur une chasse aux oies sauvages et / ou des blogs sur la façon dont leur logiciel est buggé).


hé, des nouvelles de ce projet sur Collations?
Yaroslav

10

Sur une courte phrase: COLLATION définit le tri et la comparaison .

Ainsi, le classement détermine les règles que SQL Server utilise pour comparer et trier les données de caractères. Ces règles sont sensibles à la langue / aux paramètres régionaux et peuvent également être sensibles à la casse, à l'accent, au kana et à la largeur. Les suffixes de classement identifient la sensibilité (in) des règles de dictionnaire: _CS (sensible à la casse), _CI (sensible à la casse), _AS (sensible à l'accent), _AI (sensible à l'accent) et _KS (sensible à Kana). Les classements binaires, identifiés par les suffixes _BIN (binaire) et _BIN2 (point de code binaire), sont sensibles à tous égards.

Différents classements nécessiteront certainement des solutions de contournement pour éviter les erreurs «ne peuvent pas résoudre les conflits de classement» et peuvent nuire aux performances en raison des expressions non discutables connues . Faire face à différentes collations peut être un cauchemar (ils ont été là), c'est pourquoi la recommandation d'en choisir une et de s'y tenir.

Plus de références:


1

Comme pour beaucoup de choses, dans les versions précédentes de SQL, cela pouvait causer des problèmes assez importants. Voir cet article de SQL7 / 2000

Collation SqlServerCentral

C'est beaucoup plus robuste maintenant, et il y a des situations où cela se justifie dans des systèmes plus modernes, mais il y a encore quelques mises en garde assez intéressantes pour le changer.

Voici une autre série utile sur des versions plus modernes. Par Dan Guzman, qui, je crois, publie régulièrement ici afin qu'il soit bientôt disponible :)

Enfer du classement SQL

En bref, la compatibilité, la standardisation et les performances potentielles sont les principales raisons de ne pas utiliser le classement mixte.


0

Le transfert de données entre des classements peut modifier les données s'il s'agit de char (texte 8 bits) au lieu de nchar (16 bits).

Je crois à partir de cette page https://the.agilesql.club/blogs/Blogs/Ed-Elliott/What-collation-variables-take-on-inT-SQL que lorsqu'une variable est affectée avec du texte d'une table, c'est implicitement traduit / traité comme le classement de la base de données actuelle. Mais qu'arrive-t-il au texte de la variable lorsque vous passez à une autre base de données? Ces octets sont-ils à nouveau traduits (si nécessaire) vers le nouveau classement?

J'ai choisi une astuce de collation pour supprimer les accents de lettre "latine" et ne laisser que du texte ASCII, dont j'avais besoin parce que notre logiciel tiers s'étouffait avec les accents - j'ai mis du texte dans une collation qui ne contient que ASCII et l'alphabet grec moderne; Collate SQL_Latin1_General_CP1253_CI_AI. "Slán" aux accents sur les lettres romaines! ;-)

Mais mauvaise nouvelle si j'avais voulu les garder!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.