Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Algoritmo di ordinamento GUID di SQL Server. Come mai?

L'algoritmo è documentato dai ragazzi di SQL Server qui:Come vengono confrontati i GUID in SQL Server 2005? Cito qui qui (poiché è un vecchio articolo che potrebbe scomparire per sempre in pochi anni)

In generale, i confronti di uguaglianza hanno molto senso con valori identificativi univoci. Tuttavia, se ti accorgi di aver bisogno di un ordinamento generale, potresti considerare il tipo di dati sbagliato e dovresti invece considerare vari tipi interi.

Se, dopo un'attenta riflessione, decidi di ordinare su una colonna uniqueidentifier, potresti rimanere sorpreso da ciò che ottieni.

Dati questi due valori di identificazione univoca:

@g1='55666BEE-B3A0-4BF5-81A7-86FF976E763F' @g2 ='8DD5BCA5-6ABE-4F73-B4B7-393AE6BBB849'

Molte persone pensano che @g1 sia inferiore a @g2, poiché "55666BEE" è sicuramente più piccolo di "8DD5BCA5". Tuttavia, questo non è il modo in cui SQL Server2005 confronta i valori dell'identificatore univoco.

Il confronto viene effettuato esaminando i "gruppi" di byte da destra a sinistra e da sinistra a destra all'interno di un "gruppo" di byte. Un gruppo di byte è ciò che è delimitato dal carattere '-'. Più tecnicamente, esaminiamo i byte da {10 a 15}prima, poi {8-9}, poi {6-7}, poi {4-5} e infine da {0 a 3}.

In questo esempio specifico, inizieremo confrontando "86FF976E763F" con "393AE6BBB849". Immediatamente vediamo che @g2 è effettivamente maggiore di @g1.

Si noti che nei linguaggi .NET, i valori Guid hanno un ordinamento predefinito diverso rispetto a SQL Server. Se trovi la necessità di ordinare una matrice o un elenco di Guid utilizzando la semantica di confronto di SQL Server, puoi invece utilizzare anarray o un elenco di SqlGuid, che implementa IComparable in modo coerente con la semantica di SQL Server.

Inoltre, l'ordinamento segue l'endianness dei gruppi di byte (vedi qui:identificatore univoco globale). I gruppi 10-15 e 8-9 sono memorizzati come big endian (corrispondente a Data4 nell'articolo di Wikipedia), quindi vengono confrontati come big endian. Altri gruppi vengono confrontati utilizzando little endian.