BOOLEAN

El tipo BOOLEAN (o BOOL) representa valores lógicos: verdadero o falso. En MySQL, BOOLEAN no es un tipo nativo sino un alias de TINYINT(1). TRUE se almacena como 1 y FALSE como 0. Aunque técnicamente la columna puede contener cualquier valor de -128 a 127, la convención es usar solo 0 y 1.

Sintaxis

CREATE TABLE nombre_tabla (
    columna BOOLEAN DEFAULT FALSE
);

BOOLEAN y BOOL son sinónimos. Ambos se traducen internamente a TINYINT(1).

Ejemplo básico

CREATE TABLE funcionalidades (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    habilitada BOOLEAN NOT NULL DEFAULT FALSE,
    visible BOOLEAN NOT NULL DEFAULT TRUE
);
 
INSERT INTO funcionalidades (nombre, habilitada, visible) VALUES
('Modo oscuro', TRUE, TRUE),
('Notificaciones push', TRUE, TRUE),
('Chat en vivo', FALSE, TRUE),
('Beta features', FALSE, FALSE);
 
SELECT * FROM funcionalidades;
idnombrehabilitadavisible
1Modo oscuro11
2Notificaciones push11
3Chat en vivo01
4Beta features00

MySQL muestra 1 y 0 en lugar de TRUE y FALSE. Internamente es un TINYINT(1).

BOOLEAN en tienda_mysql

Nuestra tabla productos tiene una columna activo de tipo BOOLEAN:

-- Productos activos
SELECT nombre, activo FROM productos LIMIT 5;
nombreactivo
iPhone 15 Pro1
Samsung Galaxy S241
Google Pixel 81
Xiaomi 141
MacBook Air M31

Todos los productos están activos (1). En una aplicación real, desactivar un producto (poner activo = 0) lo oculta del catálogo sin eliminarlo de la base de datos.

Filtrar con WHERE

Puedes filtrar por valores booleanos de varias formas equivalentes:

-- Todas son equivalentes para filtrar TRUE
SELECT nombre FROM funcionalidades WHERE habilitada = TRUE;
SELECT nombre FROM funcionalidades WHERE habilitada = 1;
SELECT nombre FROM funcionalidades WHERE habilitada;
nombre
Modo oscuro
Notificaciones push

La tercera forma (sin comparación) funciona porque MySQL evalúa cualquier valor distinto de 0 como verdadero en un contexto booleano.

Para filtrar FALSE:

-- Todas son equivalentes para filtrar FALSE
SELECT nombre FROM funcionalidades WHERE habilitada = FALSE;
SELECT nombre FROM funcionalidades WHERE habilitada = 0;
SELECT nombre FROM funcionalidades WHERE NOT habilitada;
nombre
Chat en vivo
Beta features

Condiciones combinadas

-- Funcionalidades habilitadas Y visibles
SELECT nombre
FROM funcionalidades
WHERE habilitada AND visible;
nombre
Modo oscuro
Notificaciones push
-- Funcionalidades visibles pero NO habilitadas
SELECT nombre
FROM funcionalidades
WHERE visible AND NOT habilitada;
nombre
Chat en vivo

TRUE y FALSE como constantes

TRUE es un alias de 1 y FALSE es un alias de 0:

SELECT TRUE, FALSE, TRUE + TRUE, TRUE + FALSE;
TRUEFALSETRUE + TRUETRUE + FALSE
1021

Puedes operar aritméticamente con ellos porque son enteros. Esto permite contar valores verdaderos con SUM:

SELECT
    SUM(habilitada) AS habilitadas,
    SUM(NOT habilitada) AS deshabilitadas,
    SUM(visible) AS visibles,
    COUNT(*) AS total
FROM funcionalidades;
habilitadasdeshabilitadasvisiblestotal
2234

INSERT y UPDATE con BOOLEAN

-- Habilitar una funcionalidad
UPDATE funcionalidades SET habilitada = TRUE WHERE nombre = 'Chat en vivo';
 
-- Desactivar
UPDATE funcionalidades SET habilitada = FALSE WHERE nombre = 'Modo oscuro';
 
-- Toggle: invertir el valor actual
UPDATE funcionalidades SET habilitada = NOT habilitada WHERE id = 4;

El patrón NOT habilitada invierte el valor: si era TRUE (1) pasa a FALSE (0) y viceversa.

BOOLEAN y NULL

Si la columna permite NULL, hay tres estados posibles: TRUE, FALSE y NULL (desconocido):

CREATE TABLE permisos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    accion VARCHAR(50),
    permitido BOOLEAN  -- Permite NULL
);
 
INSERT INTO permisos (accion, permitido) VALUES
('Leer', TRUE),
('Escribir', FALSE),
('Administrar', NULL);  -- Estado desconocido

Para filtrar correctamente con tres estados:

-- Solo TRUE
SELECT accion FROM permisos WHERE permitido = TRUE;
 
-- Solo FALSE (no incluye NULL)
SELECT accion FROM permisos WHERE permitido = FALSE;
 
-- Solo NULL
SELECT accion FROM permisos WHERE permitido IS NULL;
 
-- TRUE o desconocido
SELECT accion FROM permisos WHERE permitido OR permitido IS NULL;

Si tu lógica solo necesita verdadero/falso, usa NOT NULL DEFAULT FALSE para evitar la complejidad de tres estados.

TINYINT(1) vs BOOLEAN

Cuando defines una columna como BOOLEAN, MySQL la almacena como TINYINT(1):

CREATE TABLE test_bool (
    a BOOLEAN,
    b TINYINT(1)
);
 
DESCRIBE test_bool;
FieldTypeNullKeyDefaultExtra
atinyint(1)YESNULL
btinyint(1)YESNULL

Ambas columnas son idénticas. El (1) no limita el rango, solo es una pista de visualización. Puedes insertar cualquier valor de -128 a 127:

INSERT INTO test_bool VALUES (5, 99);
 
SELECT a, b, a = TRUE AS a_es_true, b = TRUE AS b_es_true FROM test_bool;
aba_es_trueb_es_true
59900

El valor 5 no es TRUE (que es 1), aunque en un contexto booleano de WHERE se evaluaría como verdadero. Para evitar confusiones, usa siempre TRUE/FALSE (o 1/0) al insertar valores en columnas booleanas.

Buenas prácticas

Usa BOOLEAN NOT NULL DEFAULT FALSE para columnas booleanas. Esto garantiza que solo hay dos estados y que las nuevas filas tienen un valor definido.

Nombra las columnas booleanas de forma que la lectura sea natural: activo, visible, habilitado, verificado, eliminado. Evita nombres negativos como no_enviado que crean dobles negaciones confusas (WHERE NOT no_enviado).

Usa IF o CASE para convertir booleanos a texto legible en reportes:

SELECT
    nombre,
    IF(habilitada, 'Sí', 'No') AS habilitada,
    IF(visible, 'Sí', 'No') AS visible
FROM funcionalidades;
nombrehabilitadavisible
Modo oscuroNo
Notificaciones push
Chat en vivo
Beta featuresNo

Limpieza

DROP TABLE IF EXISTS funcionalidades;
DROP TABLE IF EXISTS permisos;
DROP TABLE IF EXISTS test_bool;

En el siguiente artículo veremos VARCHAR y CHAR, los tipos para cadenas de texto cortas.

Escrito por Eduardo Lázaro