Welcher MySQL-Datentyp zum Speichern von Booleschen Werten verwendet werden soll


1207

Da MySQL keinen 'booleschen' Datentyp zu haben scheint, welchen Datentyp 'missbrauchen' Sie, um wahre / falsche Informationen in MySQL zu speichern?

Besonders im Zusammenhang mit dem Schreiben und Lesen von / zu einem PHP-Skript.

Im Laufe der Zeit habe ich verschiedene Ansätze verwendet und gesehen:

  • tinyint, varchar Felder mit den Werten 0/1,
  • Varchar-Felder mit den Zeichenfolgen '0' / '1' oder 'true' / 'false'
  • und schließlich Felder auflisten, die die beiden Optionen 'true' / 'false' enthalten.

Keines der oben genannten scheint optimal zu sein. Ich bevorzuge eher die tinyint 0/1-Variante, da die automatische Typkonvertierung in PHP mir ziemlich einfach boolesche Werte liefert.

Welchen Datentyp verwenden Sie? Gibt es einen Typ für boolesche Werte, den ich übersehen habe? Sehen Sie Vor- oder Nachteile bei der Verwendung des einen oder anderen Typs?


217
Jeder, der die alten Antworten auf diese Frage liest, muss verstehen, dass MySQL in Version 5 einen Bit-Datentyp hinzugefügt hat. Verwenden Sie diese Informationen nach Belieben. dev.mysql.com/doc/refman/5.0/en/bit-type.html
smp7d


7
Für die aktuelle Version von MYSQL ist der boolesche Typ verfügbar. dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html Überprüfen Sie dies. nach diesem Wert Null als falsch betrachtet
DevT

7
bit(1)Ein Bit ** zum Importieren in Excel. Umschalten auf tinyint(1)funktioniert.
Cees Timmerman

8
Jetzt haben wir Boolean nach 5 Jahren
V-SHY

Antworten:


1232

Für MySQL 5.0.3 und höher können Sie verwenden BIT. Das Handbuch sagt:

Ab MySQL 5.0.3 wird der BIT-Datentyp zum Speichern von Bitfeldwerten verwendet. Eine Art von BIT (M) ermöglicht die Speicherung von M-Bit-Werten. M kann zwischen 1 und 64 liegen.

Andernfalls können Sie laut MySQL-Handbuch bool und boolean verwenden, die derzeit Aliase von tinyint (1) sind:

Bool, Boolean: Diese Typen sind Synonyme für TINYINT (1). Ein Wert von Null wird als falsch betrachtet. Werte ungleich Null werden als wahr angesehen.

MySQL gibt außerdem Folgendes an:

Wir beabsichtigen, in einer zukünftigen MySQL-Version die vollständige Behandlung boolescher Typen gemäß Standard-SQL zu implementieren.

Referenzen: http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html


11
Ja, ich würde entweder dies oder ein CHAR (1) wählen und je nach Kontext 'Y' / 'N' oder 'T' / 'F' usw. speichern. Der Vorteil der Verwendung eines kleinen Integer-Typs besteht darin, dass Sie maximale Portabilität über RDBMS-es erhalten
Roland Bouman

36
Wenn Sie sich zumindest in PHP für char entscheiden, wird dies zu mehr Code führen, der !$booleanohne weitere Verarbeitung niemals richtig ausgewertet wird.
Mild Fuzz

10
@Pecerier Nichts, was du nicht selbst googeln könntest, aber ok, ich werde beißen. Schauen Sie sich zunächst zunächst data0type.h an. Bitte beachten Sie, dass innodb dort keinen BIT-Typ nativ definiert. Wenn es BIT-Felder so behandeln würde, wie Sie es beschreiben, würden wir dort sicherlich einen Hinweis auf seine Existenz finden. Zweitens lesen Sie mysqlperformanceblog.com/2008/04/23/… . Und zögern Sie nicht, uns zu erklären, welche erstaunlichen MySQL-Clients im "marktetplace" gut mit BIT-Feldern spielen. Sie werden für jeden nützlich sein, der diesen Artikel ohne Zweifel verpasst hat.
Roland Bouman

9
Wenn ich eine Auswahl aus den Standard-MySQL-Befehlszeilen-Client-Bitfeldern mache, werden diese vollständig leer angezeigt. Aus diesem Grund bevorzuge ich TINYINT (1).
Benutzer

8
@ MikePurcell Ich hasse es zu fragen, aber warum sollten Sie auto_incrementeine Spalte verwenden, die einen booleschen Wert darstellt?
Chris Hayes

248

BOOLund BOOLEANsind Synonyme von TINYINT(1). Null ist false, alles andere ist true. Weitere Informationen hier .


7
Das (1)macht nichts weiter als zu bestimmen, wie der Wert angezeigt wird. Wenn Sie sich der Speichergröße bewusst sind, möchten Sie BITstattdessen verwenden
JamesHalsall

35
@ JamesHalsall: Eigentlich BIT(1)und TINYINT(1)beide verwenden ein Byte Speicher. Bis MySQL 5.0.3 BITwar eigentlich ein Synonym für TINYINT. Spätere Versionen von MySQL haben die Implementierung von BIT geändert. Aber selbst mit der Implementierungsänderung gibt es für den BITDatentyp immer noch keinen Vorteil der "Speichergröße" (zumindest bei InnoDB und MyISAM; andere Speicher-Engines, z. B. NDB, haben möglicherweise eine Speicheroptimierung für mehrere BIT-Spaltendeklarationen.) Das größere Problem ist, dass einige Clients Bibliotheken erkennen zurückgegebene BITDatentypspalten nicht oder behandeln sie nicht angemessen . A TINYINTfunktioniert besser.
Spencer7593

5
Das Handbuch zu MySQL 5.0 besagt eindeutig, dass ein boolescher Wert entweder 1 oder 0 ist. Der Ausdruck "alles andere ist true" ist nicht wahr.
Walter

7
@Walter: Es ist eigentlich irgendwie wahr, die Erklärung fehlt etwas. Kurz gesagt, in einem booleschen Kontext kann ein Ausdruck NULL, FALSE oder TRUE ergeben. In einer MySQL-Anweisung wird ein in einem booleschen Kontext ausgewerteter Ausdruck zuerst als Ganzzahl ausgewertet (Dezimal- und Gleitkommawerte werden gerundet, Zeichenfolgen werden auf die übliche eigenartige Weise konvertiert, mit der MySQL Zeichenfolgen in Ganzzahlen konvertiert). Ein NULL ist offensichtlich NULL (weder WAHR noch FALSCH). Ein ganzzahliger Wert von 0 wird als FALSE behandelt, und jeder andere ganzzahlige Wert (1, 2, -7 usw.) wird als TRUE ausgewertet. Aus Kompatibilitätsgründen ahmen wir die Logik / Handhabung von TINYINT boolean
spencer7593 am

4
@Walter: Das ist einfach zu testen, zB SELECT 'foo' AS bar FROM dual WHERE -7. Der Ausdruck -7 wird in einem booleschen Kontext ausgewertet, und die Abfrage gibt eine Zeile zurück. Wir können mit 0 oder einem beliebigen Ausdruck testen, der den ganzzahligen Wert 0 ergibt, und es wird keine Zeile zurückgegeben. Wenn der Ausdruck in der WHERE-Klausel einen anderen ganzzahligen Wert ungleich Null als Null ergibt, ist der Ausdruck TRUE. (Ich glaube, Dezimal- und Gleitkommawerte werden auf Ganzzahl "gerundet", z . B. WHERE 1/3auf WHERE 0. Wir erhalten das gleiche Ergebnis mit WHERE 'foo', da Zeichenfolge 'foo'auch auf Ganzzahlwert 0 ausgewertet wird.
spencer7593

71

Dies ist eine elegante Lösung, die ich sehr schätze, da sie keine Datenbytes verwendet:

some_flag CHAR(0) DEFAULT NULL

Um es auf true zu setzen, setze some_flag = ''und um es auf false zu setzen, setze some_flag = NULL.

Um dann auf true zu testen, überprüfen Sie, ob some_flag IS NOT NULLund um auf false zu testen, überprüfen Sie, ob some_flag IS NULL.

(Diese Methode wird in "Hochleistungs-MySQL: Optimierung, Backups, Replikation und mehr" von Jon Warren Lentz, Baron Schwartz und Arjen Lentz beschrieben.)


3
ausgefallener Trick! Dies ist hilfreich, wenn Sie mit MySQL <5 arbeiten und möglicherweise sogar einen geringeren Platzbedarf als BIT haben. Um jedoch die Konvention einzuhalten und den Rechenaufwand etwas zu verringern (Logik vs. exakter Wert), würde ich sagen, dass BIT der bessere Weg ist.
Zamnuts

59
Könnte 'schnell' sein, aber es verschleiert die Daten so, dass jeder neue Entwickler keine Ahnung hätte, wofür die Spalte steht.
Richthofen

5
Dies verwendet die gleiche Anzahl von Bytes wie BIT (1)
ITS Alaska

25
Viel Glück, dass ein ORM dies gut abbildet.
Craig Labenz

4
Ich stimme @Richthofen zu und kann mir kaum eine Situation vorstellen, in der ich jemals die Verwendung dieser Lösung befürworten würde. Wenn es jedoch verwendet werden soll, kann die Angabe als a COMMENTin der Definition der Spalte, NULLdie false und ''true angibt, einen sehr kleinen Beitrag zur Unterstützung des zukünftigen Verständnisses leisten.
Eggyal

34

Wenn Sie den Typ BOOLEAN verwenden, ist dies auf TINYINT (1) ausgerichtet. Dies ist am besten, wenn Sie standardisiertes SQL verwenden möchten und nicht bedenken, dass das Feld einen Wert außerhalb des Bereichs enthalten kann (im Grunde ist alles, was nicht 0 ist, "wahr").

Mit ENUM ('False', 'True') können Sie die Zeichenfolgen in Ihrem SQL verwenden, und MySQL speichert das Feld intern als Ganzzahl, wobei 'False' = 0 und 'True' = 1, basierend auf der Reihenfolge, in der die Aufzählung angegeben ist .

In MySQL 5+ können Sie ein BIT (1) -Feld verwenden, um einen numerischen 1-Bit-Typ anzugeben. Ich glaube nicht, dass dies tatsächlich weniger Speicherplatz im Speicher beansprucht, aber Sie können die möglichen Werte wieder auf 1 oder 0 beschränken.

Alle oben genannten Funktionen belegen ungefähr die gleiche Speichermenge. Wählen Sie daher am besten diejenige aus, mit der Sie am einfachsten arbeiten können.


8
Ihre Bemerkung zu ENUM ist nicht wahr: Versuchen Sie CAST (yourenumcol AS UNSIGNED) und Sie werden feststellen, dass False 1 und True 2 ist. Ein weiteres Problem mit ENUM ist, dass es zu einfach ist, '' (leere Zeichenfolge) einzufügen ). Ich würde es nicht empfehlen, dies zu verwenden.
Roland Bouman

4
Nach meiner Erfahrung war die Verwendung eines BIT (1) -Felds aus PHP-Code etwas mühsam. TINYINT (1) war viel einfacher und erzeugte besser lesbaren Code.
M-Peror

1
@ M-Peror - "Die Verwendung eines BIT (1) -Feldes aus PHP-Code war etwas mühsam" ... kein Wortspiel beabsichtigt. :) Aber ja, ich stimme zu. Ich erinnere mich, dass TINYINT (1) auch einfacher war ... ich kann mich einfach nicht erinnern warum. Hat noch jemand Gedanken dazu? BIT (1) scheint auf der Oberfläche besser zu sein, da Sie es auf 0 oder 1 beschränken können. Ich denke, BIT wurde manchmal als Binärdaten interpretiert (abhängig von der Programmiersprache und dem Treiber / der Bibliothek). TINYINT wurde eher wie eine Zahl behandelt.
BMiner

2
@BMiner - haha, es war wirklich unbeabsichtigt, habe das nicht bemerkt :) Aber wenn ich mich richtig erinnere, wurde das Bitfeld als etwas Binäres interpretiert, während das tinyint leichter als Zahl zu behandeln war und aus diesem Grund leichter zu behandeln war Verwendung in einem (booleschen) Ausdruck.
M-Peror

34

Diese Frage wurde beantwortet, aber ich dachte, ich würde meine $ 0,02 einwerfen. Ich benutze oft ein CHAR(0), wo '' == true and NULL == false.

Aus MySQL-Dokumenten :

CHAR(0)ist auch sehr schön, wenn Sie eine Spalte benötigen, die nur zwei Werte annehmen kann: Eine Spalte, die als CHAR(0) NULLnur ein Bit belegt und nur die Werte NULLund ''(die leere Zeichenfolge) annehmen kann .


16
mm, das scheint um Ärger zu bitten, wenn Sie als ich. Ich meine, je nach Sprache kann es zu einfach sein, den Unterschied zwischen NULL und '' (zum Beispiel PHP) nicht zu erkennen.
Roland Bouman

3
In Bezug auf die Platzersparnis (die Anzahl der Bytes, die zur Darstellung eines Booleschen Werts verwendet werden) ist dieser Ansatz ein klarer Gewinner. Dies spart ein Byte über TINYINT. Der Nachteil (wie einige Kommentare hervorheben) ist, dass einige Clients möglicherweise Schwierigkeiten haben, zwischen einer NULL- und einer leeren Zeichenfolge zu unterscheiden. Selbst einige relationale Datenbanken (z. B. Oracle) unterscheiden nicht zwischen einer Zeichenfolge mit der Länge Null und einer NULL.
Spencer7593

3
Das ist sehr klug! Früher habe ich cleveren Code geschrieben, jetzt vermeide ich ihn wie die Pest. Ich möchte jetzt, dass mein Code eine kristallklare Absicht hat und nicht nur korrektes Verhalten. Mein Rat? Tun Sie dies nur, wenn Sie jemanden verwirren möchten, der den Code / die Datenbank unterstützen muss. Zum Beispiel in PHP sind beide ''und nullfalsche Werte.
CJ Dennis

1
@CJDennis Wenn Sie Ihre Datenbankebene hinter dem Repository-Muster abstrahiert haben, müssen Sie sich keine Sorgen über die Unklarheit dieser Lösung machen.
Programmierer


17

Bit ist gegenüber den verschiedenen Byteoptionen (tinyint, enum, char (1)) nur dann von Vorteil, wenn Sie viele boolesche Felder haben. Ein Bitfeld nimmt immer noch ein volles Byte ein. Zwei Bitfelder passen in dasselbe Byte. Drei, vier, fünf, sechs, sieben, acht. Danach füllen sie das nächste Byte auf. Letztendlich sind die Einsparungen so gering, dass Sie sich auf Tausende anderer Optimierungen konzentrieren sollten. Wenn Sie nicht mit einer enormen Datenmenge zu tun haben, summieren sich diese wenigen Bytes nicht zu viel. Wenn Sie Bit mit PHP verwenden, müssen Sie die ein- und ausgehenden Werte typisieren.


1
+1 für den Typecasting-Kommentar. Um dies bei der Arbeit mit Programmiersprachen zu ergänzen, vermeiden Sie die Verwendung fauler Programmiertechniken zugunsten der Konsistenz. Verwenden Sie identische Operatoren anstelle von nur gleich. Im Fall von PHP ist if ($ var == "") wahr für 0, false, null, undefined und "". Um alle Werte zu testen, ist es oft am besten, if (true === empty ($ var)) zu verwenden, da dadurch auch die undefinierten Fehler vermieden werden. Sie sollten auch den Datentyp überprüfen, mit dem Sie arbeiten, wenn (is_int ($ var) && $ var === 0), oder ihn typisieren, um zu erzwingen, dass er ein bestimmter Datentyp (int) $ var für die Aufgabe ist.
Fyrye

@Thor gilt dies für MySQL in demselben Maße wie für MSSQL? Ich migriere eine neue Anwendung, die noch nicht in Produktion gegangen ist, von MSSQL auf MySQL. Ich verwende kein PHP, sondern konvertiere C # in Java 8. Da Java eine stark typisierte Sprache ist, mache ich mir keine Sorgen um die Typbehandlung ... nur alle Bit-Flags, die von einem Byte für bis zu 8 Flags nach verschoben würden 1 Byte pro Flag mit TINYINT (1). Kennen Sie eine Dokumentation zu diesem Thema für MySQL?
Zack Jannsen

1
@Thor Bei tieferen Recherchen ist klar, wie die Antwort lauten sollte. Es kommt zu Veränderungen, und wir haben Verbesserungen bei dieser Handhabung festgestellt. Kennen Sie Ihre Sprache, die sich in der Anwendungsschicht / Datenzugriffsschicht befindet, und kennen Sie die Unterstützung Ihrer Bibliotheken. Ich verwende derzeit Java und BIT (1) ist derzeit die empfohlene Wahl für Bibliotheken wie Hybernate und die Verwendung von JDBC. Hier ist die URL [Siehe Tabelle 5.2]: dev.mysql.com/doc/connector-j/en/…
Zack Jannsen

12

Bis MySQL einen Bit-Datentyp implementiert, erstellen Sie ein TINYINT-Feld, das bit_flagsfür alle Ihre booleschen Variablen aufgerufen wird, und maskieren und verschieben Sie das gewünschte boolesche Bit in Ihrem SQL , wenn Ihre Verarbeitung wirklich räumlich und / oder zeitlich unter Druck steht, z. B. bei Transaktionen mit hohem Volumen Abfrage.

Wenn beispielsweise Ihr Bit ganz links Ihr Bool-Feld darstellt und die 7 Bits ganz rechts nichts darstellen, entspricht Ihr bit_flagsFeld 128 (binär 10000000). Maskieren (verbergen) Sie die sieben Bits ganz rechts (mit dem bitweisen Operator &) und verschieben Sie das 8. Bit sieben Leerzeichen nach rechts, bis 00000001. Jetzt ist die gesamte Zahl (in diesem Fall 1) Ihr Wert.

SELECT (t.bit_flags & 128) >> 7 AS myBool FROM myTable t;

if bit_flags = 128 ==> 1 (true)
if bit_flags = 0 ==> 0 (false)

Sie können solche Anweisungen beim Testen ausführen

SELECT (128 & 128) >> 7;

SELECT (0 & 128) >> 7;

usw.

Da Sie 8 Bits haben, haben Sie möglicherweise 8 boolesche Variablen aus einem Byte. Einige zukünftige Programmierer verwenden ausnahmslos die nächsten sieben Bits, daher müssen Sie maskieren. Verschieben Sie nicht einfach, sonst schaffen Sie in Zukunft die Hölle für sich und andere. Stellen Sie sicher, dass MySQL Ihre Maskierung und Verschiebung vornimmt - dies ist erheblich schneller als die Web-Skriptsprache (PHP, ASP usw.). Stellen Sie außerdem sicher, dass Sie einen Kommentar in das MySQL-Kommentarfeld für Ihr bit_flagsFeld einfügen .

Diese Websites sind bei der Implementierung dieser Methode hilfreich:


7
Dies scheint nur ein schrecklicher Weg zu sein, um die Absicht zukünftiger Programmierer zu verschleiern. Sicher scheint es eine Menge Mühe zu geben, 7 Bytes zu sparen (vorausgesetzt, Sie verwenden alle 8 Bools in dieser einzelnen Tabelle!)
yep

@yep gibt es überhaupt keine Verschleierung! Schreiben Sie Dokumentation und MySQL- Kommentare, in denen jedes Feld in der Tabelle erläutert wird (wie in der Antwort erwähnt)! Die vorgeschlagene MySQL-Demaskierungsstrategie sieht solide aus und das Speichern von bis zu 16 verschiedenen booleschen Feldern mit nur wenigen Spalten ist besser als 16 davon. Wenn es mit der Bitmanipulation zu verwirrend ist und Sie es vorziehen, Ihre Web-Skriptsprache zu verwenden, um jeden Booleschen Wert zu erhalten, speichern Sie ihn einfach als VARCHARund führen Sie die Demaskierungsprozedur im Code aus (Sie müssen ihn auch nicht auf 8 Felder beschränken). ...
CPHPython


10

Ich hatte es satt, Nullen, Nullen und '' genau um eine Schleife von PHP-, MySql- und POST-Werten zu runden, also benutze ich einfach 'Ja' und 'Nein'.

Dies funktioniert einwandfrei und erfordert keine spezielle Behandlung, die nicht offensichtlich und einfach durchzuführen ist.


17
Wenn Sie wirklich so viel Platz verschwenden und die Leistung beeinträchtigen möchten, hätten Sie zumindest CHAR (1) mit den Optionen Y und N ausführen können.
ILikeTacos

3
In den meisten Situationen der realen Welt gibt es einen echten Unterschied zwischen einem Nein und einem bloßen Fehlen von Informationen. Beispielsweise möchten Sie möglicherweise standardmäßig ein Kontrollkästchen aktivieren, wenn ein Benutzer noch nicht "Nein" gesagt hat. Genau wie viel Platz sparen Sie Ihrer Meinung nach und wie viel verarbeiten Sie jedes Mal, wenn Sie zwischen falsch und NULL unterscheiden müssen - wenn Sie tatsächlich überhaupt unterscheiden können? In einer Welt gespeicherter Bilder und digitaler Videos ist das ein oder andere bisschen Platzersparnis völlig irrelevant, aber die Klarheit und reduzierte Verarbeitung sind real.
Geoff Kendall

8
Diese Antwort ist nicht falsch, weil sie funktionieren wird und nicht so schlecht ist, wie die Leute es glauben. Für die meisten Projekte (dh: Tabellengrößen <1 Mio. Zeilen) sind die Leistungsunterschiede zwischen den bereitgestellten Lösungen vernachlässigbar. Ich werde mich nicht beschweren, wenn meine Anfragen in 7 oder 5 Millisekunden zurückkehren ... Um fair zu sein, wenn Ihre Tabellen in die 10-mil-Zeilen oder mehr hineinwachsen, ist dies wahrscheinlich nicht die bevorzugte Lösung.
Brad

1
+1 von mir für die Verwendung des Datentyps ENUM. Ich persönlich bevorzuge diese Notation: ENUM ('y', 'n'). Es ist kompakt (nur ein Byte lang), intuitiv und sieht als Konvention auf Anwendungsebene für alle booleschen Flags gut aus. Sie können es direkt mit HTML-Formularfeldern verwenden. Zum Beispiel mit PHP: <select name = "Production"> <option value = "y" <? = $ Production === 'y'? 'selected = "selected"': ''? >> Ja </ option> <option value = "n" <? = $ Production === 'n'? 'selected = "selected"': ''? >> Nein </ option> </ select>
Vlado

2
Lol das hat mein Auge gefesselt, aber ich muss sagen, @GeoffKendall ist richtig. In einer Vielzahl von Fällen besteht keine Notwendigkeit für eine optimale Leistung, und welche Methode auch immer die Aufgabe für Sie erledigt, ist die richtige Methode.
Madmenyo

6

Unter Bezugnahme auf diesen Link Boolescher Datentyp in MySQL ist je nach Anwendungsnutzung Bit (1) die bessere Wahl, wenn nur 0 oder 1 gespeichert werden sollen.


6
Es ist wahr, dass BIT(1)nur ein b'0'oder b'1'Wert gespeichert werden kann. Das größte Problem mit dem BITDatentyp ist, dass verschiedene Client-Bibliotheken eine unterschiedliche Wonky-Behandlung des Datentyps haben. Überprüfen Sie das Verhalten in verschiedenen SQL-Tools (SQLyog, TOAD für MySQL, SQL Developer), Tools, die Datenbankmodelle "zurückentwickeln", und verschiedenen Clients wie JDBC, PHP, Perl DBI und testen Sie einige ORM-Frameworks ( Ruhezustand, Mybatis, JPA). In Bezug auf Benutzerfreundlichkeit, Tool- / Framework-Kompatibilität / native Unterstützung TINYINT(1)ist der klare Gewinner.
Spencer7593

Ja. Die Fertigstellung hängt vom Framework ab, das für die App in Betracht gezogen wird. Zum Beispiel verarbeitet das
Phalcon-

Für die Aufzeichnung unterstützt MyBatis sowohl BITals auch TINYINT. Siehe MyBatis JdbcType-Klasse, mybatis.org/mybatis-3/apidocs/reference/org/apache/ibatis/type/…
Lucky

1
@Vidz Ich gebe Ihnen plus eins für die Erwähnung von BIT (1), möchte aber auch die Entwickler darauf hinweisen, die dies lesen - Kennen Sie Ihre Sprache, die sich in der Anwendungsschicht / Datenzugriffsschicht befindet, und kennen Sie die Unterstützung Ihrer Bibliotheken. Ich verwende derzeit Java und BIT (1) ist derzeit die empfohlene Wahl für Bibliotheken wie Hybernate und die Verwendung von JDBC. Hier ist die URL [Siehe Tabelle 5.2]: dev.mysql.com/doc/connector-j/en/…
Zack Jannsen

6

Da sowohl MySQL (8.0.16) als auch MariaDB (10.2.1) die CHECK-Einschränkung implementiert haben, würde ich jetzt verwenden

bool_val TINYINT CHECK(bool_val IN(0,1))

Sie werden nur zum Speichern der Lage sein 0, 1oder NULL, sowie Werte, die umgerechnet werden kann 0oder 1ohne Fehler wie '1', 0x00, b'1'oder TRUE/ FALSE.

Wenn Sie keine NULL-Werte zulassen möchten, fügen Sie die NOT NULLOption hinzu

bool_val TINYINT NOT NULL CHECK(bool_val IN(0,1))

Beachten Sie, dass es praktisch keinen Unterschied , wenn Sie verwenden TINYINT, TINYINT(1)oder TINYINT(123).

Wenn Sie möchten, dass Ihr Schema aufwärtskompatibel ist, können Sie auch BOOLoder verwendenBOOLEAN

bool_val BOOL CHECK(bool_val IN(TRUE,FALSE))

db <> Geigen-Demo


was ist mit enum (0, 1)
santiago arizti

3
@santiagoarizti ENUM(es muss sein enum('0', '1')- beachten Sie: das sind Zeichenfolgen) ist keine gute Idee. Es gibt zu viele Probleme aufgrund der internen Speicherung und der Behandlung von Nicht-String-Werten. Z.B. 0und FALSE kann nicht gespeichert werden. 1und TRUEwerden '0'. Und 2wird '1'.
Paul Spiegel

Beste Antwort ... für diejenigen, die MySQL 8+ verwenden
Dolmen

2

Nachdem ich die Antworten hier gelesen hatte, entschied ich mich zu verwenden bit(1)und ja, es ist irgendwie besser in Raum / Zeit, ABER nach einer Weile habe ich meine Meinung geändert und ich werde es nie wieder verwenden. Es hat meine Entwicklung sehr erschwert, wenn ich vorbereitete Anweisungen, Bibliotheken usw. (php) verwendet habe.

Seitdem benutze ich immer tinyint(1), scheint gut genug.


3
Möchten Sie erklären, inwiefern dies Ihre Entwicklung erschwert hat?
Chazy Chaz

@ChazyChaz erwartet im Gegensatz zu einigen anderen Datenbanken wie SQL Server true / false anstelle von 1/0. Dies kann manchmal zu seltsamen Situationen führen, in denen Sie glauben, dass Sie es auf wahr setzen, aber es passiert nicht wirklich.
Maembe

0

Sie können den Datentyp BOOL, BOOLEAN zum Speichern von Booleschen Werten verwenden.

Diese Typen sind Synonyme für TINYINT (1)

Der Datentyp BIT (1) ist jedoch sinnvoller, um einen booleschen Wert (entweder true [1] oder false [0]) zu speichern. TINYINT (1) ist jedoch einfacher zu verarbeiten, wenn Sie Daten ausgeben, abfragen usw. ein und um Interoperabilität zwischen MySQL und anderen Datenbanken zu erreichen. Sie können diese Antwort oder diesen Thread auch überprüfen .

MySQL konvertiert auch die Datentypen BOOL, BOOLEAN in TINYINT (1).

Lesen Sie weiter die Dokumentation

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.