![]() |
Datenbank: MariaDB • Version: 5.5 • Zugriff über: UniDAC
Wie speichert ihr boolsche Werte in der DB?
Moin!
Ich mach mir immer wieder einen Kopf über die Frage, wie ich boolsche Werte am besten in einer DB-Tabelle speichere mit Blick auf Indizierbarkeit, Performance und lesbaren Delphi-Code. Einen dedizierten Bool-Typ gibt es bei MariaDB (MySQL) ja nicht. Drei Varianten fallen mir ein:
Delphi-Quellcode:
Alle drei Varianten werden innerhalb der DB als Integer abgebildet und lassen sich indizieren.
BoolVar:= (Fields.FieldByName('TheName').AsInteger > 0); { INT(1) }
BoolVar:= (Fields.FieldByName('TheName').AsString <> '0'); { ENUM('0','1') } BoolVar:= (Fields.FieldByName('TheName').AsInteger > 0); { TINYINT(1) } Daneben gäbe es noch den Feldtyp BIT(1), wobei ich keine Ahnung habe wie der intern abgebildet wird in der DB. Darum mal die Frage in die Runde: Wie macht ihr das so? Grüße Cody |
AW: Wie speichert ihr boolsche Werte in der DB?
Oft wird das ja so gemacht, das ein Wert True entspricht und alles andere ist False bzw. umgekehrt, also:
0 oder 1 oder -1 = True, alles andere False bzw. 0 oder 1 oder -1 = False, alles andere True Ich kann mir nie merken wie das jetzt genau war. Nur mal generelle Frage, macht ein Index der ja über einen bool-Wert gehen soll grundsätzlich Sinn (gibt ja nur zwei Werte)? Und falls das Sinn macht, würde ein solcher Index dann Sinn machen, wenn man das mit einem Integer nachbildet und sagt z.B. True alles <=0, False alles >0 oder so ähnlich? Denn dann können da ja alle möglichen Integer drin stehen, die Interpretation als True,False erfolgt dann ja nur in Anwendung? Was hilft da der Index? |
AW: Wie speichert ihr boolsche Werte in der DB?
Sagen wir mal so: In der Praxis macht sich ein Index über die "Pseudo-Bool-Felder" bemerkbar wenn ich eine WHERE-Klausel auf dieses Feld lege und eine größere Ergebnismenge bekomme. Man erkauft sich das aber mit dem Preis höherer Anforderungen der DB an das Hostsystem.
In meinem Fall speichere ich die Bool-Werte ja alle selber und kann da für mich festlegen, dass '0'=FALSE und '1'=TRUE ist. Zur Sicherheit mache ich aber (X<>'0')=TRUE. |
AW: Wie speichert ihr boolsche Werte in der DB?
Worauf willst Du denn mit der Frage hinaus?
Performance? Ressourcenverbrauch? ..? Das Thema Indizierung bspw. ist ein mageres Feld by Boolean Werten. Verwendet man normale Indizes, ergibt sich kaum ein Nutzen, da die Selektivität mehr oder weniger = 0 ist. 1 Mio Datensätze mit einem gleichverteilten Anteil von Booleanwerten ergeben als Selektionskriterium 500T Sätze True und 500T False. Das ergibt in der Praxis dann trotzdem einen Fullscan und damit keinen Performancegewinn, wohl aber Overhead bei der Indexverwaltung, nämlich Speicherplatz und Kosten bei Insert/Delete. Wichtiger scheint mir in dem Bereich eine einheitliche Handhabung, ideal systemübergreifend. Dann nimmt man sich aber u.U. wieder die Möglichkeit proprietäre Verfahren einzelner Hersteller nutzbringend einzusetzen. |
AW: Wie speichert ihr boolsche Werte in der DB?
Im Interbase habe ich für Boolean eine Domain angelegt und den Feldern zugewiesen:
Code:
Damit sind nur die Werte 0 oder 1 möglich.
CREATE DOMAIN DBOOLEAN AS SMALLINT DEFAULT 0 NOT NULL CHECK (value in (0,1))
Ein Index auf Boolean-Felder macht nur Sinn, wenn die Gesamtmenge der auszuwertenden Daten damit wirklich erheblich eingeschränkt wird. z.B. Die Tabelle enthält 10000 Datensätze, davon 100 neue Datensätze (mit einem Boolean-Feld gekennzeichnet), die weiter verarbeitet werden müssen. Hier ist es aber wahrscheinlich sinnvoller auf das Boolean-Feld zu verzichten und dafür eine weitere Tabelle anzulegen, in der nur die ID der 100 Datensätze gespeichert wird. Für beliebig viele unterschiedliche Boolean-Felder müsste man diese Tabelle um ein Feld TYP ergänzen. |
AW: Wie speichert ihr boolsche Werte in der DB?
in einer Online-Vorlesung zu In-Memory Datenbanken am HPI Potsdam hat Hasso Plattner (SAP) zu diesem Thema referiert und präferiert die Lösung, statt eines Status (true/false) lieber einen Zeitstempel zu speichern. Dann hat man zusätzlich noch die Information, wann sich der Status geändert hat. Verbunden mit einem INSERT ONLY (=>
![]() |
AW: Wie speichert ihr boolsche Werte in der DB?
Nun ganz so platt ist das Beispiel ja nicht, und wenn man ehrlich ist, dann wird über das vorhandensein eines Datums ein Bool-Wert erzeugt. Wobei das Konzept für Daten mit einem zeitlichen Gültigkeitsbereich durchaus seinen Reiz hat.
Gruß K-H |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
P.S.: Hab mir auch mal deinen Blogeintrag durchgelesen. Das erinnert mich doch sehr an die Historienverwaltung, in einer Payroll-Software um die herum wir viel arbeiten. |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
|
AW: Wie speichert ihr boolsche Werte in der DB?
hmm
Bei SQLite auf iOS & Android habe ich mir eine Classe erzeugt die alle Bool-Werte kapselt und in einem einzigen String speichert. (weniger Speicher) Nach dem Motto "JJJNNNJJJNJNJNJNJNJNJJJJJJ" Die Felddefinition erzeugt ein Dictionary mit den Feldnamen und kennt die Position im String. Sehr praktisch. Checkbox.Checked := MySQLite.GetBool('Einstellung1'); Mavarik |
AW: Wie speichert ihr boolsche Werte in der DB?
SQL-Server bietet bit-Felder an, die intern als Byte abgelegt werden, allerdings so, das immer 8 bit-Felder eines Datensatzes in ein Byte passen. Man bekommt also 7 bits geschenkt, wenn man ein bit anlegt. Wieso man einen Mehrwert haben sollte, wenn ich das als Zeitstempel umsetze, erschließt sich mir nicht. Wenn ich eine Historienverwaltung brauche, lege ich sie an.
Was hab ich davon, das ich weiß, das die Option 'HatdieHosenAn' gestern um 17:30 gesetzt wurde, aber die Information 'Durchmesser des Nudelholzes' zwar auf 36cm steht (echt ne fiese Sache, so eine Ehe), aber ich dummerweise nicht weiss, wann diese doch sozusagen systemimmanente Wert von vormals 3cm hochgesetzt wurde. Dessenungeachtet ist es schon etwas merkwürdig, beim Feldnamen 'IstNachtaktiv' einen Zeitstempel zu sehen: Bedeutet das: 'Ist nachtaktiv ab ....?' oder bis? Nee, also Ich kann mir auch von hinten durch die Brust ins Auge schießen. Zurück zum Thema: Wenn die DB keine Bits unterstützt, dann würde ich die ansonsten kleinste Einheit nehmen, also char(1), smallint etc. Die Sache mit den Constraints ist nett, frist zwar ein wenig Performance, aber WTF, außerdem ist das dann so sauber. Nebenbei: Ebenso wie in der Programmierung ist es häufig so, das aus zwei Zuständen rasch mehr werden... Und insofern ist ein smallint gar nicht mal so blöd. Fängt schon beim Geschlecht an. Vor 30 Jahren reichte ein Bit: IstWeiblich Ja/nein (Wir sind ja schön gequotet). Aber heutzutage benötigt man schon etwas mehr Optionen, um das Geschlecht anzugeben (Weiblich, Männlioh, weiß noch nicht, bin gerade am umbiegen, beides, weder noch, da Politiker etc.). |
AW: Wie speichert ihr boolsche Werte in der DB?
@Furtbichler sorry für OT, aber bei Deiner Antwort merkt man dass es Frühling wird ...
|
AW: Wie speichert ihr boolsche Werte in der DB?
Das Timestamp-Konzept leuchtet mir allerdings auch nicht wirklich ein, vor allem, wenn NULL als false interpretiert werden soll. Auf diese Weise kann man dann zwar ermitteln, wann der Status zu true gewechselt ist, aber nicht andersherum, da ja dann NULL im Feld steht. Ich selbst mache das meist so wie von Blup skizziert, indem ich eine Boolean-Domäne anlege, die benutzt dann den kleinsten ganzzahligen Typen, den die DB anbietet.
|
AW: Wie speichert ihr boolsche Werte in der DB?
Hallo,
Zitat:
Mir geht es da wie DeddyH, erschließt sich mir nicht wirklich.... Ich verwende für Boole'sche Informationen Smallint-Felder mit 0 für False und 1 für True, wobei nur auf <> 0 geprüft wird (Firebird 2.5.2). Firebird 3 soll ja Boole'sche Felder direkt unterstützen, aber bis dahin ist wohl noch lang hin. Grüße Frank |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
|
AW: Wie speichert ihr boolsche Werte in der DB?
Nemen wir das Nudelholz, das ist so schön schief
id name Durchmesser durchmesser_alt_erledigt
Wenn Du ein Nudelholz hast, gibt es auch einen Durchmesser (<>null), ohne Durchmesser soll es erst noch gekauft werden. Ist Durchmesser_alt_erledigt belegt, dann gibt es das Nudelholz nicht mehr (frag Furtbichler wo's ist) Wenn man dafür dann ein Datumsfeld/Timestamp nimmt, dann weiß man von wann bis wann man das Nudelholz gehabt hat. Oder anders herum: IchbinNudelholzeigentümer:=(durchmesser <> null) and (durchmesser_alt_erledigt = null) ich_hatte_mal_EIN_nudelholz:=(durchmesser<>null) and (durchmesser_alt_erledigt <> null) Gruß K-H |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
Da wäre ein Test "sum(alleBuchungsbeträge) = 0" besser, und wenn es mehrere Teilzahlungen waren, braucht man sowieso bei jeder Zahlung einen Timestamp. |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
Und ja, es kommt in der Praxis durchaus mal vor, das man einen bool explizit noch nicht gesetzt haben darf, da der Business-Case z.B. sowohl für das Ja als auch das Nein eine bewusste Entscheidung des Users voraussetzt. Solange die nicht da ist, ist es eben undefined. |
AW: Wie speichert ihr boolsche Werte in der DB?
Also nach meinen Erfahrungen nach kommt es recht häufig vor, dass später weitere Zustände ausser True und False benötigt werden.
Deshalb verwende ich immer meistens ein BYTE (0..255) als Booleanfeld. Beispiel 1: Splashscreen_aktive: True oder False. Später fällt mir dann ein, dass ich den Splashscreen nicht aktivieren möchte, wenn die Anwendung auf einem Terminalserver läuft; es soll aber einstellbar sein. Und schon sind es 3 Zustände... Beispiel 2: Kundensperre (z.B. weil der Kunde im Zahlungsrückstand ist). Könnte man ja meinen dass True oder False ausreichend sind. Später möchte man aber genauer wissen weshalb der Kunde gesperrt ist (Insolvent, Zahlungsrückstand, Gerichtsverfahren anhängig, ...) und schon braucht man wieder mehr Zustände. Deshalb jedes Booleanfeld genau überprüfen und vorrausplanen ob nicht ein Bytefeld besser passt. |
AW: Wie speichert ihr boolsche Werte in der DB?
Hallo,
für mich ergibt das nur Sinn, wenn sichergestellt ist, dass das Feld mit dem Timestamp nie wieder geändert werden kann (da ja sonst die Information verlorenginge), insofern hat joachimd das schon richtiggestellt. Wenn das Feld wieder geändert werden kann, muss man eben die bisher bekannten Datentypen verwenden (smallint, char, usw. usf). Gruß Frank |
AW: Wie speichert ihr boolsche Werte in der DB?
Nicht in allen Fällen ist es ratsam, als Repräsentant für ein Boolean-Feld die kleinste verfügbare Einheit zu nehmen. So erwarten die IbDac-Komponenten von Devart einen Integer. Mit einem SmallInt, der z.B. bei den FibPlus-Komponenten funktionierte, tritt bei Verwendung von IbDac eine Fehlermeldung auf bzw. wird dieses Feld nicht als Boolean erkannt. Der String "Boolean" muß im Feldnamen vorkommen, bei Firebird z.B.:
Code:
CREATE DOMAIN INTBOOLEAN AS
INTEGER DEFAULT 0 NOT NULL CHECK (VALUE IN (0,1)); COMMENT ON DOMAIN INTBOOLEAN IS 'Boolean False oder True'; |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
Also legt man diese Zusatzinformationen in eine eigene Tabelle und prüft, ob es dort Einträge gibt, und wenn ja, ob diese auf die aktuelle Situation passen. SplashDisable
Kunden
Das Beispiel mit den Rechnungen verhält sich ähnlich Rechnungen
Den Boolean-Wert für RechnungBezahlt bekommt man also durch die Analyse der entsprechenden Tabelle. |
AW: Wie speichert ihr boolsche Werte in der DB?
Hallo,
Perlsau meint vermutlich, dass Smallint in Verbindung mit Domäne in Firebird über IBDAC nicht funktioniert. Als normale Spalte vom Typ "Smallint", in der 0 oder 1/-1 gespeichert werden, gibt es keine Probleme. Gruß Frank |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
|
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
Manche Versender geben Kunden mit negativer Schufaauskunft auch eine eingeschränkte Kundensperre und verschicken z.B. nur per Nachnahme. Ein Sperrfeld in der Kundentabelle ist absolut sinnvoll und muss mehr Informationen tragen können als nur True oder False. |
AW: Wie speichert ihr boolsche Werte in der DB?
Sorry, wenn ich mich hier als völlig DB.Außenstehender einmische:
Wer ein "Falsch" nicht als Nil/Null/0 wegschreibt, sollte seine Existenzbeschreibung überdenken. Ob man ein plus1 oder minus1 als "Zutreffend/Richtig/Wahr" interpretiert, scheint mir im Auge des *perversen* Betrachters zu liegen: Frage: "Sammeln Sie Kinderpornos?" Antwort: "Nie und Nimmer!" Also minus1 statt null? Alles klar? |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
|
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
Insolvenz, Schufa, etc. -> Bar, Nachnahme Doofmann -> gar nicht In der Kundentabelle selber fehlt auch die Möglichkeit einer reinen Sperr-Historie. Irgendwie machbar, aber umständlich und gehört irgendwie nicht so zusammen wie die Firmierung und die Handelsregister-Nummer. |
AW: Wie speichert ihr boolsche Werte in der DB?
Zitat:
17.13.1.8.2.2 BooleanDomainFields Property Used to create TBooleanField for fields that have domain of the integer data type, and the domain name contains 'BOOLEAN'. Class: TIBCDataSetOptions Syntax: property BooleanDomainFields: boolean default False; Remarks: If the BooleanDomainFields property is set to True, TBooleanField objects are created for fields that have domain of the integer data type, and the domain name contains 'BOOLEAN'. |
AW: Wie speichert ihr boolsche Werte in der DB?
Da Du ja MySQL bzw. MariaDB verwendest, kann ich Dir vllt. sagen wie ich das bei MySQL 5.1 mit UniDAC handhabe.
Ich erstelle meine DB-Modelle mit MySQL Workbench. Da kannst Du durchaus "BOOLEAN"-Typen anlegen. Die werden in der Datenbank auf TINYINT(1) Felder gemappt. Das finde ich legitim und habe das bisher immer so verwendet. Wenn Du BIT(1) verwendest ist das Anzeigen der Werte schwierig, da ![]() Mit UniDAC sollte auch ein
Delphi-Quellcode:
kein Problem sein.
Field.AsBoolean
![]() Viele Grüße |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz