Wie stellst du booleans in MySQL dar?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Wie stellst du booleans in MySQL dar?

    Hallo,

    vor einiger Zeit begann ich, DB-Anwendungen nach dem DRY-Prinzip aufzubauen. Dabei hole ich mir alle Informationen über Tabellen, Spalten, Indizes und Fremdschlüsselbeziehungen direkt aus der DB statt sie in der Anwendung nochmal zu modellieren.

    Bis dahin hatte ich noch "tinyint(1) unsigned not null" für boolean-Spalten benutzt, leider ist dabei nicht anwendungsseitig feststellbar, ob es sich dabei nicht doch um eine normale Ziffer handelt.

    Inzwischen nutze ich seit längerem "set('true') not null" und das hat einige Vorteile. Wenn es ganz normal selektiert wird, liefert es "true" oder "", was in PHP auf bool gecastet den korrekten Wert liefert. Selektiert man es in einem numerischen Kontext, liefert es 1/0, was auch ziemlich sinnvoll ist. Beim Schreiben kann man ebenfalls 1/0 reinschreiben oder auch das was PHP aus booleans in einem String-Kontext macht: '1'/''.

    Der einzige Nachteil dieser Variante ist, dass man in PHPMyAdmin erst mal wissen muss, wie man das Flag wieder löscht. Dazu braucht man die Strg-Taste. Außerdem könnte man denken, wenn dort true dasteht, wäre es schon gesetzt, was natürlich nur stimmt, wenn das Wörtchen auch farbig hinterlegt ist.

    Welche Varianten nutzt ihr, um boolean Werte abzubilden?

    Gruß,

    Amica
    19
    tinyint(1) unsigned not null
    0%
    14
    char(0) default null
    0%
    0
    enum('false', 'true') (oder umgekehrt)
    0%
    2
    set('true')
    0%
    1
    ganz anders
    0%
    2

    Die Umfrage ist abgelaufen.

    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

  • #2
    Ich benutze BOOLEAN, was ja nur ein Alias für TINYINT(1) ist. Und ich gebe den Spalten ein Präfix "is", also zum Beispiel isEnabled.

    Kommentar


    • #3
      Zitat von onemorenerd Beitrag anzeigen
      Ich benutze BOOLEAN, was ja nur ein Alias für TINYINT(1) ist. Und ich gebe den Spalten ein Präfix "is", also zum Beispiel isEnabled.
      So hatte ich es erst auch gemacht, aber das war mir für DRY-Anwendungen zu unsicher. Außerdem komme ich mit is_ nicht in allen Fällen hin. Ich brauche dann noch has_ und can_, weil mir solche Konstrukte wie is_having_ oder is_able_to_have_ irgendwann auch zu albern wurden
      [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
      Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
      Super, danke!
      [/COLOR]

      Kommentar


      • #4
        Früher hab ich Enums verwendet, mitlerweile dann doch nur tinyints. Das meisste wird aber halt auch schon in den Modellen abgefackelt.
        [FONT="Helvetica"]twitter.com/unset[/FONT]

        Shitstorm Podcast – Wöchentliches Auskotzen

        Kommentar


        • #5
          Ich habe dem Gedanken pro Boolean ein ganzes Feld zu verschwenden abgeschworen, sofern ich mehr als ein Boolschen Wert in einer DB speichern möchte. Ist das der Fall greife ich zu SET und nenne dieses Feld einfach "Booleans".

          Code:
          Booleans SET('Klima', 'Servo', 'Xenon', 'Lenkrad')
          Ist also sozusagen eine minimal abgewandelte Variante von 'set('true') not null' wo der Name des DB-Feldes ansich die Namensgebung übernimmt.

          Hab sowas vor einer Zeit mal gegen die andere Methode mit tinyint(1) unsigned not null getestet. Bei vielen Booleans blieb die SET-Methode beim Speicherplatzverbrauch im Vorteil, jedoch war interessant, das MySql viele tinyint(1) unsigned not null Felder "intelligent" handled. So war der Speicherplatzverbrauch bei einem Feld bei 7Bytes pro DS und blieb auch bei 4 solchen Feldern bei 7Bytes pro DS.

          Bei 10 Feldern gerät die SET-Methode aber schon in Vorteil beim Speicherplatzverbrauch und SELECTs auf größere Datenmengen waren auch schneller.
          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
          Schön - etwas Geschichte kann ja nicht schaden.
          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

          Kommentar


          • #6
            Feldname beginnt mit B_ und ist Tinyint(1) unsigned not null. Set kommt bei mir nur in Frage, wenn ich Felder mit mehreren Werten gleichzeitig brauche, nach denen ich schnell suchen muss.
            h.a.n.d.
            Schmalle

            http://impressed.by
            http://blog.schmalenberger.it



            Wichtige Anmerkung: Ich habe keine Probleme mit Alkohol ...
            ... nur ohne :-)

            Kommentar


            • #7
              wir verwenden enum('0','1') not null default '0'.

              tinyint(1) kann leider auch die werte von 2 bis 9 erhalten, bei "enum('0','1') not null" hast du wirklich nur 2 Zustände
              Slava
              bituniverse.com

              Kommentar


              • #8
                Zitat von Slava Beitrag anzeigen
                tinyint(1) kann leider auch die werte von 2 bis 9 erhalten
                Eben, daher halte ich das für absolut ungeeignet.

                Zitat von Slava Beitrag anzeigen
                bei "enum('0','1') not null" hast du wirklich nur 2 Zustände
                Der Nachteil an enum ist aber, dass die Werte in einem numerischen Kontext als 1 für false und 2 für true zurückgegeben werden und man beim Einfügen ganz genau drauf achten muss, ob sie als Strings oder als Zahl übergeben werden, da 1 false wäre, aber '1' true. Daher finde ich set('true') not null ideal, weil false dort als 0 und true als 1 rauskommt.
                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                Super, danke!
                [/COLOR]

                Kommentar


                • #9
                  Zitat von AmicaNoctis Beitrag anzeigen
                  Eben, daher halte ich das für absolut ungeeignet.
                  Die Werte 2-9 sind in PHP auch true.

                  Kommentar


                  • #10
                    Zitat von onemorenerd Beitrag anzeigen
                    Die Werte 2-9 sind in PHP auch true.
                    Das weiß ich doch, mir geht es aber darum, dass ich bei einer tinyint-Spalte nicht programmatisch feststellen kann, ob es eine Ziffer als solche repräsentieren soll oder einen Wahrheitswert, genauer gesagt: Soll ich das Feld dann als Checkbox realisieren oder als Textfeld (evtl. mit Tasteninterzeptor, der nur Zifferntasten akzeptiert)?
                    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                    Super, danke!
                    [/COLOR]

                    Kommentar


                    • #11
                      Zitat von AmicaNoctis Beitrag anzeigen
                      Das weiß ich doch, mir geht es aber darum, dass ich bei einer tinyint-Spalte nicht programmatisch feststellen kann, ob es eine Ziffer als solche repräsentieren soll oder einen Wahrheitswert ...
                      Das kann man am Präfix des Spaltennamens erkennen. Ich weiß, du willst es lieber direkt am Wert erkennen. Das klappt zwar mit deiner SET-Variante, aber dafür musst du beim Schreiben in die DB genau auf den Typ achten bzw. konvertieren. Denn aus einem Formular kommt von einer Checkbox irgendwas (vom User manipuliertes). Du musst daraus 'true' oder 'false' machen, während für TINYINT-Spalten ein Cast zu int genügt.

                      Eigentlich ist das alles nur eine Geschmacksfrage und imho kaum praxisrelevant. Ich habe jedenfalls schon ewig nichts mehr so programmiert, dass die Applikation den Datentyp aus dem DB-Schema oder -Werten erkennen muss.

                      Kommentar


                      • #12
                        Zitat von onemorenerd Beitrag anzeigen
                        Das kann man am Präfix des Spaltennamens erkennen.
                        Unzuverlässig.

                        Zitat von onemorenerd Beitrag anzeigen
                        Ich weiß, du willst es lieber direkt am Wert erkennen.
                        Nein, am Typ!

                        Zitat von onemorenerd Beitrag anzeigen
                        aber dafür musst du beim Schreiben in die DB genau auf den Typ achten bzw. konvertieren. Denn aus einem Formular kommt von einer Checkbox irgendwas (vom User manipuliertes). Du musst daraus 'true' oder 'false' machen, während für TINYINT-Spalten ein Cast zu int genügt.
                        Völlig falsch! Ich hab im ersten Beitrag dieses Threads schon ziemlich ausführlich erklärt, wie sich das verhält. Ich kann genau so auf int casten und erhalte den richtigen Wert - sowohl beim Select als auch beim Insert. Das ist alles völlig logisch und intuitiv.

                        Zitat von onemorenerd Beitrag anzeigen
                        Eigentlich ist das alles nur eine Geschmacksfrage und imho kaum praxisrelevant. Ich habe jedenfalls schon ewig nichts mehr so programmiert, dass die Applikation den Datentyp aus dem DB-Schema oder -Werten erkennen muss.
                        Es ist praxisrelevant. Ich will doch nicht jedes Mal, wenn sich an der DB ne Kleinigkeit ändert, die kompletten Model-Klassen durchwühlen, um die Änderungen dort auch vorzunehmen. Außerdem habe ich eine generische ReST-Schnittstelle zu MySQL entwickelt, die gar nicht realisierbar wäre, wenn ich nicht die strukturellen Metadaten der Datenbank auslesen würde. Das alles ist unter dem Namen DRY-Prinzip bekannt und durchaus sinnvoll, wenn man nicht für jedes Projekt alles doppelt modellieren will (DB und Model-Klassen).
                        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                        Super, danke!
                        [/COLOR]

                        Kommentar


                        • #13
                          Zitat von AmicaNoctis Beitrag anzeigen
                          Völlig falsch! Ich hab im ersten Beitrag dieses Threads schon ziemlich ausführlich erklärt, wie sich das verhält. Ich kann genau so auf int casten und erhalte den richtigen Wert - sowohl beim Select als auch beim Insert.
                          Ohja stimmt. Ich hatte schon vergessen, dass du kein 'false' im SET hast. Jedenfalls musst du auch casten. Beim Schreiben in die DB mit int(), beim Lesen mit bool(). Genau das muss man auch bei TINYINT.

                          In deiner selbstgebauten DB-Abstraktion hast du ein bißchen Code, der automatisch richtig castet. Aber dazu muss dieser Code auch das DB-Schema kennen. Sonst könnte man in ein Textfeld "true" eingeben und beim nächsten Aufruf wäre es eine Checkbox.
                          Woher kennt dein Code das DB-Schema? Offensichtlich liest er es aus der DB. Das kostet.

                          Ich will doch nicht jedes Mal, wenn sich an der DB ne Kleinigkeit ändert, die kompletten Model-Klassen durchwühlen
                          Wenn sich bei mir das DB-Schema ändert, spiegelt sich das zuerst im Code wider. Propel, Doctrine, sogar Drupal ...

                          Kommentar


                          • #14
                            *OT-Diskussion abgetrennt*
                            [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                            Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                            Super, danke!
                            [/COLOR]

                            Kommentar


                            • #15
                              bei einem feld der "feld set('true') not null" ist, erwarte ich logischeweise nur ein einziger wert und zwar 'true' (so eine spalte kann man ganz auslassen).

                              "Set" ist für die Anzeige von meheren Zuständen gleichzeitg ausgedacht und ein einzelner Eintrag set('true') sieht schon ein wenig verdächtigt aus

                              Die Tatsache , dass
                              " update tabelle set feld= ''; "
                              eine set-spalte bei MySql tatsächlich mit leerem String verändert, ist zwar machbar, aber leider verwirrend

                              Die Frage ist auch, ob so ein (meine Meinung nach ein falschen) Verhalten auch in den nächsten Versionen vom Mysql unterstützt wird.
                              Slava
                              bituniverse.com

                              Kommentar

                              Lädt...
                              X