Gerda: mysql Datentyp

Hallo,

ich programmiere gerade an einem Shop und habe eine Grundlegende Frage.

Und zwar bin ich nun an dem Punkt wo och den Datentyp auswähle.
Zum Beispiel ich muß nun Meine Bestellungen in folgenden Kategorien abspeichern

Status: Offen
        In Arbeit
        Versendet

Was ist nun besser den Datentyp varchar zu wählen und den Status in Wörtern rein zu schreiben oder ein Int zu wählen und es in 1, 2 oder 3 abzuspeichern

Die Frage ist immer wie mysql es intern schneller verarbeiten kann wenn ich eine Abfrage starte wo ich Frage ob der Status schon in Arbeit ist und alle diese sollen mir angezeigt werden.

Mache ich das mit varchar oder besser mit int?

Ich bin Euch Dankbar für eure Hilfe!

Gruß Gerda

  1. Status: Offen
            In Arbeit
            Versendet

    Was ist nun besser den Datentyp varchar zu wählen und den Status in Wörtern rein zu schreiben oder ein Int zu wählen und es in 1, 2 oder 3 abzuspeichern

    Wenn du sicher bist das es nur diese drei Wert gibt, dann könnte ich dir noch ENUM empfehlen das ist wohl auch sehr schnell.

    Struppi.

    1. Wenn du sicher bist das es nur diese drei Wert gibt, dann könnte ich dir noch ENUM empfehlen das ist wohl auch sehr schnell.

      Hallo Struppi,

      Ich habe genau genommen 6 Werte die was über den Status aussagen.

      Wenn ich nun den Status mit 1,2,3,4,5,6 bestimme und in einer weiteren Tabelle die Bezeichnung auslese macht das Sinn?

      In dem Fall hätte ichj ja schon mal 2 Zugriffe auf die Datenbank oder ich schreibe die Bezeichnung im PHP Quelltext

    2. Hallo

      ehrlich gesagt verstehe ich den Datentyp ENUM nicht
      Ich habe mir folgenden verlinkte Seite durchgelsen.

      [link]http://www.mysql.de/doc/de/ENUM.html[/link]

      Wert  Index
      NULL  NULL
      ""      0
      "eins"  1
      "zwei"  2
      "drei"  3

      Wozu muß ich denn hier noch den Index anlegen? Ich brauche das gar nicht. Weil ich eine Bestellnummer habe.

      um nun den "Wert" auslzulesen muß ich erst den Index abfragen oder wie soll ich das verstehen?

      Gruß Gerda

      1. Hello,

        ehrlich gesagt verstehe ich den Datentyp ENUM nicht
        Ich habe mir folgenden verlinkte Seite durchgelsen.

        [link]http://www.mysql.de/doc/de/ENUM.html[/link]

        Wert  Index
        NULL  NULL
        ""      0
        "eins"  1
        "zwei"  2
        "drei"  3

        Wozu muß ich denn hier noch den Index anlegen? Ich brauche das gar nicht. Weil ich eine Bestellnummer habe.

        Den Index legt MySQL automatisch an.

        um nun den "Wert" auslzulesen muß ich erst den Index abfragen oder wie soll ich das verstehen?

        Du kannst abfragen nach dem Klartext oder auch nach dem Index. Deshalb sollte man ENUM-Felder nicht für numerische Werte benutzen. Das kann großes Durcheinander bringen.

        Hast Du MySQL-Front? Das läuft auf Windows und Du kannst damit auf deine Datenbanken über Port zugreifen (sofern der bereitgetellt ist). Damit kann man recht gut seine kleinen Experimente machen. Es funktioniert (meistens) besser, als dies PHPMySqlAdmin (oder wie das Ding heißt).

        Liebe Grüße aus http://www.braunschweig.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        1. Hallo Tom,

          nein ich habe einen Linux Server am laufen.
          ein Index habe ich ich ja auch über meine Rechungsnummern...

          Aber so richtig habe ich es immer noch nicht verstanden wo der Unterschied zwischen varchar ist und enum? Muß ich in enum irgendwo eintragen welche Werte gesetzt werden?

          Ich benutze phpmyadmin und wollte nun ein neues tesfeld anelegen und wähle enum aus aber dann bekomme ich ein MySQL Fehler: #1064

          Oder muß ich in Standard Wert was eintragen? Wenn ja was?

          Irgendwie stehe ich momentan auf der Leitung...

          1. Aber so richtig habe ich es immer noch nicht verstanden wo der Unterschied zwischen varchar ist und enum? Muß ich in enum irgendwo eintragen welche Werte gesetzt werden?

            enum ist nur ein Byte gross und du hast eine Liste von Werten (ich seh gerade evtl. ist SET für dein Fall besser egeignet, da ich auch noch nicht soviel damit gemacht habe musst du dir mal die Doku durchlesen, was für was sinnvoll ist) und du setzt dann den entsprechenden Wert.

            Normalerweise sowas:

            ENUM('y', 'n')

            und als Wert überträgst du 'y' oder 'n' ansonsten wirft die DB einen Fehler.

            Ich benutze phpmyadmin und wollte nun ein neues tesfeld anelegen und wähle enum aus aber dann bekomme ich ein MySQL Fehler: #1064

            Oder muß ich in Standard Wert was eintragen? Wenn ja was?

            Ja, du musst eine Liste von Werten angeben und bei NOT NULL einen aus dieser Liste als default wählen.

            Struppi.

            1. Ich fange es nun an zu verstehen :)

              Also in meiner Liste steht nun z.B.:
              Offen','Zahlungseingang','In Bearbeitung','Pakete werden kommissioniert','Pakete warten auf Abholung','Pakete sind unterwegs'

              Die Frage ist nun nocht macht es viel an Geschwindigkeit aus wenn jeweils 1-3 Wörter dort stehen?

              Oder ist die ganze Prozedur schneller wenn ich es jeweils auf 2 Zeichen begrenze? Fraglich ist was schnell ist?

              ENUM bezieht sich auf 65535 Elementen ich gehe mal davon aus das es der max Wert handelt?

              Aber beziehen sich die Elemente auf das ENUM Datbank Feld oder auf die einzelnen Zeilen. Ich meine damit wenn ich ein Index habe hat der Index nur 65535 Felder?

              1. Ich fange es nun an zu verstehen :)

                und ich komm an meine Grenze ;-)

                Also in meiner Liste steht nun z.B.:
                Offen','Zahlungseingang','In Bearbeitung','Pakete werden kommissioniert','Pakete warten auf Abholung','Pakete sind unterwegs'

                Die Frage ist nun nocht macht es viel an Geschwindigkeit aus wenn jeweils 1-3 Wörter dort stehen?

                Intern werden die Werte als Index der Liste abgespeichert deshalb ist die  suche schneller, beim übetragen der Daten ist es natürlich genau so schnell oder langsam.

                ENUM bezieht sich auf 65535 Elementen ich gehe mal davon aus das es der max Wert handelt?

                Nein, die maximale Anzahl von Einträgen.

                Aber beziehen sich die Elemente auf das ENUM Datbank Feld oder auf die einzelnen Zeilen. Ich meine damit wenn ich ein Index habe hat der Index nur 65535 Felder?

                Das versteh ich nicht ganz. Wie gesagt ENUM speichert im Prinzip (vielleicht kann ein mySQL Fachmann das bestätigen oder verbessern) nur den Index der ENUM Liste ab, also in deinem Fall, statt 'offen' eine 0 statt 'Zahlungseingang' eine 1 usw. nur du musst beim Übertragen der Daten den Klartext schreiben.

                Du kannst natürlich genauso unsigned tinyint(1) verwenden und in deiner Applikation die Umrechnung machen, dann ist die Übertragung schneller.

                Was letztlich am besten ist liegt wohl in deinem ermessen und ob du mit den jeweilig auftretenden Problemen kannst.

                Struppi.

                1. Hallo

                  ENUM bezieht sich auf 65535 Elementen ich gehe mal davon aus das es der max Wert handelt?

                  Nein, die maximale Anzahl von Einträgen.

                  Also das ist der max Wert pro Feld? Den SET hat nur 64
                  Wenn ich ein SET auf Anrede setze mit den Werten 'Herr','Frau' reicht das aus? Pro Feld wären das in dem Beispiel nur 2 Elemente.
                  Oder auf was beziehen sich die Elemente? Vielleicht habe ich das auch falsch verstanden?

                  Das versteh ich nicht ganz. Wie gesagt ENUM speichert im Prinzip (vielleicht kann ein mySQL Fachmann das bestätigen oder verbessern) nur den Index der ENUM Liste ab, also in deinem Fall, statt 'offen' eine 0 statt 'Zahlungseingang' eine 1 usw. nur du musst beim Übertragen der Daten den Klartext schreiben.

                  Beim UPDATE oder INSERT darf ich in mein mysql Query nicht offen setzen sondern muß das Element über das Indiziz ansprechen?

                  Also 0 für offen und 1 für bezahlt usw. wenn das so ist dann habe ich es erst jetzt richtig verstanden.

                  1. Hello,

                    ENUM bezieht sich auf 65535 Elementen ich gehe mal davon aus das es der max Wert handelt?

                    Nein, die maximale Anzahl von Einträgen.

                    Nein, der höchste Index!
                    Die Werte liegen doch im Klartext vor.
                    Also der höchste Index und damit die größte Anzahle unterschiedlicher Werte für die Spalte.

                    Also das ist der max Wert pro Feld? Den SET hat nur 64

                    Mit 8Byte Flags lassen sich nur 8*8 Bits (=Flags) setzen. Da bei einem SET die Werte optional und nicht alternativ sind, dürfen sie eben alle gleichzeitig auftreten.

                    Wenn ich ein SET auf Anrede setze mit den Werten 'Herr','Frau' reicht das aus? Pro Feld wären das in dem Beispiel nur 2 Elemente.

                    Wie meisnt Du das jetzt?
                    Ich habe noch nicht gesehen, dass jemand Herr und Frau gleichzeitig als Anrede hat. Und ulkig fände ich es auch, wenn man an Herr Mercedes Benz AG schreibt oder an Frau TU Berlin.

                    Es fehlen also mindestens die Alternativen "" und "Firma". Ich würde dann noch "Familie" hinzunehmen.

                    Beim UPDATE oder INSERT darf ich in mein mysql Query nicht offen setzen sondern muß das Element über das Indiziz ansprechen?

                    Du kannst entweder 1 eingeben oder "offen" schreiben

                    ACHTUNG:

                    update ADRESSE set STATUS='2' where ID_ADRESSE=5;

                    würde den Status auf den Klartext 2 setzen, wenn vorhanden, und sonst auf den Index 2, wenn definiert. Deshalb nochmals meine Warnung: ENUM-Felder sind nicht für Numerische Werte geeignet!

                    Wenn man also die Auswahl von Nummernstrings abspeichern muss, dann ist Enum ungeeignet.

                    Liebe Grüße aus http://www.braunschweig.de

                    Tom

                    --
                    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                    1. hi,

                      ACHTUNG:

                      update ADRESSE set STATUS='2' where ID_ADRESSE=5;

                      würde den Status auf den Klartext 2 setzen, wenn vorhanden, und sonst auf den Index 2, wenn definiert. Deshalb nochmals meine Warnung: ENUM-Felder sind nicht für Numerische Werte geeignet!

                      interessant wäre hier, wie auf
                      SET STATUS=2
                      reagiert wird, also mit einem definitiv nummerischen wert.
                      weisst du zufällig genaueres?

                      gruss,
                      wahsaga

                      --
                      http://wazgnuks.net/ - back from the dead
                      1. Hello,

                        interessant wäre hier, wie auf
                        SET STATUS=2
                        reagiert wird, also mit einem definitiv nummerischen wert.
                        weisst du zufällig genaueres?

                        Zufällig nicht, aber absichtlich:

                        definiertes ENUM('1','2','3','4','5','7','10')

                        Index             1   2   3   4   5   6   7

                        insert into ADRESSE set IDX=10;

                        funktioniert nicht, da der höchste Index 7 ist.

                        insert into ADRESSE set IDX='10';

                        Trägt 10 ein.

                        Wenn ich jetzt aber schreibe

                        update ADRESSE set IDX='6' where ID_ADRESSE=10;

                        Dann steht im Datensatz nachher 7 drin.

                        Updates numerischer ENUM-Listen sind also mit MySQL 3.23.55-max nicht fehlerfrei möglich. Leider habe ich die version 4.x eingepackt.

                        Liebe Grüße aus http://www.braunschweig.de

                        Tom

                        --
                        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                        1. Hello,

                          update ADRESSE set IDX=7 where ID_ADRESSE=10;

                          Dann steht im Datensatz nachher 10 drin.

                          Über den Index funktioniert es also. Den muss man sich nur immer erst aktuell beschaffen, da er nicht starr an den Wert gekoppelt bleibt. Wenn also zwischendurch ein

                          ALTER TABLE ADRESSE CHANGE IDX IDX ENUM('1','2','3','4','6','7','10') durchgeführt wurde, sind die Indexe neu vergeben. Die Tabelle wird automatsich angepasst.

                          Liebe Grüße aus http://www.braunschweig.de

                          Tom

                          --
                          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                        2. insert into ADRESSE set IDX=10;

                          funktioniert nicht, da der höchste Index 7 ist.

                          insert into ADRESSE set IDX='10';

                          Trägt 10 ein.

                          Wenn ich jetzt aber schreibe

                          update ADRESSE set IDX='6' where ID_ADRESSE=10;

                          Dann steht im Datensatz nachher 7 drin.

                          Updates numerischer ENUM-Listen sind also mit MySQL 3.23.55-max nicht fehlerfrei möglich. Leider habe ich die version 4.x eingepackt.

                          Hello!

                          Was ist denn IDX ?

                          Kann ich irgendwie auch die Anzahl von den ENUM oder SET Elementen auslesen? Finde dazu leider nichts

                          Gruß Gerda

                          1. Hello Gerda,

                            update ADRESSE set IDX='6' where ID_ADRESSE=10;

                            Was ist denn IDX ?

                            Bitte beschäftige Dich mit der (My)SQL-Syntax. IDX ist ein Spaltenname. Das geht hier eindeutig aus dem Kontext hervor. Da der Thread sich entwickelt hat, kann man das durchaus nachvollziehen. Ich habe die Spalte als ENUM('1','2',...,'7','10') angelget, um den anderen von wahsaga angeregten Test noch zu machen.

                            Kann ich irgendwie auch die Anzahl von den ENUM oder SET Elementen auslesen? Finde dazu leider nichts

                            Du solltest dich sowieso früher oder später mit einer Auskunftsfunktion zur Tabelle beschäftigen. Da man später zu fast jedem feld eine Info benötigt, habe ich mal eine Funktion get_info() erstellt (im Archiv!), die auf dem SQL-Statement "show columns from $table" beruht [1].

                            Sie liefert ein speziell formatiertes Array mit allen möglichen Informationen zu den Tabellenfeldern zurück.

                            Das soll nur eine Anregung sein, Du wirst sicher eine eigene und viel bessere schreiben, wenn Du erst ein bisschen weiter bist. Die könntest Du dann aber auch hier veröffentlichen.

                            [1] $table ist der Name der Tabelle, über deren Struktur Du etas wissen möchtest.

                            Liebe Grüße aus http://www.braunschweig.de

                            Tom

                            --
                            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                2. Hello,

                  Ich fange es nun an zu verstehen :)

                  und ich komm an meine Grenze ;-)

                  Na, dann mal los, frag mich doch mal *ggg*
                  (habe mir das gerade noch mal im Hexeditor angeschaut)

                  Also in meiner Liste steht nun z.B.:
                  Offen','Zahlungseingang','In Bearbeitung','Pakete werden kommissioniert','Pakete warten auf Abholung','Pakete sind unterwegs'

                  Die Frage ist nun nocht macht es viel an Geschwindigkeit aus wenn jeweils 1-3 Wörter dort stehen?

                  Unwesentlich, denn die Klartexte stehen hintereinander in der Werteliste Felddefinition der *.frm -Datei

                  S T A T U S          O f f e n    Z a h l u n g s e i n g a n g    I n   B
                  . . . . . . FF 00 FF . . . . . FF . . . . . . . . . . . . . . . FF . . . .

                  und so weiter. Statt der 00 stünde der Default-Wert, wenn angegeben.

                  ENUM bezieht sich auf 65535 Elementen ich gehe mal davon aus das es der max Wert handelt?

                  Nein, die maximale Anzahl von Einträgen.

                  Die Maximale Anzahl von verschiedenen Werten, die das ENUM-Feld in der Datendatei annehmen kann. ENUM hat entweder 255 Wert plus Default-Wert oder 65535 Werte plus Default. Bei meiner Version ist zusätzlich immer auch NULL möglich. Wenn man beim Select einen Wert angibt, den es in der Liste nicht gibt, bleibt das Query von vornherein leer.

                  Aber beziehen sich die Elemente auf das ENUM Datbank Feld oder auf die einzelnen Zeilen. Ich meine damit wenn ich ein Index habe hat der Index nur 65535 Felder?

                  Hier ist was durcheinandergekommen.
                  Der Index ist intern und bezieht sich hier auf die Position des ENUM-Wertes in der Definitionliste (s.o.)

                  Das versteh ich nicht ganz. Wie gesagt ENUM speichert im Prinzip (vielleicht kann ein mySQL Fachmann das bestätigen oder verbessern) nur den Index der ENUM Liste ab, also in deinem Fall, statt 'offen' eine 0 statt 'Zahlungseingang' eine 1 usw. nur du musst beim Übertragen der Daten den Klartext schreiben.

                  Statt Offen eine 1 und statt Zahlungseingang eine 2
                  Man muss nicht unbedingt den Klartext schreiben, sondern kann den Index benutzen. Nur muss man den kennen! Wenn man einen falschen Index benutzt, der aber trotzdem belegt ist, dann kann MySQL den fehler nicht erkennen. Wenn man einen falschen Klartext benutzt, der nicht vorhanden ist, wird 00 eingetragen. Es gibt _keinen_ fehler.

                  Bitte merken: Datenbanken fangen meistens bei 1 an zu zählen (MySQL tuts jedenfalls). das gilt für die Indexe genauso wie für eine Position in einem String. Ein String beginnt bei 1 und nicht wie in PHP und C bei 0.

                  Liebe Grüße aus http://www.braunschweig.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            2. Hello,

              Normalerweise sowas:

              ENUM('y', 'n')

              und als Wert überträgst du 'y' oder 'n' ansonsten wirft die DB einen Fehler.

              Nein, die DB verursacht keinen Fehler, zumindest nicht bei Version 3.23.55-max. Es wird bei fehlerhafter Eingabe einfach 0 eingetragen. Ob das bei Version 4 anders ist, weiß ich nicht.

              Man kann auch "Not Null" setzen. Es lässt sich trotzdem der Wert "" eintragen. Eine Prüfung muss also unbedingt durch die API stattfinden.

              Ich habe die Korrektur- und Ergänzugsmöglichkeit nochmals ausprobiert, und mir die Änderungen im HEX-Editor angeschaut. Man kann nachträglich Auswahlwerte hinzufügen oder entfernen. Die Daten bleiben erhalten. MySQL passt automatisch den Index in der Datendatei (*.MYD) an, zumindest, wenn man nicht mehr als eine Änderung gleichzeitig an der ENUM-Wertedefinition vornimmt. Die schweren Fehler bei den ENUM-Feldern (in einer älteren MySQL-Version) scheinen also behoben.

              ENUM ist eine Tabelle in der Tabelle. das heißt, dass in der Definition der Tabelle (*.frm) die Werteliste nebst Indexen angelegt wird. Im der Datentabelle steht dann nur der Index. Bei der Anzeige ersetzt MySQL diesen Index durch den Klartext aus der internen Nachschlagetabelle.

              Liebe Grüße aus http://www.braunschweig.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              1. Hello,

                endlich habe ich es verstanden! Jetzt verstehe ich auch die Beschreibung im MySQL Manuel...

                Du sprichst von Klartext was meinst Du damit genau?
                In PHPmyAdmin gibt es eine Auswahl (Checkbox) Volltext.

                Muß ich das ankreuzen bzw. ich weiß nicht wirklich wozu die Option gut sein soll?

                Gruß Gerda

                1. Hello,

                  Du sprichst von Klartext was meinst Du damit genau?
                  In PHPmyAdmin gibt es eine Auswahl (Checkbox) Volltext.

                  Muß ich das ankreuzen bzw. ich weiß nicht wirklich wozu die Option gut sein soll?

                  Ich leider auch nicht, da ich PHPmyAdmin schon lange nicht mehr benutze.

                  Index    Klartext
                    0                       leeres Feld
                    1        offen
                    2        in Arbeit
                    3        Versand

                  Ich vermute, dass Du nun über das Wort "Index" bei "Volltext" gelandet bist. Der Index des Feldes hat aber nichts mit dem Index der Werte IM Feld zu tun.

                  Liebe Grüße aus http://www.braunschweig.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  1. Index    Klartext
                      0                       leeres Feld
                      1        offen
                      2        in Arbeit
                      3        Versand

                    Ok soweit habe ich das jetzt verstanden!

                    Danke!

  2. Mojen,

    Status: Offen
            In Arbeit
            Versendet

    Also für den Status nimmst du Number,

    d.h. 1, 2, 3

    Wenn du eine Verweistabelle machts legt du den Primary Key auf die
    Spalte (z.b. status_id) mit den Nummern und hast eine zweite Spalte
    (z.b. status_text), die hat nun Varchar2.

    Somit hast du überall, wo der Status hineinkommt, die einzelne Zahl, und in nem Select ließt du den Text aus.

    sYs

  3. Hello Gerda,

    Status: Offen
            In Arbeit
            Versendet

    Prinzipiell stimme ich Struppi zu, dass Enum der passende Typ wäre. Man kann dan sowohl über 1,2,3 als auch über Offen, In Arbeit, Versendet zugreifen. Maybe, this Feature is a Bug...

    Allerdings machen enum-felder bei der nachträglichen Änderung (wenn schon daten in der Tabelle sind) große Probleme. Wenn also jemand auf die Idee kommt, lieber die Abteilung reinzuschreiben: Eingang, Bearbeitung, Versand oder das ganze auf Französisch anzuzeigen, obwohl schon Daten drin sind im System, dann hast Du ein Problem.

    Wenn das Frontend mit HTML erstellt werden soll, musst Du für die Formular-Datenbank-Kopplung sowieso prüfen, ob der Wert zulässig ist, der übertragen wird. Dazu musst Du dann die Enum-Felder auslesen (ich hatte da mal eine generelle Funktion get_info() angefangen und hier veröffentlicht).

    Mach mal einen Versuch, was eingetragen wird ins enum-feld, wenn ein falscher Wert ankommt.

    Ich denke, es ist aus diesen praktischen Erwägungen besser, diese Übersetzung an PHP zu übergeben.

    MySQL ist kein vollständiges DBMS sondern ein intelligents "Tabellenabfragesystem".

    Liebe Grüße aus http://www.braunschweig.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen