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

UCS-2 e SQL Server

A differenza di altri RDBMS che consentono di scegliere una codifica, SQL Server archivia i dati Unicode solo in UTF-16 (Little Endian) e dati non Unicode in una codifica a 8 bit (Extended ASCII, DBCS o EBCDIC) per qualsiasi tabella codici sia implicita nelle regole di confronto del campo.

La loro decisione di scegliere UCS-2 ha abbastanza senso dato che UTF-16 è stato introdotto a metà del 1996 e completamente specificato nel 2000. Anche molti altri sistemi lo usano (o lo usano) (vedi:https://en.wikipedia.org/wiki/UTF-16#Utilizzo ). La loro decisione di continuare con esso potrebbe essere più discutibile, anche se probabilmente è dovuto al fatto che Windows e .NET sono UTF-16. Il layout fisico dei byte è lo stesso tra UCS-2 e UTF-16, quindi l'aggiornamento dei sistemi da UCS-2 per supportare UTF-16 dovrebbe essere puramente funzionale senza la necessità di modificare i dati esistenti.

Ehm, no. La creazione di un tipo personalizzato definito dall'utente tramite SQLCLR non , in ogni caso, ti procurerà un sostituto di qualsiasi tipo nativo. È molto utile per creare qualcosa per gestire dati specializzati. Ma le stringhe, anche con una codifica diversa, sono tutt'altro che specializzate. Seguire questa strada per i tuoi dati di stringa distruggerebbe qualsiasi quantità di usabilità del tuo sistema, per non parlare delle prestazioni poiché non saresti in grado di usarne nessuna funzioni di stringa integrate. Se fossi in grado di salvare qualcosa sullo spazio su disco, quei guadagni verrebbero cancellati da ciò che perderesti in termini di prestazioni complessive. La memorizzazione di un UDT avviene serializzandolo in un VARBINARY . Quindi per fare qualsiasi confronto di stringhe O ordinamento, al di fuori di un confronto "binario" / "ordinale", dovresti convertire tutti gli altri valori, uno per uno, in UTF-8 per quindi eseguire il confronto di stringhe che può tenere conto delle differenze linguistiche.

Inoltre, quella "documentazione" è in realtà solo codice di esempio/prova del concetto. Il codice è stato scritto nel 2003 ( http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/CS/UTF8String/Utf8String.cs ) per SQL Server 2005. Ho visto uno script per testare la funzionalità, ma niente che riguardasse le prestazioni.

Sì, molto. Per impostazione predefinita, la gestione delle funzioni integrate è solo per UCS-2. Ma a partire da SQL Server 2012, puoi far sì che gestiscano l'intero set di caratteri UTF-16 (a partire da Unicode versione 5 o 6, a seconda del tuo sistema operativo e della versione di .NET Framework) usando una delle regole di confronto che ha un nome che termina con _SC (cioè caratteri supplementari).

Corretta. UTF-16 e UCS-2 utilizzano entrambi punti di codice a 2 byte. Ma UTF-16 ne usa alcuni in coppia (es. Coppie surrogate) per mappare caratteri aggiuntivi. I punti di codice utilizzati per queste coppie sono riservati a questo scopo in UCS-2 e quindi non vengono utilizzati per mappare alcun simbolo utilizzabile. Questo è il motivo per cui puoi archiviare qualsiasi carattere Unicode in SQL Server e verrà archiviato e recuperato correttamente.

Corretto, anche se fuorviante. Sì, UTF-8 è a larghezza variabile, ma anche UTF-16 è leggermente variabile poiché tutti i caratteri supplementari sono composti da due punti di codice a doppio byte. Quindi UTF-16 utilizza 2 o 4 byte per simbolo, sebbene UCS-2 sia sempre 2 byte. Ma non è questa la parte fuorviante. Ciò che è fuorviante è l'implicazione che qualsiasi altra codifica Unicode non sia in grado di codificare tutti gli altri punti di codice. Mentre UCS-2 può tenerli ma non interpretarli, sia UTF-16 che UTF-32 possono entrambi mappare tutti i punti di codice Unicode, proprio come UTF-8.

Questo può essere vero, ma è del tutto irrilevante dal punto di vista operativo.

Ancora una volta, vero, ma del tutto irrilevante poiché anche UTF-16 e UTF-32 mappano tutti i punti di codice Unicode.

A seconda delle circostanze, questo potrebbe benissimo essere vero e hai ragione a preoccuparti di un uso così dispendioso. Tuttavia, come ho accennato nella domanda che porta a questa ( Supporto UTF-8, SQL Server 2012 e UDT UTF8String ), hai alcune opzioni per ridurre la quantità di spazio sprecato se la maggior parte delle righe può rientrare in VARCHAR tuttavia alcuni devono essere NVARCHAR . L'opzione migliore è abilitare ROW COMPRESSION o PAGE COMPRESSION (solo Enterprise Edition!). A partire da SQL Server 2008 R2, consentono NVARCHAR non MAX campi per utilizzare lo "Schema di compressione standard per Unicode" che è buono almeno quanto UTF-8 e in alcuni casi è persino migliore di UTF-8. NVARCHAR(MAX) i campi non possono utilizzare questa compressione di fantasia , ma i loro dati IN ROW possono trarre vantaggio dalla normale compressione ROW e/o PAGE. Vedere quanto segue per una descrizione di questa compressione e un grafico che confronta le dimensioni dei dati per:UCS-2 / UTF-16, UTF-8 e UCS-2 / UTF-16 non elaborati con la compressione dei dati abilitata.

SQL Server 2008 R2 - Compressione UCS2 che cos'è - Impatto sui sistemi SAP

Consulta anche la pagina MSDN per Compressione dati per maggiori dettagli in quanto ci sono alcune restrizioni (oltre che disponibile solo in Enterprise Edition, MA reso disponibile a tutti edizioni a partire da SQL Server 2016, SP1 !!) e alcune circostanze in cui la compressione potrebbe peggiorare le cose.

La veridicità di tale affermazione dipende da come si definisce "disco". Se stai parlando in termini di parti di base che puoi acquistare in un negozio per l'uso nel tuo desktop / laptop, allora certo. Ma, se parli in termini di storage a livello aziendale che verrà utilizzato per i tuoi sistemi di produzione, divertiti a spiegare a chi controlla il budget che non dovrebbe rifiutare la SAN da un milione e più di dollari che desideri perché è "economica ";-).

Nessuno a cui riesco a pensare. Bene, purché tu non segua alcun consiglio orribile per fare qualcosa come implementare quell'UDT o convertire tutte le stringhe in VARBINARY o utilizzando NVARCHAR(MAX) per tutti i campi stringa;-). Ma di tutte le cose di cui potresti preoccuparti, SQL Server che utilizza UCS-2 / UTF-16 non dovrebbe essere una di queste.

Ma, se per qualche motivo questo problema dell'assenza di supporto nativo per UTF-8 è estremamente importante, potrebbe essere necessario trovare un altro RDBMS da utilizzare che consenta UTF-8.

AGGIORNAMENTO 2018-10-02

Sebbene questa non sia ancora un'opzione praticabile, SQL Server 2019 introduce il supporto nativo per UTF-8 in VARCHAR / CHAR tipi di dati. Al momento ci sono troppi bug con esso per poter essere utilizzato, ma se vengono risolti, questa è un'opzione per alcuni scenari. Si prega di consultare il mio post, "Supporto UTF-8 nativo in SQL Server 2019:Salvatore o Falso profeta? ", per un'analisi dettagliata di questa nuova funzionalità.