Color de Acento

Diseño de Esquema de Base de Datos para Sistema POS

Tablas Centrales: Productos y Categorías

La tabla products es la base. Los campos incluyen product_id (PK), sku (unidad de mantenimiento de stock única), barcode, product_name, description, category_id (FK), brand, unit_price, cost_price, tax_rate, unit_type (pieza/kg/litro), is_active, e image_url. La tabla categories organiza los productos jerárquicamente: category_id (PK), name, parent_category_id (FK autorreferenciado para subcategorías), y sort_order. Un árbol de categorías bien diseñado soporta reportes departamentales.

Inventario y Gestión de Stock

La tabla inventory rastrea los niveles de stock en múltiples ubicaciones: inventory_id (PK), product_id (FK), store_id (FK), quantity_on_hand, quantity_committed (reservado para órdenes abiertas), reorder_point, reorder_quantity, y last_count_date. Una tabla stock_movements registra cada cambio de inventario: movement_id (PK), product_id (FK), store_id (FK), movement_type (recepción/venta/devolución/ajuste/transferencia), quantity, reference_document, movement_date, y performed_by. Esta pista de auditoría es esencial para identificar discrepancias durante conteos físicos de inventario.

Esquema de Transacciones de Venta

El esquema de ventas sigue un patrón de encabezado-detalle. La tabla sales_orders (encabezado) registra: order_id (PK), store_id (FK), customer_id (FK), employee_id (FK — el cajero), order_date, order_time, subtotal, discount_total, tax_total, grand_total, payment_status, y order_status. La tabla sales_order_items (detalle) captura cada línea: order_item_id (PK), order_id (FK), product_id (FK), quantity, unit_price_at_sale, discount_percent, line_total, y returned_quantity. Almacenar unit_price_at_sale es crítico porque los precios de los productos cambian con el tiempo.

Procesamiento de Pagos

La tabla payments maneja múltiples tipos de pago por transacción: payment_id (PK), order_id (FK), payment_method (efectivo/tarjeta/UPI/crédito/voucher), payment_amount, reference_number (para transacciones con tarjeta/UPI), payment_date, y is_verified. Para pagos divididos, múltiples filas se vinculan al mismo order_id. Una tabla separate registers gestiona las operaciones del cajón de efectivo: register_id (PK), store_id (FK), opening_balance, closing_balance, opened_by, closed_by, opening_date, closing_date, expected_cash, y variance.

Gestión de Relaciones con Clientes

La tabla customers almacena: customer_id (PK), first_name, last_name, phone, email, date_of_birth, anniversary_date, loyalty_points, total_spent, registration_date, e is_vip. Una tabla loyalty_transactions rastrea los puntos ganados y canjeados por orden. Para cadenas minoristas, una tabla customer_addresses soporta órdenes de entrega con múltiples direcciones. La tabla customer se integra con el esquema de ventas a través del FK customer_id en sales_orders, permitiendo funciones como historial de compras y ofertas personalizadas.

Arquitectura Multi-Tienda

Para operaciones de cadena, la tabla stores define cada ubicación: store_id (PK), store_name, address, city, state, phone, tax_registration_number, e is_active. Las órdenes de transferencia entre tiendas usan una tabla transfer_orders: transfer_id (PK), from_store_id (FK), to_store_id (FK), product_id (FK), quantity, status (solicitada/aprobada/enviada/recibida), request_date, y completion_date. Esta estructura soporta reportes centralizados mientras permite operaciones descentralizadas.

Mejores Prácticas para Base de Datos POS

Usa transacciones de base de datos para cada venta — si la inserción de cualquier línea falla, toda la orden debe revertirse. Indexa la columna barcode para búsquedas de productos sub-milisegundo en el registro. Implementa bloqueo optimista (columna de número de versión) en tablas de inventario para prevenir sobreventas durante períodos de alta concurrencia. Particiona sales_order_items por order_date para consultas históricas rápidas. Siempre almacena valores monetarios en la unidad monetaria más pequeña (céntimos/paisa) como enteros para evitar errores de redondeo de punto flotante.