Domanda

Mentre opzioni di ricerca per l'archiviazione di dati per lo più inglesi ma a volte non in un database SQL Server che può potenzialmente essere piuttosto grande, sono propenso a archiviare la maggior parte dei dati di stringa con codifica UTF-8.

Tuttavia, Microsoft ha scelto UCS-2 per ragioni che non comprendo appieno e che mi fanno dubitare di questa inclinazione.La documentazione per SQL Server 2012 mostra come creare un file UTF-8UDT, ma la decisione per UCS-2 presumibilmente pervade SQL Server.

Wikipedia (che rileva in modo interessante che UCS-2 è obsoleto a favore di UTF-16) nota che UTF-8 è un set di caratteri a larghezza variabile in grado di codificare qualsiasi punto dati Unicode e che provides the de facto standard encoding for interchange of Unicode text.Quindi, sembra che qualsiasi carattere Unicode possa essere rappresentato in UTF-8 e poiché la maggior parte del testo sarà in inglese, la rappresentazione sarà quasi due volte più compatta rispetto a UCS-2 (so che il disco è "economico", ma la cache del disco non lo è no, e la memoria non è paragonabile alle dimensioni dei dati con cui ho a che fare.Molte operazioni peggiorano in modo esponenziale quando il working set è più grande della RAM disponibile).

Quali problemi potrei incontrare risalendo il flusso dell'UCS-2?

È stato utile?

Soluzione

memorizzando dati per lo più in inglese ma a volte non in un database SQL Server che può potenzialmente essere piuttosto grande, sono propenso a memorizzare la maggior parte dei dati di stringa come codificati UTF-8.

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

Microsoft ha scelto UCS-2 per ragioni che non comprendo appieno

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#Usage).La loro decisione di Continua 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.

La documentazione per SQL Server 2012 mostra come creare un UDT UTF-8,

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 utilizzare Qualunque funzioni di stringa integrate.Se potessi risparmiare qualcosa sullo spazio su disco, quei guadagni verrebbero cancellati da ciò che perderesti in termini di prestazioni complessive.La memorizzazione di un UDT viene eseguita serializzandolo in un file VARBINARY.Quindi, per fare Qualunque 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 poi eseguire il confronto di stringhe che possa tenere conto delle differenze linguistiche.

Inoltre, quella "documentazione" è in realtà solo codice di esempio / prova di 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 nulla che riguardasse le prestazioni.

ma la decisione per UCS-2 presumibilmente pervade SQL Server.

Sì, moltissimo.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 (beh, a partire da Unicode versione 5 o 6, a seconda del sistema operativo e della versione di .NET Framework) utilizzando una delle regole di confronto che ha un nome che termina con _SC (cioè.Caratteri supplementari).

Wikipedia...rileva che UCS-2 è obsoleto a favore di UTF-16

Corretto.UTF-16 e UCS-2 utilizzano entrambi punti di codice a 2 byte.Ma UTF-16 ne utilizza alcuni in coppia (ad 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 è possibile archiviare qualsiasi carattere Unicode in SQL Server e verrà archiviato e recuperato correttamente.

Wikipedia...rileva che UTF-8 è un set di caratteri a larghezza variabile in grado di codificare qualsiasi punto dati Unicode

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.Sebbene UCS-2 possa trattenerli ma non interpretarli, sia UTF-16 che UTF-32 possono entrambi mappare tutti i punti di codice Unicode, proprio come UTF-8.

e che [ndr:UTF-8] fornisce la codifica standard de facto per lo scambio di testo Unicode.

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

sembra che qualsiasi carattere Unicode possa essere rappresentato in UTF-8

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

poiché la maggior parte del testo sarà in inglese, la rappresentazione sarà quasi due volte più compatta rispetto a UCS-2

A seconda delle circostanze, ciò potrebbe benissimo essere vero e hai ragione a essere preoccupato per un utilizzo così dispendioso.Tuttavia, come ho accennato nella domanda che ha portato a questa ( Supporto UTF-8, SQL Server 2012 e UDT UTF8String ), hai alcune opzioni per ridurre la quantità di spazio sprecato se è possibile inserire la maggior parte delle righe VARCHAR eppure alcuni devono esserlo NVARCHAR.L'opzione migliore è abilitare la COMPRESSIONE RIGA o la COMPRESSIONE PAGINA (solo Enterprise Edition!).A partire da SQL Server 2008 R2, consentono non-MAX NVARCHAR campi per utilizzare lo "schema di compressione standard per Unicode" che è almeno altrettanto valido di UTF-8 e in alcuni casi è addirittura migliore di UTF-8. NVARCHAR(MAX) i campi non possono utilizzare questa compressione fantasiosa, ma i dati IN ROW possono trarre vantaggio dalla normale compressione ROW e/o PAGE.Consulta 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 grezzi con compressione dei dati abilitata.

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

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

So che il disco è "economico"

La veridicità di tale affermazione dipende da come si definisce "disco".Se parli in termini di parti di base che puoi acquistare dallo scaffale in un negozio per utilizzarle sul tuo desktop / laptop, allora certo.Ma, se parli in termini di storage di 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 oltre un milione di dollari che desideri perché è "economica" " ;-).

Quali problemi potrei incontrare risalendo il flusso dell'UCS-2?

Nessuno che mi venga in mente.Bene, finché non segui 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 tra 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 di 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.Attualmente ci sono troppi bug per poterlo utilizzare, ma se vengono risolti, questa è un'opzione 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à.

Altri suggerimenti

Cosa intendi per "Nuotare il flusso UCS-2"?

Ecco le tue opzioni:

    .
  • Utilizzare le nuove libellula _SC 2012 ( https://msdn.microsoft.com/en-us/library/ms143726.as143726.aspx ).Questa idea viene da Sruutzky.Dovresti controllare la sua risposta.Questo è di gran lunga la soluzione migliore.

    Non consigliato ma possibile:

      .
    • Implementa un UDT.Questo sarà molto lavoro e si perde il supporto del supporto (o la mappatura e sicuramente alcune funzionalità di SQL Server che funzionano su tipi nativi).
    • Utilizzare varbinary (max): richiede di effettuare il codice di conversione personalizzato.Nessuna indicizzazione dell'indice.
    • Utilizzare Nvarchar (N) e accendere la compressione della riga.A partire da SQL Server 2008 R2 Questo utilizzerà una codifica che è compatta come UTF-8.Ma questo richiede Enterprise Edition.

      Guarda i commenti per leggere i gravi inconvenienti che questi approcci hanno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top