koallalays: VarChar oder Char

Hi,

hab mal eine theoretische Frage....

ich hab vor kurzem in der MySQL doku glesen, daß wenn man den Typ CHAR (und INT...) verwendet ... daß MYQL dann schneller ist weil es weiß wo die nächste Zeile "auf der Festplatte" anfängt weil die Zeilenlänge immer gleich ist..... irgendwie klar...

jetzt meine Frage hat es Auswirkungen, ob ich jetzt 1, oder 2 VARCHAR in einer Tabelle verwende .... ... ich bräuchte für eine Spalte nämlich mehr als die 255 Zeichen =>
was mich also zu dem Vergleich veranlaßt

2 x VARCHAR
oder 1 x VARCHAR + 2 x CHAR(255)

weiß das zufällig wer?

Danke :)

  1. ich bräuchte für eine Spalte nämlich mehr als die 255 Zeichen =>
    was mich also zu dem Vergleich veranlaßt

    2 x VARCHAR
    oder 1 x VARCHAR + 2 x CHAR(255)

    weiß das zufällig wer?

    Da brauchst Du mindestens TEXT (max. 65536 Zeichen) als Feldtyp:
    http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html

    1. Moin!

      2 x VARCHAR
      oder 1 x VARCHAR + 2 x CHAR(255)

      weiß das zufällig wer?

      Da brauchst Du mindestens TEXT (max. 65536 Zeichen) als Feldtyp:
      http://dev.mysql.com/doc/refman/5.0/en/string-type-overview.html

      Und wenn du eine Spalte variabler Länge, also den Typen Text, Blob oder eben Varchar in deiner Tabelle hast, werden auch alle anderen Spalten, die vom Typ Char sind, in Varchar umgewandelt. Ausnahme: Varchar(3) (oder kürzer) wird in char(3) umgewandelt, weil das weniger Speicherplatz benötigt.

      Dazu steht auch vieles im MySQL-Handbuch.

      - Sven Rautenberg

      --
      My sssignature, my preciousssss!
      1. Und wenn du eine Spalte variabler Länge, also den Typen Text, Blob oder eben Varchar in deiner Tabelle hast, werden auch alle anderen Spalten, die vom Typ Char sind, in Varchar umgewandelt. Ausnahme: Varchar(3) (oder kürzer) wird in char(3) umgewandelt, weil das weniger Speicherplatz benötigt.

        Dazu steht auch vieles im MySQL-Handbuch.

        • Sven Rautenberg

        Danke!

        das beantwortet meine Frage!
        .... ich bin noch relatiev "neu" bei Mysql und hab bisher nur einfache Mysql Queries gemacht... befase mich aber jetzt ein bißchen mehr damit weil ich vorhabe ein Forum auf die Beine zu stellen... ich weiß nicht obs mir gelingen wird, aber ich schau halt daß ich im Vorfeld so viel infos wie möglich bekomme... wenn ich endlich ne gute DB-struktur im Kopf hab werd ich damit anfangen... ;)

        in der offiziellen MySQL-Doku hab ich bisher nur ein bißchen herumgeschmökert, die ist sehr unübersichtlich... zB wollt ich mir raussuchen, obs noch mehr Möglichkeiten bei LIKE gibt ...
        zB LIKE ("%text1%" || "%text2%) habe lange gesucht und doch keine eindeutige antwort daruf finden können (PS: geht das ?)

        grz,
        koallalays

        1. echo $begrüßung;

          [...] obs noch mehr Möglichkeiten bei LIKE gibt ...
          zB LIKE ("%text1%" || "%text2%") habe lange gesucht und doch keine eindeutige antwort daruf finden können (PS: geht das ?)

          Mir ist keine Programmiersprache bekannt, die soetwas zulässt. Solch ein Konstrukt ist nicht eindeutig auswertbar. Es lässt sich neben der von dir gewünschten Weise auch so interpretieren, dass zuerst der Ausdruck

          ("%text1%" || "%text2%")

          ausgerechnet werden soll. Das Ergebnis wäre dann das Argument für LIKE. Die Schreibweise

          a LIKE b OR a LIKE c

          ist eindeutig. (Gegebenenfalls muss man Teilausdrücke klammern, das ist aber in dem Fall nicht nötig, da LIKE stärker als OR ist und zuerst berechnet wird.)

          echo "$verabschiedung $name";

          1. Mir ist keine Programmiersprache bekannt, die soetwas zulässt. Solch ein Konstrukt ist nicht eindeutig auswertbar. Es lässt sich neben der von dir gewünschten Weise auch so interpretieren, dass zuerst der Ausdruck

            ";

            wie gesagt, ich hab bisher nur standard queries angewandt, und bis zu den mehreren Tabellen in einer Abfrage geglaubt das sei die ganze MySQL-Welt 0:) ... Mir wurde in einem andern Forum auf eine Frage hin geraten mich mit Joins zu beschäftigen (???) was ich auch prompt gemacht habe... dabei hab ich Sachen kennegelernt wie 5-fach verschachtelte Abfragen, rechenoperationnen in der Query...., die ich nie für Möglich gehalten hab ... deswegen auch die Suche nach LIKE... vielleicht gibts da ja auch was, was ich noch nicht kenne  ;)
            Der Wunsch mit dem Like ist aus

            spalte IN (2,3,79,1,4)

            entstanden, was ich schon immer sehr praktisch finde, und oft anwende ;)

            ( nen Versuch wars Wert :D )

            grz,
            koallalays

      2. Hi Sven,

        ist das wirklich reguläres Verhalten von MySQL, einfach alle anderen Spalten einfach so umzuwandeln? Gut, letzten Endes ist es aus Benutzersicht unerheblich ob ein 12 stelliger Code in char(12) oder varchar(12) gespeichert wird, aber dennoch finde ich ein solches Verhalten abnorm.

        Ciao, Frank

        1. Moin!

          ist das wirklich reguläres Verhalten von MySQL, einfach alle anderen Spalten einfach so umzuwandeln? Gut, letzten Endes ist es aus Benutzersicht unerheblich ob ein 12 stelliger Code in char(12) oder varchar(12) gespeichert wird, aber dennoch finde ich ein solches Verhalten abnorm.

          Der einzige Vorteil von Char gegenüber Varchar ist, dass konstante Feldlängen zu einer leichteren Auffindbarkeit eines Datensatzes führen.

          Wenn aber nicht alle Spalten der Tabelle konstante Feldlängen haben, sondern einer davon Varchar benutzt, ist dieser Vorteil komplett zunichte gemacht. Es ist daher im Sinne der Optimierung durch MySQL absolut sinnvoll, wenn der Vorteil konstanter Datensatzlänge nicht erreicht werden kann, dann weiter zu optimieren und den Vorteil geringerer Datenmenge durch Varchar auf alle Spalten anzuwenden.

          - Sven Rautenberg

          --
          My sssignature, my preciousssss!
          1. Hoi,

            dann weiter zu optimieren und den Vorteil geringerer Datenmenge durch Varchar auf alle Spalten anzuwenden.

            Sorry, aber diesen Nebensatz versteh ich jetzt irgendwie gar nicht mehr. Wie erhältst du durch die Verwendung von Varchar als Datentyp eine geringere Datenmenge, wenn du dieselben Inhalte speicherst?
            Natürlich unter der Voraussetzung das die Char(n) Spalten auch entsprechend mit n Zeichen gefüllt waren. Sonst ist klar.

            Aber egal, ich sehe es einfach mal als proprietäres MySQL Feature an ;)

            Ciao und Grüsse,
            Frank

            1. Hi ihr,

              Natürlich unter der Voraussetzung das die Char(n) Spalten auch entsprechend mit n Zeichen gefüllt waren. Sonst ist klar.

              In dem Fall bringt dich VARCHAR in der Tat nicht weiter, da hilft nur noch Viper

              MfG
              Rouven

              --
              -------------------
              ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
              1. Moin!

                Natürlich unter der Voraussetzung das die Char(n) Spalten auch entsprechend mit n Zeichen gefüllt waren. Sonst ist klar.
                In dem Fall bringt dich VARCHAR in der Tat nicht weiter, da hilft nur noch Viper

                Das mischt jetzt aber MySQL, von dem bisher die Rede war, mit DB2-Features, die ein komplett anderes Territorium sind.

                - Sven Rautenberg

                --
                My sssignature, my preciousssss!
            2. Moin!

              dann weiter zu optimieren und den Vorteil geringerer Datenmenge durch Varchar auf alle Spalten anzuwenden.

              Sorry, aber diesen Nebensatz versteh ich jetzt irgendwie gar nicht mehr. Wie erhältst du durch die Verwendung von Varchar als Datentyp eine geringere Datenmenge, wenn du dieselben Inhalte speicherst?

              Die Frage ist: Was sind "dieselben" Inhalte? Und wie stehen die in Beziehung zur definierten Spalte.

              Ein 32-Chars-MD5 wird natürlich besser in ein CHAR(32) gespeichert, als in ein VARCHAR(32), und in jedem Fall die gleiche Zahl an Zeichen einnehmen.

              Aber Tabellen, die ausschließlich CHAR haben, behalten diesen Typ ja auch.

              Wenn aber beispielsweise Namen (Personen-, Straßen-, Orts-, Produkt- etc.) gespeichert werden, gilt diese Aussage nicht.

              Es wäre daher sinnlos, eine Namensspalte als VARCHAR, die andere als CHAR zu speichern, wenn die Chance besteht, dass auch in der CHAR-Spalte nicht ausschließlich Strings der maximalen Länge gespeichert werden. Der Performancevorteil ist durch die eine VARCHAR-Spalte ohnehin dahin.

              Natürlich unter der Voraussetzung das die Char(n) Spalten auch entsprechend mit n Zeichen gefüllt waren. Sonst ist klar.

              Das ist der Punkt. :)

              Die Optimierung dürfte darauf hinauslaufen, wenigstens die Chance zu haben, Bytes einzusparen, wenn die Daten mal nicht die maximale Länge einnehmen.

              Aber egal, ich sehe es einfach mal als proprietäres MySQL Feature an ;)

              Das ist definitiv so.

              - Sven Rautenberg

              --
              My sssignature, my preciousssss!
              1. Ja, hoi,

                jetzt verstehe ich deine Argumentation, vorher war's mir irgendwie zu puzzlehaft ;)   Und wie ich schon sagte, letztenendes ist es aus Benutzersicht auch egal, ich bekomme ja bei Char(32) dieselben 32 Zeichen (vorausgesetzt ... du weißt schon) wie bei Varchar(32).

                Grüsse,
                Frank

          2. Hallo,

            Der einzige Vorteil von Char gegenüber Varchar ist, dass konstante Feldlängen zu einer leichteren Auffindbarkeit eines Datensatzes führen.

            Ist es aber an sich nicht so, dass CHAR immer Zeichenketten mit einer konstanten Länge ablegt und dabei gegebenenfalls mit Leerzeichen auffüllt, falls die eingefügte Zeichenkette kürzer als die vorgegebene Feldlänge ist?

            Wenn nun aber, so wie es MySQL macht, CHAR-Datentypen in VARCHAR umgewandelt wird, dann müsste es auch eine Strategie geben, wie man Abfragen wie

            select what, ever from table_x
            where char6field = 'ABC   '

            korrekt ausführen kann. Imho müsste also ein implizites TRIM (oder so ähnlich) ausgeführt werden, da ja die normalerweise aufgefüllten Leerzeichen im Feld fehlen.

            Und dann würde es auch passieren, dass man keine zwei Datensätze unterscheiden kann, die sich in einem VARCHAR-Datenfeld nur durch ein abschliessendes Leerzeichen unterscheiden.[1]

            Wie wird in MySQL solch ein Fall wirklich behandelt?[2]

            Grüße
              Klaus

            [1] Das Problem hat auch der .NET-DataProvider für/von Oracle. Ein Unique-Constraint auf ein VARCHAR2-Feld in der DB erkennt die Unterschiedlichkeit von 'ABC' und 'ABC ', der selbe Contraint im DataProvider hat mit solchen Dtaensätzen dann aber ein Problem.

            [2] Je mehr ich von MySQL so mitbekomme um so weniger mach ich diese Datenbank:-(

            1. Moin!

              Ist es aber an sich nicht so, dass CHAR immer Zeichenketten mit einer konstanten Länge ablegt und dabei gegebenenfalls mit Leerzeichen auffüllt, falls die eingefügte Zeichenkette kürzer als die vorgegebene Feldlänge ist?

              So ist es.

              Wenn nun aber, so wie es MySQL macht, CHAR-Datentypen in VARCHAR umgewandelt wird, dann müsste es auch eine Strategie geben, wie man Abfragen wie

              select what, ever from table_x
              where char6field = 'ABC   '

              korrekt ausführen kann. Imho müsste also ein implizites TRIM (oder so ähnlich) ausgeführt werden, da ja die normalerweise aufgefüllten Leerzeichen im Feld fehlen.

              Das Handbuch sagt dazu (http://dev.mysql.com/doc/refman/4.1/en/char.html):
              "When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed."

              "VARCHAR values are not padded when they are stored. Trailing spaces in MySQL version up to and including 4.1 are removed from values when stored in a VARCHAR column; this also means that the spaces are absent from retrieved values."

              "If you need a data type for which trailing spaces are not removed, consider using a BLOB or TEXT type."

              TINYTEXT kann max. 255 Zeichen aufnehmen, TEXT 65534 Zeichen.

              Und dann würde es auch passieren, dass man keine zwei Datensätze unterscheiden kann, die sich in einem VARCHAR-Datenfeld nur durch ein abschliessendes Leerzeichen unterscheiden.[1]

              Das ist offensichtlich so.

              [2] Je mehr ich von MySQL so mitbekomme um so weniger mach ich diese Datenbank:-(

              Für Version 5.1 gilt:
              "When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed."

              "VARCHAR values are not padded when they are stored. Trailing spaces are retained when values are stored and retrieved, in conformance with standard SQL."

              - Sven Rautenberg

              --
              My sssignature, my preciousssss!