Frage

Während optionen recherchieren um hauptsächlich englische, aber manchmal nicht englische Daten in einer SQL Server-Datenbank zu speichern, die möglicherweise ziemlich groß sein kann, neige ich dazu, die meisten Zeichenfolgendaten als UTF-8-codiert zu speichern.

Microsoft hat sich jedoch aus Gründen, die ich nicht ganz verstehe, für UCS-2 entschieden, was mich veranlasst, diese Neigung zu überdenken.Die Dokumentation für SQL Server 2012 zeigt, wie Sie eine erstellen UTF-8 UDT, aber die Entscheidung für UCS-2 durchdringt vermutlich SQL Server.

Deutschsprachige Wikipedia (was interessanterweise feststellt, dass UCS-2 zugunsten von UTF-16 veraltet ist) stellt fest, dass UTF-8 ein Zeichensatz mit variabler Breite ist, der jeden Unicode-Datenpunkt codieren kann und dass er provides the de facto standard encoding for interchange of Unicode text.Es fühlt sich also so an, als ob jedes Unicode-Zeichen in UTF-8 dargestellt werden kann, und da der meiste Text Englisch ist, ist die Darstellung fast doppelt so kompakt wie bei UCS-2 (ich weiß, dass die Festplatte "billig" ist, aber der Festplatten-Cache nicht) und Speicher ist nicht im Vergleich zu den Datengrößen, mit denen ich es zu tun habe.Viele Operationen verschlechtern sich exponentiell, wenn der Arbeitssatz größer als der verfügbare RAM ist).

Auf welche Probleme könnte ich stoßen, wenn ich den UCS-2-Stream hochschwimme?

War es hilfreich?

Lösung

wenn ich hauptsächlich englische, aber manchmal nicht englische Daten in einer SQL Server-Datenbank speichere, die möglicherweise ziemlich groß sein kann, neige ich dazu, die meisten Zeichenfolgendaten als UTF-8-codiert zu speichern.

Im Gegensatz zu einigen anderen RDBMS, die die Auswahl einer Codierung ermöglichen, speichert SQL Server Unicode-Daten nur in UTF-16 (Little Endian) und Nicht-Unicode-Daten in einer 8-Bit-Codierung (erweitertes ASCII, DBCS oder EBCDIC) für jede Codepage, die durch die Sortierung des Felds impliziert wird.

Microsoft hat sich aus Gründen, die ich nicht ganz verstehe, für UCS-2 entschieden

Ihre Entscheidung zu wählen UCS-2 ist sinnvoll genug, da UTF-16 Mitte 1996 eingeführt und im Jahr 2000 vollständig spezifiziert wurde.Viele andere Systeme verwenden (oder verwenden) es auch (siehe: https://en.wikipedia.org/wiki/UTF-16#Usage).Ihre Entscheidung zu weiterhin damit könnte es fragwürdiger sein, obwohl es wahrscheinlich daran liegt, dass Windows und .NET UTF-16 sind.Das physikalische Layout der Bytes ist zwischen UCS-2 und UTF-16 gleich, daher sollte das Upgrade von Systemen von UCS-2 auf UTF-16 rein funktional sein, ohne dass vorhandene Daten geändert werden müssen.

Die Dokumentation zu SQL Server 2012 zeigt, wie ein UTF-8-UDT erstellt wird,

Ähm, nein.Das Erstellen eines benutzerdefinierten benutzerdefinierten Typs über SQLCLR ist nicht, in irgendeiner Weise erhalten Sie einen Ersatz für jeden nativen Typ.Es ist sehr praktisch, um etwas für den Umgang mit speziellen Daten zu erstellen.Aber Zeichenfolgen, auch mit einer anderen Codierung, sind alles andere als spezialisiert.Wenn Sie diesen Weg für Ihre Zeichenfolgendaten einschlagen, würde dies die Benutzerfreundlichkeit Ihres Systems beeinträchtigen, ganz zu schweigen von der Leistung, die Sie nicht verwenden könnten jeder eingebaute String-Funktionen.Wenn Sie etwas an Speicherplatz sparen könnten, würden diese Gewinne durch das, was Sie an Gesamtleistung verlieren würden, gelöscht.Das Speichern einer UDT erfolgt durch Serialisierung in eine VARBINARY.Also, um zu tun jeder Zeichenfolgenvergleich ODER -sortierung, außerhalb eines "binären" / "ordinalen" Vergleichs, müssten Sie alle anderen Werte nacheinander zurück in UTF-8 konvertieren, um dann den Zeichenfolgenvergleich durchzuführen, der sprachliche Unterschiede berücksichtigen kann.

Auch diese "Dokumentation" ist wirklich nur Beispielcode / Proof-of-Concept-Zeug.Der Kodex wurde 2003 geschrieben ( http://msftengprodsamples.codeplex.com/SourceControl/latest#Kilimanjaro_Trunk/Programmability/CLR/UTF8String/CS/UTF8String/Utf8String.cs ) für SQL Server 2005.Ich habe ein Skript zum Testen der Funktionalität gesehen, aber nichts mit Leistung.

aber die Entscheidung für UCS-2 zieht sich vermutlich durch SQL Server.

Ja, sehr gerne.Standardmäßig erfolgt die Behandlung der eingebauten Funktionen nur für UCS-2.Ab SQL Server 2012 können Sie sie jedoch dazu bringen, den vollständigen UTF-16-Zeichensatz zu verarbeiten (ab Unicode Version 5 oder 6, abhängig von Ihrem Betriebssystem und der Version von .NET Framework), indem Sie eine der Kollatierungen mit einem Namen verwenden endet in _SC (also.Zusatzzeichen).

In: Wikipedia ...stellt fest, dass UCS-2 zugunsten von UTF-16 veraltet ist

Richtig.UTF-16 und UCS-2 verwenden beide 2-Byte-Codepunkte.Aber UTF-16 verwendet einige von ihnen paarweise (d. h.Ersatzpaare), um zusätzliche Zeichen zuzuordnen.Die für diese Paare verwendeten Codepunkte sind für diesen Zweck in UCS-2 reserviert und werden daher nicht zum Abbilden auf verwendbare Symbole verwendet.Aus diesem Grund können Sie jedes Unicode-Zeichen in SQL Server speichern und es wird korrekt gespeichert und abgerufen.

In: Wikipedia ...stellt fest, dass UTF-8 ein Zeichensatz mit variabler Breite ist, der jeden Unicode-Datenpunkt codieren kann

Richtig, wenn auch irreführend.Ja, UTF-8 hat eine variable Breite, aber UTF-16 ist auch geringfügig variabel, da alle Zusatzzeichen aus zwei Doppelbyte-Codepunkten bestehen.Daher verwendet UTF-16 entweder 2 oder 4 Bytes pro Symbol, obwohl UCS-2 immer 2 Bytes ist.Aber das ist nicht der irreführende Teil.Irreführend ist die Implikation, dass jede andere Unicode-Codierung nicht in der Lage ist, alle anderen Codepunkte zu codieren.Während UCS-2 sie speichern, aber nicht interpretieren kann, können sowohl UTF-16 als auch UTF-32 alle Unicode-Codepunkte abbilden, genau wie UTF-8.

und dass es [ed:UTF-8] bietet die De-facto-Standardcodierung für den Austausch von Unicode-Text.

Das mag stimmen, ist aber aus operativer Sicht völlig irrelevant.

es fühlt sich so an, als ob jedes Unicode-Zeichen in UTF-8 dargestellt werden kann

Wieder wahr, aber völlig irrelevant, da UTF-16 und UTF-32 auch alle Unicode-Codepunkte abbilden.

da der meiste Text englisch sein wird, wird die Darstellung fast doppelt so kompakt sein wie bei UCS-2

Abhängig von den Umständen könnte dies sehr wohl zutreffen, und Sie haben Recht, sich über eine solche verschwenderische Nutzung Sorgen zu machen.Wie ich jedoch in der Frage erwähnt habe, die zu dieser Frage geführt hat ( UTF-8-Unterstützung, SQL Server 2012 und die UTF8-Zeichenfolge UDT ), haben Sie einige Optionen, um den verschwendeten Speicherplatz zu verringern, wenn die meisten Zeilen hineinpassen VARCHAR doch einige müssen sein NVARCHAR.Die beste Option ist, die ZEILEN- oder SEITENKOMPRIMIERUNG zu aktivieren (nur Enterprise Edition!).Ab SQL Server 2008 R2 erlauben sie Nicht-MAX NVARCHAR felder, um das "Standardkomprimierungsschema für Unicode" zu verwenden, das mindestens so gut wie UTF-8 und in einigen Fällen sogar besser als UTF-8 ist. NVARCHAR(MAX) felder können diese ausgefallene Komprimierung nicht verwenden, aber ihre ZEILENINTERNEN Daten können von einer regelmäßigen ZEILEN- und/ oder Seitenkomprimierung profitieren.Im Folgenden finden Sie eine Beschreibung dieser Komprimierung und ein Diagramm zum Vergleich der Datengrößen für:rohes UCS-2 / UTF-16, UTF-8 und UCS-2 / UTF-16 mit aktivierter Datenkomprimierung.

SQL Server 2008 R2 - UCS2-Komprimierung Was ist das - Auswirkungen auf SAP-Systeme

Bitte beachten Sie auch die MSDN-Seite für Datenkompression für weitere Details, da es einige Einschränkungen gibt (darüber hinaus ist es nur in der Enterprise Edition verfügbar - aber verfügbar für aller editionen ab SQL Server 2016, SP1 !!) und einige Umstände, unter denen die Komprimierung die Situation verschlimmern könnte.

Ich weiß, dass Diskette "billig" ist

Die Richtigkeit dieser Aussage hängt davon ab, wie man "disk" definiert.Wenn Sie in Bezug auf Warenteile sprechen, die Sie in einem Geschäft von der Stange kaufen können, um sie in Ihrem Desktop / Laptop zu verwenden, dann sicher.Aber wenn Sie von Speicher auf Unternehmensebene sprechen, der für Ihre Produktionssysteme verwendet wird, dann haben Sie Spaß daran, jedem, der das Budget kontrolliert, zu erklären, dass er das von Ihnen gewünschte SAN mit mehr als einer Million Dollar nicht ablehnen sollte, weil es "billig" ist ;-).

Auf welche Probleme könnte ich stoßen, wenn ich den UCS-2-Stream hochschwimme?

Keine, an die ich denken kann.Nun, solange Sie keinen schrecklichen Rat befolgen, etwas wie die Implementierung dieses UDT oder die Konvertierung aller Zeichenfolgen in zu tun VARBINARY, oder mit NVARCHAR(MAX) für alle String-Felder ;-).Aber von all den Dingen, über die Sie sich Sorgen machen könnten, sollte SQL Server mit UCS-2 / UTF-16 nicht dazu gehören.

Wenn jedoch aus irgendeinem Grund das Problem der fehlenden nativen Unterstützung für UTF-8 sehr wichtig ist, müssen Sie möglicherweise ein anderes RDBMS finden, das UTF-8 zulässt.


AKTUALISIERUNG 02.10.2018

Obwohl dies noch keine praktikable Option ist, führt SQL Server 2019 die native Unterstützung für UTF-8 ein VARCHAR / CHAR Datentypen.Es gibt derzeit zu viele Fehler, als dass sie verwendet werden könnten, aber wenn sie behoben sind, ist dies eine Option für einige Szenario.Bitte sehen Sie sich meinen Beitrag an. "Native UTF-8-Unterstützung in SQL Server 2019:Retter oder falscher Prophet?", für eine detaillierte Analyse dieser neuen Funktion.

Andere Tipps

Was meinst du damit mit "Schwimmen des UCS-2-Streams"?

Hier sind Ihre Optionen:

  • Verwenden Sie die neuen 2012 _SC-Kollationen ( https://msdn.microsoft.com/en-us/library/ms143726.aspx ).Diese Idee kommt von Srutzky.Sie sollten seine Antwort überprüfen.Dies ist bei weitem die beste Lösung.

    nicht empfohlen, aber möglich:

    • Implementieren Sie eine UDT.Dies ist viel Arbeit, und Sie verlieren die Tolling-Unterstützung (oder Mapping und sicherlich einige SQL Server-Funktionen, die an nativen Typen funktionieren).
    • Verwenden von VARBINARY (MAX): Erfordert, dass Sie benutzerdefinierte Konvertierungscode ausführen.Keine Reichweite-Indizierung.
    • Verwenden Sie nvarchar (n) und schalten Sie die Zeilenkomprimierung ein.Beginnend mit SQL Server 2008 R2 wird eine Codierung verwendet, die ebenso kompakt wie utf-8 ist.Dies erfordert jedoch die Enterprise Edition.

      sehen Sie die Kommentare, um über die schweren Nachteile zu lesen, die diese Ansätze haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top