Diseña estructuras de datos sólidas en MySQL con claves confiables, correos únicos y metadatos que facilitan auditoría y análisis. Aquí se explica cómo crear la tabla clients con auto_increment, validar duplicados con unique, elegir entre timestamp y datetime, usar enum para género y aplicar desactivación lógica con active. Además, se bosqueja la tabla Operations para ventas, préstamos y devoluciones, y cómo finished refleja el estado del flujo.
¿Cómo crear una tabla de clientes robusta en MySQL?
Definimos una estructura clara que prioriza consistencia e integridad. Se parte de un ID en singular, un nombre acotado, un correo único y metadatos de creación y actualización.
CREATETABLE clients ( client_id INTUNSIGNEDPRIMARYKEYAUTO_INCREMENT, name VARCHAR(50)NOTNULL, email VARCHAR(100)NOTNULLUNIQUE, birth_date DATETIMENULL, gender ENUM('male','female','N/D')NOTNULL, active TINYINT(1)NOTNULLDEFAULT1, created_at TIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMP, updated_at TIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP);
ID con auto_increment: asegura consistencia sin depender de otra capa. Sin auto_increment sigue siendo llave primaria válida, pero otra capa debería asignar el ID.
name NOT NULL: máximo 50 caracteres para un nombre corto y obligatorio.
email UNIQUE: evita duplicados por correo y permite detectar registros previos antes del insert.
gender con enum: sólo permite 'male', 'female' o 'N/D'. Sin default: se debe enviar un valor en cada insert.
active TINYINT(1): eliminación lógica. Nunca se borra la tupla; se inactiva con 0 por defecto en 1.
created_at y updated_at: metadatos clave para auditoría y análisis.
Nota: IF NOT EXISTS es útil, aunque aquí se omitió para simplificar.
¿Qué diferencia hay entre TIMESTAMP y DATETIME y cómo aplicarlos?
Ambos se ven igual al mostrarse (AAAA-MM-DD HH:MM:SS), pero se almacenan distinto.
timestamp: basado en epoch (segundos desde 1970-01-01). Es entero, eficiente para cálculos y proyecciones.
datetime: representa fechas amplias, incluso anteriores a 1970. Útil para cumpleaños, ya que no todos nacieron después de 1970.
Aplicación práctica: birth_date en datetime; metadatos en timestamp por eficiencia.
A partir de MySQL 5.3 se puede usar CURRENT_TIMESTAMP en varias columnas con comportamientos distintos.
Comportamiento: al crear, ambos toman el mismo valor. En un update, sólo updated_at cambia automáticamente.
Valor de negocio: permite responder preguntas como “¿cuántos usuarios se crearon la semana pasada?” o “¿cuáles fueron creados el año pasado pero actualizados este año?”.
¿Cómo modelar operaciones de venta, préstamo y devolución?
Se requiere registrar el libro, el cliente y el tipo de operación. Además, finished indica si la operación terminó.
type con enum: 'prestado', 'devuelto', 'vendido'.
Regla de negocio: 'vendido' implica finished = 1 por defecto. 'prestado' implica finished = 0 hasta que sea 'devuelto' (finished = 1).
Incluye metadatos created_at y updated_at como en clients.
Cascarón de la tabla (completar tipos y restricciones):
CREATETABLE Operations ( operation_id /* definir tipo y PK */, book_id /* definir tipo */, client_id /* definir tipo */,type/* ENUM('prestado','devuelto','vendido') NOT NULL */, finished /* TINYINT(1) NOT NULL */, created_at /* TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP */, updated_at /* TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP */);
Sugerencia práctica: mantener coherencia de nombres (singular para IDs), usar not null cuando el dato sea obligatorio y centralizar reglas de negocio simples en enum y defaults.
¿Qué le agregarías a Operations para tu caso? Comenta tus decisiones de tipos, restricciones y cómo validarías finished en tus inserts y updates.