# Tipos de datos para identificadores: Por qué los números de pasaporte no son enteros
Una pregunta sencilla sobre la elección del tipo de dato adecuado para almacenar números de pasaporte en una base de datos SQL divide a los desarrolladores en dos bandos: los que piensan en la semántica de los datos y los que siguen recetas memorizadas. Elegir INTEGER en lugar de VARCHAR elimina los ceros iniciales y rompe la identificación, algo crítico en sistemas que manejan millones de usuarios. Este artículo desglosa un principio fundamental del diseño de esquemas de bases de datos basado en la naturaleza de los datos, no en su apariencia.
Semántica de los datos vs. apariencia
La mayoría de los desarrolladores, al ver dígitos en un número de pasaporte durante una entrevista, instintivamente eligen tipos numéricos como INTEGER o BIGINT. Este es un error clásico por análisis superficial. La pregunta clave no es de qué está hecho el dato, sino cómo se usa. Nunca realizas operaciones aritméticas con series o números de pasaporte: solo los comparas por igualdad, buscas y transmites. Son identificadores, no cantidades. Por eso, la elección correcta es un tipo de cadena: CHAR(4) para la serie y CHAR(6) para el número, o CHAR(10) para el valor combinado. Almacenar en INTEGER elimina irreversiblemente los ceros iniciales: 0306 se convierte en 306, invalidando el documento sin registrar errores.
Consecuencias reales del error
Elegir el tipo de dato equivocado no es teórico: impacta en producción con frecuencia. Imagina un servicio de permisos de estacionamiento donde el campo de pasaporte como NUMBER recortó silenciosamente un cero inicial, haciendo que los registros de la base no coincidieran con los documentos en papel. Pasó desapercibido en revisiones de código y pruebas hasta que afectó a usuarios con series que empezaban por cero. En Rusia, millones de pasaportes así existen, escalando el problema enormemente. Los argumentos de optimización como ahorro de espacio o velocidad de índices no se sostienen:
- CHAR(4) ocupa los mismos 4 bytes que INTEGER para dígitos de un byte.
- Los índices de VARCHAR rinden con eficiencia O(log n), igual que los numéricos, con diferencias insignificantes para cadenas fijas.
El ahorro de bytes no justifica los riesgos de pérdida de datos.
Aplicando la regla a otros identificadores
La regla «si no haces matemáticas con él, no es un número» se aplica a muchos identificadores en sistemas rusos y globales. Ejemplos clave:
- SNILS (11 dígitos, formato XXX-XXX-XXX XX): Almacena como VARCHAR(14) o CHAR(11) tras quitar guiones, no BIGINT.
- NIF personal (12 dígitos): Puede empezar por cero en regiones 01-09, así que VARCHAR(12) es imprescindible.
- Número de teléfono: VARCHAR(20) exclusivamente, para conservar el '+' en formatos internacionales.
- Código postal: CHAR(6), ya que los internacionales pueden ser alfanuméricos.
- Cuenta bancaria (20 dígitos): CHAR(20), pues los tipos numéricos no manejan esa longitud sin desbordamiento.
Los tipos de cadena garantizan flexibilidad y evitan pérdidas por cambios de formato.
Lecciones clave
- Semántica primero: Elige el tipo de dato según las operaciones, no la apariencia.
- Los ceros iniciales importan: Los numéricos los eliminan, rompiendo identificadores de millones de registros.
- Optimización después: No cambies bytes o microsegundos por datos corruptos.
- Principio universal: Cubre SNILS, NIF, teléfonos y más.
- Audita tus esquemas: Revisa bases existentes en busca de riesgos ocultos.
Cómo elegir el tipo de dato correcto
Un ingeniero sólido se hace tres preguntas al diseñar un campo de base de datos:
- ¿Cuál es la semántica? (¿ID, cantidad, texto?)
- ¿Qué operaciones? (¿Comparar, buscar, matemáticas?)
- ¿Qué reglas de negocio aplican? (¿Formato, longitud, caracteres?)
Las respuestas dictan la elección: cadenas para identificadores, numéricos para cantidades. Esto separa la resolución de problemas del copiar-pegar y evita errores costosos desde el principio.
Tipos de datos para identificadores rusos
| Dato | Formato | Tipo correcto | Error común | Impacto del error |
|------|---------|---------------|-------------|-------------------|
| Serie de pasaporte | 4 dígitos | CHAR(4) | INTEGER | Pérdida de cero inicial, doc inválido |
| Número de pasaporte | 6 dígitos | CHAR(6) | INTEGER | Recorte de ceros, ID roto |
| Pasaporte completo | 10 dígitos | CHAR(10) | BIGINT | Hasta dos ceros iniciales perdidos |
| SNILS | 11 dígitos | CHAR(11) | BIGINT | Recorte en códigos 01-09 |
| NIF personal | 12 dígitos | CHAR(12) | BIGINT | Pérdida de dígitos en 01-09 |
| Teléfono | +7... | VARCHAR(20) | BIGINT | No almacena '+', sin soporte intl |
| Código postal | 6 dígitos | CHAR(6) | INTEGER | Sin códigos alfanuméricos intl |
| Cuenta bancaria | 20 dígitos | CHAR(20) | Sin INT adecuado | Desbordamiento, riesgos financieros |
Esta tabla es tu hoja de referencia para diseño de esquemas y auditorías.
— Editorial Team
Aún no hay comentarios.