Perché la miscelazione delle regole di confronto delle colonne in un singolo database è considerata negativa?


11

Ci sono due motivi che mi spingono a porre questa domanda:

tSQLt
Il framework di test T-SQL tSQLt lo considera un problema di "Alta gravità" quando esistono colonne con regole di confronto non predefinite. L'autore del test afferma quanto segue:

NON sto suggerendo che ogni colonna di stringa dovrebbe avere un confronto che corrisponde al confronto predefinito per il database. Invece, sto suggerendo che quando è diverso, ci dovrebbe essere una buona ragione per questo.

Tuttavia, la gravità del test fallito è, come detto, considerata elevata.

Octopus Deploy
Durante la configurazione di Octopus Deploy Server, l'installazione non riesce con un errore FATAL durante l'inizializzazione dell'istanza di OctopusServer. L' articolo relativo al messaggio di errore non spiega perché si tratta di un requisito, ma afferma semplicemente che sarà un requisito per le distribuzioni future, a partire dalla versione 3.8 di Octopus inclusa.

Come nota a margine, il pacchetto di strumenti CI di RedGate, la DLM Automation Suite , supporta implementazioni con regole di confronto variabili senza lamentele.

La raccomandazione di mantenere tutte le regole di confronto delle colonne sui valori predefiniti del database mi sembra più una linea guida o best practice. Perché è considerato un errore così grave da alcuni?


Ti riferisci alle incarnazioni tSQLt dei test di SQL Cop. Poiché i test tSQLt superano o falliscono, questi devono offrire un valore predefinito raccomandato. Ci si aspetta che gli utenti adattino i test SQLCop alle proprie esigenze poiché non sono altro che procedure memorizzate nello schema SQLCop acquisite dal framework tSQLt.
David Atkinson,

Risposte:


19

La raccomandazione di mantenere tutte le regole di confronto delle colonne sui valori predefiniti del database mi sembra più una linea guida o best practice.

Hai perfettamente ragione qui.

Perché è considerato un errore così grave da alcuni?

Per lo stesso motivo per cui sentirai / leggerai spesso che "non dovresti mai usare:"

  • cursori
  • GOTO dichiarazioni
  • SQLCLR
  • WITH (NOLOCK)
  • ecc, ecc, ecc

Alcune funzionalità / opzioni / tecnologie sono più complicate di altre e generalmente richiedono maggiori conoscenze da parte dell'utente poiché le possibilità di mettersi nei guai durante l'utilizzo sono molto maggiori delle possibilità di non avere problemi. Quindi, è più facile avere regole generalizzate contro tali cose per la popolazione in generale. In effetti, quando scrivo "Standard di codifica" al lavoro, avrò sempre una regola per non farlo maiuso i CURSORI, ma li uso anch'io perché so sia "quando" usarli e "come" usarli in modo efficace. Ma le persone che scrivono solo occasionalmente query non dovrebbero aspettarselo. Questo è anche simile a "non modificare il registro a meno che tu non sappia assolutamente cosa stai facendo" o le regole che creiamo come genitori per i nostri bambini (molto piccoli) in cui dobbiamo dire loro di non fare qualcosa semplicemente perché sono incapace di attraversare le complessità di quando è ok fare una cosa particolare o come procedere.

Nel caso di Collations, questo è un argomento molto complesso e confuso, e puoi imbatterti in entrambi gli errori (questi sono un problema ma meno di un problema poiché sono ovvi e quindi abbastanza facili da risolvere) e in "dispari" comportamento in cui è difficile spiegare perché le cose si comportano come sono (perché alcuni elementi vengono filtrati o non filtrati al di fuori delle aspettative, O perché lo smistamento si comporta al di fuori delle aspettative). E purtroppo, sembra esserci una quantità piuttosto grande di disinformazione che fluttua attorno alla quale favorisce la confusione di massa. In realtà sto lavorando a un progetto per aumentare notevolmente la conoscenza generale di Raccolte e codifiche, ecc. E, si spera, per contrastare la disinformazione e i miti, ma non sono ancora pronto a rilasciarlo (quando fatto aggiornerò questo con un link ad esso).

Per le regole di confronto, è necessario utilizzare ciò che ha più senso per il caso aziendale. L'idea di non mescolare le regole di confronto in una tabella o in un database è un approccio predefinito, ma se si esaminano le regole di confronto utilizzate per le varie colonne delle viste del catalogo di sistema, si noterà una varietà di regole di confronto utilizzate. Quindi sono d'accordo con la citazione principale nella domanda che SE le Collazioni saranno diverse, dovrebbe essere intenzionale, ma non c'è nulla di intrinsecamente sbagliato in esso.


A proposito di ciò dalla domanda (enfasi aggiunta):

Durante la configurazione di Octopus Deploy Server, l'installazione non riesce con un errore FATAL durante l'inizializzazione dell'istanza di OctopusServer. L'articolo relativo al messaggio di errore non spiega perché questo è un requisito

Ho controllato la pagina della documentazione collegata e in effetti spiega perché è un requisito. Ho copiato le informazioni pertinenti da quella documentazione di seguito:

È necessario assicurarsi di modificare anche le regole di confronto di tutti gli oggetti nel database Octopus, altrimenti potrebbero verificarsi errori durante la modifica del database durante gli aggiornamenti della versione di Octopus. I nuovi oggetti creati useranno le regole di confronto aggiornate e quando si tenta di (ad esempio) eseguire connessioni SQL tra questi e oggetti esistenti utilizzando la regole di confronto originali, potrebbero verificarsi errori di corrispondenza errata delle regole di confronto.

Stanno dicendo che il loro codice, nel database Octopus, ha JOIN tra le colonne di stringhe e potrebbe probabilmente avere un nuovo codice introdotto in un aggiornamento futuro che ha JOIN aggiuntivi su nuove colonne di stringhe. Alle nuove colonne, tramite CREATE TABLEo ALTER TABLE ... ADD, verrà assegnato il confronto predefinito del database se ilCOLLATEla parola chiave non è stata specificata per le nuove colonne di stringa. E i JOIN tra colonne di stringhe che non hanno lo stesso confronto genereranno un errore di mancata corrispondenza del confronto. Sembrano anche consentire all'utente di scegliere il proprio Collation (possibilmente per adattarsi a diverse località) poiché affermano che l'unico requisito è che il Collation non fa distinzione tra maiuscole e minuscole. E poiché la collation del database in cui risiede il loro codice non è garantita essere sempre la stessa, non possono usare la COLLATEparola chiave per forzare la stessa collation su tutte le nuove colonne di stringhe (beh, tecnicamente possono, ma ciò richiede Dynamic SQL quindi non facile da gestire durante la generazione di script di aggiornamento). Se fossero stati in grado di utilizzare la COLLATEparola chiave, avrebbero potutoevita che le regole di confronto predefinite del database siano diverse dalle colonne di stringa. Ciò eviterebbe i gravi errori di "mancata corrispondenza delle regole di confronto", ma lascerebbe comunque aperta la possibilità di operazioni di confronto che coinvolgono una di quelle colonne di stringhe e una stringa letterale o variabile con conseguente comportamento "dispari" in quanto utilizzerebbe le regole di confronto della colonna e non quelle del database Fascicolazione. Certo, potrebbe benissimo essere previsto un comportamento. Ma poiché si tratta di un'app di terze parti, il comportamento dovrebbe essere quello che intendevano piuttosto che una probabilità 50/50 tra a) ciò che l'utente voleva (o non ha obiettato) eb) ciò che l'utente considera un bug (e quindi spreca il tempo di supporto del venditore in una caccia all'oca selvatica e / o blog su come il loro software è difettoso).


ehi, qualche notizia su quel progetto su Collations?
Yaroslav,

10

In breve: COLLATION definisce l'ordinamento e il confronto .

Pertanto, le regole di confronto determinano le regole utilizzate da SQL Server per confrontare e ordinare i dati dei caratteri. Queste regole sono a conoscenza della lingua / locale e possono anche essere sensibili a maiuscolo / minuscolo, accento, Kana e larghezza. I suffissi delle regole di confronto identificano la sensibilità del dizionario (in): _CS (sensibile al maiuscolo / minuscolo), _CI (sensibile al maiuscolo / minuscolo), _AS (sensibile all'accento), _AI (sensibile al tocco) e _KS (sensibile al Kana). Le regole di confronto binarie, identificate dai suffissi _BIN (binario) e _BIN2 (punto di codice binario), sono sensibili sotto tutti gli aspetti.

Diverse regole di confronto richiederanno sicuramente soluzioni alternative per evitare errori "impossibile risolvere il conflitto di regole di confronto" e possono uccidere le prestazioni a causa delle espressioni note non identificabili . Trattare con diverse collation può essere un incubo (ci sono stato) quindi è per questo che la raccomandazione di sceglierne uno e attenersi ad esso.

Più riferimenti:


1

Come per molte cose, nelle versioni precedenti di SQL potrebbe causare problemi abbastanza significativi. Vedi questo articolo da SQL7 / 2000

SqlServerCentral Collation

È molto più robusto ora, e ci sono situazioni in cui è giustificato in sistemi più moderni, ma ci sono ancora alcuni avvertimenti abbastanza interessanti nel cambiarlo.

Ecco un'altra utile serie su versioni più moderne. Di Dan Guzman, che credo pubblichi regolarmente dei post qui, quindi potrebbe fare presto il tubo :)

Inferno di confronto SQL

In breve, compatibilità, standardizzazione e potenziali successi nelle prestazioni sono i motivi principali per non utilizzare le regole di confronto miste.


0

Il trasferimento di dati tra regole di confronto può modificare i dati se è char (testo a 8 bit) anziché nchar (16 bit).

Credo da questa pagina https://the.agilesql.club/blogs/Blogs/Ed-Elliott/What-collation-variables-take-on-inT-SQL che quando una variabile viene assegnata con il testo da una tabella, è implicitamente tradotto / trattato come confronto del database corrente. Ma cosa succede al testo nella variabile quando si passa a un database diverso? Questi byte vengono nuovamente tradotti (se necessario) nella nuova raccolta?

Ho raccolto un trucco per rimuovere gli accenti di lettere "latine" e lasciare solo il testo ASCII, di cui avevo bisogno perché il nostro software di terze parti stava soffocando sugli accenti - ho inserito il testo in una raccolta che contiene solo ASCII e il moderno alfabeto greco; Collate SQL_Latin1_General_CP1253_CI_AI. "Slán" agli accenti sulle lettere romane! ;-)

Ma cattive notizie se avessi voluto tenerle!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.