web-dev-qa-db-fra.com

Quel type de données MySQL utiliser pour stocker les valeurs booléennes

Comme MySQL ne semble pas avoir de type de données "booléen", quel type de données utilisez-vous pour "abuser" du stockage d'informations vraies ou fausses dans MySQL?

Surtout dans le contexte de l'écriture et de la lecture de/vers un script PHP.

Au fil du temps, j'ai utilisé et vu plusieurs approches:

  • tinyint, champs varchar contenant les valeurs 0/1,
  • champs varchar contenant les chaînes '0'/'1' ou 'true'/'false'
  • et enfin enum Champs contenant les deux options 'true'/'false'.

Aucune de ces réponses ne semble optimale. J'ai tendance à préférer la variante tinyint 0/1, car la conversion de type automatique dans PHP me donne des valeurs booléennes plutôt simplement.

Alors quel type de données utilisez-vous? Existe-t-il un type conçu pour les valeurs booléennes que j'ai oublié? Voyez-vous des avantages/inconvénients en utilisant un type ou un autre?

1144
Beat

Pour MySQL 5.0.3 et versions ultérieures, vous pouvez utiliser BIT. Le manuel dit:

Depuis MySQL 5.0.3, le type de données BIT est utilisé pour stocker les valeurs de champs de bits. Un type de BIT (M) permet de stocker des valeurs de M bits. M peut aller de 1 à 64.

Sinon, selon le manuel MySQL, vous pouvez utiliser bool et boolean qui sont actuellement des alias de tinyint (1):

Bool, Boolean: Ces types sont des synonymes de TINYINT (1). Une valeur de zéro est considérée comme fausse. Les valeurs non nulles sont considérées comme vraies.

MySQL indique également que:

Nous avons l'intention d'implémenter la gestion complète des types booléens, conformément au standard SQL, dans une future version de MySQL.

Références: http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html

1186
markus

BOOL et BOOLEAN sont des synonymes de TINYINT(1). Zéro est false, tout le reste est true. Plus d'informations ici .

236
Philip Morton

C'est une solution élégante que j'apprécie beaucoup car elle utilise zéro octet de données:

some_flag CHAR(0) DEFAULT NULL

Pour le définir sur true, définissez some_flag = '' et pour le définir sur false, définissez some_flag = NULL.

Ensuite, pour tester la valeur true, vérifiez si some_flag IS NOT NULL, et pour vérifier la valeur false, vérifiez si some_flag IS NULL.

(Cette méthode est décrite dans "Performances élevées MySQL: optimisation, sauvegardes, réplication, etc." de Jon Warren Lentz, Baron Schwartz et Arjen Lentz.)

69
R. S.

Si vous utilisez le type BOOLEAN, il est associé à TINYINT (1). Cela est préférable si vous souhaitez utiliser du SQL normalisé et que le champ peut contenir une valeur hors limites (en principe, tout ce qui n'est pas 0 sera "vrai").

ENUM ('False', 'True') vous permettra d'utiliser les chaînes de votre code SQL et MySQL stockera le champ en interne sous la forme d'un entier où 'False' = 0 et 'True' = 1 en fonction de l'ordre spécifié par Enum. .

Dans MySQL 5+, vous pouvez utiliser un champ BIT (1) pour indiquer un type numérique à 1 bit. Je ne crois pas que cela utilise réellement moins d’espace dans la mémoire mais permette encore une fois de contraindre les valeurs possibles à 1 ou 0.

Tout ce qui précède utilise approximativement la même quantité de stockage, il est donc préférable de choisir celui qui vous convient le mieux.

34
Ciaran McNulty

On a répondu à cette question, mais je me suis dit que je mettrais 0,02 $. J'utilise souvent un CHAR (0), où '' == true et NULL == false.

De documentation mysql

CHAR (0) est également assez agréable lorsque vous avez besoin d'une colonne ne pouvant prendre que deux valeurs: une colonne définie comme CHAR (0) NULL n'occupe qu'un bit et ne peut prendre que les valeurs NULL et '' (la chaîne vide) .

34
Josh

J'utilise TINYINT (1) afin de stocker des valeurs booléennes dans Mysql.

Je ne sais pas s'il y a un avantage à utiliser cela ... Mais si je ne me trompe pas, mysql peut stocker boolean (BOOL) et le stocke comme un tinyint (1)

http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html

19
Fred

Bit n’est avantageux que pour les différentes options d’octets (tinyint, enum, char (1)) si vous avez beaucoup de champs booléens. Un champ de bits occupe toujours un octet complet. Deux champs de bits entrent dans ce même octet. Trois, quatre, cinq, six, sept, huit. Après quoi, ils commencent à remplir l'octet suivant. En fin de compte, les économies sont si faibles que vous devriez vous concentrer sur des milliers d’optimisations supplémentaires. À moins que vous ne traitiez une quantité énorme de données, ces quelques octets ne vous rapporteront pas grand chose. Si vous utilisez bit avec PHP, vous devez transtyper les valeurs entrantes et sortantes.

17
Thor

Jusqu'à ce que MySQL implémente un type de données de bits, si votre traitement est vraiment sollicité pour l'espace et/ou le temps, comme pour les transactions de volume élevé, créez un champ TINYINT appelé bit_flags pour toutes vos variables booléennes, masquez et déplacez le bit booléen. vous désirez dans votre requête SQL.

Par exemple, si votre bit le plus à gauche représente votre champ bool et que les 7 bits les plus à droite ne représentent rien, votre champ bit_flags sera égal à 128 (valeur binaire 10000000). Masque (masque) les sept bits les plus à droite (à l'aide de l'opérateur binaire &) et décale le huitième bit de sept espaces vers la droite, terminant par 00000001. Le nombre entier (qui dans ce cas est 1) est votre valeur.

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

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

Vous pouvez exécuter des instructions comme celles-ci lorsque vous testez

SELECT (128 & 128) >> 7;

SELECT (0 & 128) >> 7;

etc.

Comme vous avez 8 bits, vous avez potentiellement 8 variables booléennes d'un octet. Certains futurs programmeurs utiliseront invariablement les sept bits suivants, de sorte que vous devez masquer. Ne vous contentez pas de changer, ou vous allez créer un enfer pour vous et les autres à l'avenir. Assurez-vous que MySQL masque et modifie les modifications. Ce sera beaucoup plus rapide que le langage de script Web (PHP, ASP, etc.). Assurez-vous également de placer un commentaire dans le champ de commentaire MySQL pour votre champ bit_flags.

Vous trouverez ces sites utiles lors de l’implémentation de cette méthode:

13
Jonathan

J'en avais marre d'essayer d'obtenir des zéros, des NULLS et des '' arrondir avec précision une boucle de PHP, MySql et POST valeurs, donc j'utilise simplement 'Oui' et 'Non'.

Cela fonctionne parfaitement et ne nécessite aucun traitement spécial, ni évident ni facile à faire.

10
Geoff Kendall

En se référant à ce lien type de données booléen dans Mysql , en fonction de l'utilisation de l'application, si l'on souhaite que seulement 0 ou 1 soit stocké, bit (1) est le meilleur choix.

6
Vidz

Après avoir lu les réponses ici, j’ai décidé d’utiliser bit(1) et oui, c’est mieux dans l’espace/le temps, MAIS après un moment, j’ai changé d’avis et je ne l’utiliserai plus jamais . Cela a beaucoup compliqué mon développement, lors de l'utilisation d'instructions préparées, de bibliothèques, etc. (php).

Depuis lors, j’utilise toujours tinyint(1), semble assez bon.

1
Lemures

Puisque MySQL (8.0.16) et MariaDB (10.2.1) ont tous deux implémenté la contrainte CHECK, je voudrais maintenant utiliser

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

Vous ne pourrez stocker que 0, 1 ou NULL, ainsi que des valeurs pouvant être converties en 0 ou 1 sans erreurs telles que '1', 0x00, b'1' ou TRUE/FALSE.

Si vous ne souhaitez pas autoriser les valeurs NULL, ajoutez l'option NOT NULL

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

Notez qu'il n'y a pratiquement aucune différence si vous utilisez TINYINT, TINYINT(1) ou TINYINT(123).

Si vous voulez que votre schéma soit compatible vers le haut, vous pouvez également utiliser BOOL ou BOOLEAN

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

db <> démo de violon

1
Paul Spiegel