Saltar al contenido

Mentoring

Tipos de datos en MySQL: guía para elegir el adecuado

Resumen de los tipos de datos más usados en MySQL y cómo elegir entre números, textos, fechas y booleanos.

Mentoring 6 min de lectura

Actualizado el

Tipos de datos en MySQL

El tipo de dato que asignas a cada columna en MySQL determina qué valores acepta, cuánto espacio ocupa, la precisión con la que se guardan y cómo se comportan la validación y la indexación.

Después de elegir cada tipo, puedes aplicarlo en una definición completa con CREATE TABLE en MySQL.

Elección rápida según el dato

DatoElección habitual
IDINT o BIGINT, según el rango
ImporteDECIMAL(M,D)
Texto cortoVARCHAR(N)
Texto largoTEXT
Solo fechaDATE
Fecha y hora civilDATETIME
Instante con conversión de zona horariaTIMESTAMP
BooleanoBOOLEAN / TINYINT(1)
BinarioVARBINARY o BLOB
Documento estructuradoJSON

Tipos numéricos

TipoUso habitual
TINYINTNúmeros pequeños, flags, valores tipo booleano.
SMALLINTEnteros pequeños.
MEDIUMINTEnteros medianos.
INTEnteros habituales: ids, contadores, cantidades.
BIGINTEnteros muy grandes.
DECIMALImportes y valores que necesitan precisión exacta.
FLOAT / DOUBLEDecimales aproximados, mediciones o cálculos científicos.
TipoAlmacenamientoCon signo (SIGNED)Sin signo (UNSIGNED)
TINYINT1 byte−128 a 1270 a 255
SMALLINT2 bytes−32.768 a 32.7670 a 65.535
MEDIUMINT3 bytes−8.388.608 a 8.388.6070 a 16.777.215
INT4 bytes−2.147.483.648 a 2.147.483.6470 a 4.294.967.295
BIGINT8 bytes−9.223.372.036.854.775.808 a 9.223.372.036.854.775.8070 a 18.446.744.073.709.551.615

El rango SIGNED es el predeterminado; los bytes indican almacenamiento, no ancho de visualización.

DECIMAL guarda valores exactos y es adecuado para importes; FLOAT y DOUBLE son aproximados, así que no los uses para dinero.

precio DECIMAL(10, 2)

UNSIGNED

UNSIGNED indica que un número no puede ser negativo.

stock INT UNSIGNED

Es útil para ids, cantidades o contadores. No lo uses si el campo puede tener valores negativos, y no lo apliques de forma automática a todos los identificadores: solo cuando necesites aprovechar ese rango adicional.

No uses INT(11) para definir capacidad: el ancho de visualización de enteros está obsoleto, al igual que ZEROFILL. El rango depende del tipo y de UNSIGNED, no del número entre paréntesis.

Tipos de texto

TipoUso habitual
CHARTexto de longitud fija.
VARCHARTexto corto de longitud variable.
TEXTTextos largos.
MEDIUMTEXTTextos muy largos.
LONGTEXTTextos enormes.

VARCHAR(N) usa longitud variable y es adecuado para nombres, correos, slugs o títulos. Con utf8mb4, cada carácter puede necesitar hasta 4 bytes, y el máximo teórico de un VARCHAR es de 16.383 caracteres, sujeto además al límite de fila y al espacio que ocupen el resto de columnas.

email VARCHAR(255) NOT NULL

Para descripciones o contenidos largos, usa TEXT: no es equivalente directo a un VARCHAR. Usa utf8mb4 en lugar de depender de una collation concreta del servidor.

Tipos de fecha y hora

TipoUso habitual
DATESolo fecha: YYYY-MM-DD.
TIMESolo hora: HH:MM:SS.
DATETIMEFecha y hora.
TIMESTAMPFecha y hora ligada a zona horaria/registro temporal.
YEARAño.

La diferencia práctica entre DATETIME y TIMESTAMP está en el rango y la zona horaria:

  • DATETIME cubre de 1000 a 9999 y no convierte por zona horaria.
  • TIMESTAMP almacena y convierte respecto de UTC y de la zona horaria de la sesión, pero su rango termina el 19 de enero de 2038.

Elige DATE cuando solo necesites la fecha, DATETIME para fechas civiles futuras o fuera del rango de TIMESTAMP, y TIMESTAMP cuando su conversión de zona horaria y su rango encajen con el dato.

Ejemplo:

created_at DATETIME NOT NULL

No des por hecho que TIMESTAMP tendrá un valor por defecto automático: ese comportamiento depende de la configuración y de la versión.

Booleanos en MySQL

BOOLEAN es un alias de TINYINT(1), no un tipo lógico independiente.

activo BOOLEAN NOT NULL DEFAULT TRUE

También puedes escribirlo así:

activo TINYINT(1) NOT NULL DEFAULT 1

TINYINT(1) no impide guardar otros valores: si necesitas limitar estrictamente a 0 y 1, valídalo desde la aplicación o mediante una restricción adecuada.

Datos binarios

TipoUso habitual
BINARYDatos binarios de longitud fija.
VARBINARYDatos binarios de longitud variable.
BLOBArchivos o datos binarios.

Aunque MySQL puede guardar archivos en campos BLOB, muchas veces es mejor guardar el archivo en almacenamiento externo y en la base de datos solo su ruta o identificador.

Datos JSON

configuracion JSON

En este ejemplo ilustrativo, la tabla ajustes tiene una columna configuracion:

SELECT configuracion->'$.tema' AS tema_json,
       configuracion->>'$.tema' AS tema_texto
FROM ajustes;

Con el documento {"tema":"oscuro"}, -> extrae el valor JSON string, que se representa con comillas ("oscuro"); ->> lo descomilla y devuelve el texto oscuro.

MySQL valida el documento JSON al insertarlo y lo guarda en un formato binario propio. Una columna JSON no se indexa directamente: si necesitas indexar rutas concretas, se usan columnas generadas con sus índices, y los arrays pueden requerir índices multivalor según el caso.

Recomendaciones rápidas

  • Elige el tipo por el dato real, no por costumbre: DECIMAL para importes, VARCHAR para textos cortos y TEXT para textos largos.
  • Reserva FLOAT y DOUBLE para valores aproximados, nunca para dinero.
  • Usa utf8mb4 y no dependas de una collation concreta del servidor.
  • Ten en cuenta el rango de TIMESTAMP antes de usarlo en fechas lejanas.
  • No guardes números en campos de texto si luego vas a calcular con ellos.
  • Define NOT NULL cuando el dato sea obligatorio y añade valores por defecto cuando tenga sentido.