| SQL / Datenbanken Probleme mit SQL? Hier könnt ihr eure Fragen zu SQL (MySQL, PostgreSQL, MS-SQL und andere ANSI-SQL Server) los werden. |
|
Umfrageergebnis anzeigen: Wie stellst du booleans in MySQL dar?
|
|
tinyint(1) unsigned not null
|
  
|
14 |
73,68% |
|
char(0) default null
|
  
|
0 |
0% |
|
enum('false', 'true') (oder umgekehrt)
|
  
|
2 |
10,53% |
|
set('true')
|
  
|
1 |
5,26% |
|
ganz anders
|
  
|
2 |
10,53% |
 |
|

08-10-2009, 13:28
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
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
Geändert von AmicaNoctis (08-10-2009 um 13:31 Uhr)
|

08-10-2009, 14:53
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
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.
|

08-10-2009, 15:03
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Zitat:
Zitat von onemorenerd
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
|

09-10-2009, 11:32
|
unset
 Moderator
|
|
Registriert seit: Jan 2007
Ort: Düsseldorf
Beiträge: 3.778
|
|
Früher hab ich Enums verwendet, mitlerweile dann doch nur tinyints. Das meisste wird aber halt auch schon in den Modellen abgefackelt.
|

20-10-2009, 16:18
|
|
Quetschi
PHP Expert
|
|
Registriert seit: Dec 2004
Beiträge: 2.756
|
|
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.
|

28-10-2009, 09:45
|
 |
schmalle
  Ich Root, Du nix
|
|
Registriert seit: Jun 2001
Ort: Egelsbach FFM
Beiträge: 9.170
|
|
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.
|

28-10-2009, 13:59
|
|
Slava
PHP Senior
|
|
Registriert seit: Nov 2002
Ort: Köln->Karlsruhe
Beiträge: 1.583
|
|
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
|

28-10-2009, 14:21
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Zitat:
Zitat von Slava
tinyint(1) kann leider auch die werte von 2 bis 9 erhalten
|
Eben, daher halte ich das für absolut ungeeignet.
Zitat:
Zitat von Slava
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.
|

28-10-2009, 14:50
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Zitat:
Zitat von AmicaNoctis
Eben, daher halte ich das für absolut ungeeignet.
|
Die Werte 2-9 sind in PHP auch true.
|

28-10-2009, 14:53
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Zitat:
Zitat von onemorenerd
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)?
|

28-10-2009, 15:26
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Zitat:
Zitat von AmicaNoctis
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.
|

28-10-2009, 16:04
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
Zitat:
Zitat von onemorenerd
Das kann man am Präfix des Spaltennamens erkennen.
|
Unzuverlässig.
Zitat:
Zitat von onemorenerd
Ich weiß, du willst es lieber direkt am Wert erkennen.
|
Nein, am Typ!
Zitat:
Zitat von onemorenerd
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:
Zitat von onemorenerd
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).
|

28-10-2009, 20:10
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Zitat:
Zitat von AmicaNoctis
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.
Zitat:
|
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 ...
|

29-10-2009, 14:39
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
* OT-Diskussion abgetrennt*
|

04-11-2009, 14:39
|
|
Slava
PHP Senior
|
|
Registriert seit: Nov 2002
Ort: Köln->Karlsruhe
Beiträge: 1.583
|
|
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.
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|