none
Grundsätzliches zu Datentypen RRS feed

  • Frage

  • Hallo,

    wir haben seit über 15 Jahren gewachsene Datenbanken mit unzähligen Tabellen und einer wilden Kombination von Datentypen.
    Mir geht es aktuell um einen optimalenDatentypen für Textfelder.
    Meine Überlegung war als Datentyp für Text grundsätzlich NVARCHAR zu verwenden, da wir in den Datenbanken zumindest teilweise mit "internationalen" (zumindest europäischen) Zeichen klar kommen müssen.
    Darüber habe ich mal irgendwo gelesen das NVARCHAR und VARCHAR Felder immer nur so viel Speicherplatz benötigen wie auch Zeichen darin gespeichert sind.

    Da ich in einem NVARCHAR Feld maximal 4000 und in einem VARCHAR Feld das Doppelte speichern kann, frage ich mich ob es wirklich die beste Lösung komplett auf NVARCHAR umzusteigen.

    Wir habe Tabellen mit teilweise mehreren Millionen Datensätzen und in einigen Fällen auch sehr vielen Feldern.

    Hat jemand Erfahrung mit diesem Thema?

    Bin für jeden Tipp dankbar.

    Freitag, 30. Oktober 2020 13:24

Alle Antworten

  • Korrekt, CHAR speichert die Daten in eine fixen Länge, während VARCHAR es in der variablen Länge speichert.

    Du kannst auch den Datentyp (N)VARCHAR(MAX) als Ersatz für den abgekündigten Datentypen TEXT verwenden.

    Siehe char und varchar (Transact-SQL) mit einer ausführlichen Beschreibung


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Freitag, 30. Oktober 2020 14:10
  • Und NVARCHAR speichert Text in Unicode, somit sind weltweit alle Textarten ob bekannt oder unbekannt speicherbar.
    Freitag, 30. Oktober 2020 17:11
  • Und NVARCHAR belegt den doppelten Speicherplatz wie VARCHAR, was auch beim Transport zu anderen Systemen und zum Client zu beachten ist, wenn größere Mengen bewegt werden.

    Ich würde NVARCHAR nur dort einsetzen, wo ich auch Unicode-Zeichen in einem Feld erwarte.

    Jedes Textfeld variabler Länge (VARCHAR oder NVARCHAR) hat außerdem einen Overhead von 2 Byte, in denen die Länge abgelegt ist. Wenn ein Textfeld variabler Länge aber NULL enthält, belegt es keinen Speicherplatz.

    Ein VARCHAR(2) macht also nicht unbedingt Sinn gegenüber einem CHAR(2), da es mehr Platz belegt. Ein CHAR(2) liefert Dir aber noch ein zusätzliches Leerzeichen, falls Du nur ein Zeichen ablegst. Ein VARCHAR macht das nicht.

    DECLARE @myChar CHAR(2) = 'A',
    		@myVarchar VARCHAR(2) = 'B';
    
    SELECT @myChar, 'X'+@myChar + 'X', @myVarchar, 'X'+@myVarChar + 'X';


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu

    Montag, 2. November 2020 09:00
  • Ist Platz heute noch ein Problem?
    Unicode ist für moderne Anwendungen heute bereits Pflicht, da man alleine schon west- und osteuropäische Daten (polnisch, tchechisch usw,) nicht unter einen Hut bekommen kann.
    Andere Datenbanken wie Oracle/Firebird speichern die Daten von NVARCHAR in UTF-8 um den Grenzen der 2-Byte-Speicherung zu entgehen.
    Klar, kann ich bei Feldern, die nur invariante Zeichen enthalten, auch auch auf CHAR oder VARCHAR ausweichen.

    Der SQL-Server kann noch zwischen UCS2 (fixe 2-Byte-Speicher) oder UTF-16 (variable 2/4-Byte-Speicherung) unterscheiden.

    https://docs.microsoft.com/de-de/sql/t-sql/data-types/nchar-and-nvarchar-transact-sql?view=sql-server-ver15

    Montag, 2. November 2020 09:53
  • Vielleicht habe ich mich nicht genau genug ausgedrückt.
    Wir speichern in unseren Tabellen Lateinische Schrift aber es kommen halt so ziemlich alle europäischen Sonderzeichen vor.
    Wenn dafür VARCHAR reichen würde, würde ich es vorziehen.

    Wir haben leider in vielen Indizes Textzeichen, der Join damit ist ja schon nicht besonders schnell und wenn ich pro "Buchstabe" dann 2 anstatt einem Zeichen vergleichen muss, dürfte alles entsprechend länger dauern.

    Und nein, wir können das mit den Texten in den Schlüsseln nicht ändern.

    Dienstag, 3. November 2020 10:19
  • Hier spricht man dann von "Microoptimierungen".
    Wie lange dauert ein Vergleich von 2 Zeichenketten einer beliebigen Länge?
    Ich denke messbar wird das erst ab ein paar Megabyte.

    Da dauert es schon länger, bei den meisten Indexzugriffen, die Daten caseinsensitive zu vergleichen.
    Vor einem Vergleich müssen die Daten nämlich erst caseinsensitive umgesetzt werden.
    Was allerdings genauso schnell wie ein Vergleich ist.

    "europäischen Sonderzeichen" gliedern sich ja nun schon in 2 Sprachräume (Latin): west- und osteuropäisch.
    [VAR]CHAR kann aber  nur genau 1 Sprachraum speichern.

    Sprachräume sind Latin-1 bis Latin-n, auch bekannt als ISO-8859-1 bis -n.
    Ich denke jeder hat schon mal das Problem mit unseren Umlauten gehabt, wenn die Daten mit diversen Codepages (OEM 850, Windows 1252, ...) verarbeitet werden.

    Dienstag, 3. November 2020 14:04