Concepto clave
Diseñar un schema para una API de e-commerce en producción requiere pensar en escalabilidad, relaciones entre entidades y validaciones desde el inicio. Imagina que estás construyendo un centro comercial digital: necesitas tiendas (productos), clientes (usuarios), transacciones (pedidos) y un sistema de inventario que funcione en tiempo real. En Prisma, el schema define la estructura de tu base de datos usando un lenguaje declarativo que luego se traduce a SQL mediante migraciones.
La clave está en modelar las relaciones correctamente. Por ejemplo, un usuario puede tener múltiples pedidos, y cada pedido puede contener varios productos. Esto se representa con relaciones uno a muchos y muchos a muchos. En producción, debes evitar diseños que generen consultas ineficientes, como anidaciones excesivas o falta de índices en campos frecuentemente consultados.
Cómo funciona en la práctica
Vamos a crear un schema básico para un e-commerce con estas entidades: Usuario, Producto, Pedido y DetallePedido. Sigue estos pasos:
- Define el modelo Usuario con campos como id, email, nombre y una relación a Pedido.
- Crea el modelo Producto con id, nombre, precio, stock y categoría.
- Modela Pedido con id, fecha, estado y relaciones a Usuario y DetallePedido.
- Implementa DetallePedido como tabla de unión para la relación muchos a muchos entre Pedido y Producto, incluyendo cantidad y precioUnitario.
Antes de codificar, piensa en los índices: por ejemplo, agrega un índice único al email del usuario para evitar duplicados y mejorar búsquedas. En producción, esto reduce tiempos de consulta significativamente.
Código en acción
Aquí tienes un ejemplo funcional del schema.prisma:
// Modelo Usuario
model Usuario {
id Int @id @default(autoincrement())
email String @unique
nombre String
pedidos Pedido[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Modelo Producto
model Producto {
id Int @id @default(autoincrement())
nombre String
precio Float
stock Int @default(0)
categoria String
detalles DetallePedido[]
}
// Modelo Pedido
model Pedido {
id Int @id @default(autoincrement())
fecha DateTime @default(now())
estado String @default("pendiente")
usuarioId Int
usuario Usuario @relation(fields: [usuarioId], references: [id])
detalles DetallePedido[]
}
// Modelo DetallePedido (tabla de unión)
model DetallePedido {
id Int @id @default(autoincrement())
pedidoId Int
productoId Int
cantidad Int @default(1)
precioUnitario Float
pedido Pedido @relation(fields: [pedidoId], references: [id])
producto Producto @relation(fields: [productoId], references: [id])
@@unique([pedidoId, productoId])
}Ahora, mejoremos el schema para producción agregando validaciones y un índice compuesto:
// Refactorización: Agregar validaciones e índices
model Usuario {
id Int @id @default(autoincrement())
email String @unique @db.VarChar(255)
nombre String @db.VarChar(100)
pedidos Pedido[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email]) // Índice para búsquedas rápidas
}
model Producto {
id Int @id @default(autoincrement())
nombre String @db.VarChar(200)
precio Float @db.Decimal(10, 2)
stock Int @default(0)
categoria String @db.VarChar(50)
detalles DetallePedido[]
@@index([categoria]) // Índice para filtrar por categoría
}Errores comunes
- Olvidar relaciones bidireccionales: En Prisma, si defines una relación en un modelo, debes definirla en el otro. Por ejemplo, si Usuario tiene pedidos, Pedido debe tener un campo usuarioId y una relación a Usuario.
- No usar tipos de datos apropiados para producción: Evita String sin límites; usa @db.VarChar(length) para controlar el almacenamiento y mejorar el rendimiento.
- Ignorar índices en campos frecuentemente consultados: Campos como email o categoría deben tener índices para acelerar las queries en grandes volúmenes de datos.
- Diseñar relaciones muchos a muchos sin tabla de unión explícita: En e-commerce, necesitas almacenar datos adicionales como cantidad y precio en DetallePedido; no uses la relación implícita de Prisma en este caso.
- No planificar migraciones desde el inicio: Cambiar el schema después de desplegar requiere migraciones cuidadosas; prueba siempre en un entorno de staging primero.
Checklist de dominio
- ¿Definiste todos los modelos necesarios (Usuario, Producto, Pedido, DetallePedido) con sus campos básicos?
- ¿Estableciste las relaciones correctamente (uno a muchos, muchos a muchos) usando claves foráneas?
- ¿Agregaste índices a campos como email y categoría para optimizar consultas?
- ¿Usaste tipos de datos específicos (ej., @db.Decimal para precios) en lugar de tipos genéricos?
- ¿Incluiste campos de auditoría como createdAt y updatedAt en modelos críticos?
- ¿Validaste que el schema permita operaciones comunes como crear un pedido con múltiples productos?
- ¿Probaste el schema generando una migración y ejecutándola en una base de datos local?
Extiende el Schema para Incluir Reseñas de Productos
En este ejercicio, ampliarás el schema de e-commerce para soportar reseñas de productos, una funcionalidad común en plataformas de comercio electrónico. Sigue estos pasos:
- Crea un nuevo modelo llamado Resena con los siguientes campos: id, contenido, calificacion (del 1 al 5), usuarioId, productoId, y fechacreacion.
- Establece las relaciones: una Resena pertenece a un Usuario y a un Producto. Asegúrate de que Usuario y Producto tengan campos para acceder a sus reseñas (ej., resenas en Usuario y Producto).
- Agrega validaciones: calificacion debe ser un entero entre 1 y 5, y contenido debe tener un máximo de 500 caracteres.
- Implementa un índice compuesto en usuarioId y productoId para evitar que un usuario deje múltiples reseñas para el mismo producto.
- Genera una migración usando
npx prisma migrate dev --name add_resenasy verifica que no haya errores.
Al final, tu schema debe permitir consultas como "obtener todas las reseñas de un producto con sus usuarios" de forma eficiente.
Pistas- Recuerda que en Prisma, las relaciones se definen en ambos modelos involucrados.
- Usa @db.VarChar(500) para limitar el contenido de la reseña.
- Considera agregar un campo de estado (ej., 'activa' o 'eliminada') para manejar moderación en producción.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.