Hola a todos,
en el grupo generalmente se hacen consultas técnicas, pero pocas veces sobre diseño de datos (me incluyo a la cabeza de la lista). Creo que los programadores asumimos que no necesitamos consultar estas cuestiones porque de una forma u otra vamos a guardar la información y la vamos a encontrar después. Y básicamente es así, pero podemos sacar buenas ideas y copiar mejores prácticas de otros colegas que nos ayudarán a convertirnos en mejores diseñadores y a ahorrarnos dolores de cabeza.
Yo estoy ahora exactamente en el punto donde tengo que rediseñar mi sistema por completo, pasarme a un motor SQL y luego, lamentablemente abandonar fox, y probablemente va a ser por Windev. Pero esto es aparte.
En este proceso de rediseño y aprendizaje de MySQL, ya que siempre me manejé con tablas nativas, empezaron a surgir serias dudas sobre temas que los tenía absolutamente resueltos. El primero fue el stock. Aquí mis prácticas hasta ahora:
1) Para cada producto llevo un historial con un registro por cada evento de entrada/salida, ej. venta, compra, remito interno, corrección, etc. El registro contiene básicamente los campos codigo, fecha, concepto, ingresa, egresa y stock, tal como si fuera una cuenta corriente de ese producto.
2) Siempre fuí enemigo de guardar el stock final de un producto en la tabla de productos en la forma codigo - descripcion - precio - stock, sino que por el contrario cuando necesitaba saber el stock de un producto buscaba el último registro de ese producto en el historial y mostraba el valor del campo stock.
Con estos dos conceptos me manejé perfectamente, hasta que me llegaron clientes con depósitos y sucursales, y el panorama se complicó. La primera pregunta fue:
¿Dónde guardo el historial de cada depósito o sucursal?
A) Agrego un campo sucursal y guardo todo en una misma tabla.
B) Tengo cada lugar en una tabla separada.
Considerando que se generan cientos o miles de movimientos por día, juntarlos todos en una tabla me traería problemas con el tamaño y con la velocidad de las consultas, por lo que me decidí por la opción B.
Ahora bien, algunos clientes quieren conocer el stock en el salón de ventas y en el depósito pequeño de arriba y en el depósito grande que está a 50 metros. Un cliente que vende cubiertas por ejemplo, busca "175 70 13" que es la medida, el sistema le devuelve 10 cubiertas de distintas marcas en esa medida, él no puede estar haciendo clicks en cada producto para saber cuánto hay en cada lugar. El debe saber de un vistazo cuántas cubiertas de cada marca hay en total antes de ofrecerselas a su cliente, no importan dónde estén, por lo tanto necesita el stock global de las mismas. Según el esquema elegido por mí, esto me obliga a hacer una búsqueda en cada historial y sumar el stock final de cada una. Ahora empiezo a pensar que no es tan bueno el diseño. Si la búsqueda no está muy bien hecha, por ejemplo "arandela", el resultado puede contener cientos de registros y por cada registro de ese resultado el sistema tuvo que hacer 3 búsquedas para sumar el stock global, uf.
¡Es aquí donde empiezo a pensar que el grupo puede tener una idea diferente (y mejor) al respecto! :-)
Ahora, por cuestiones de eficiencia, estoy tentado de hacer lo que siempre me pareció incorrecto, poner el stock final de cada lugar en un campo de la tabla de productos:
codigo - descripcion - precio - stock_salon - stock_dep_arriba - stock_dep_grande
Cuando uno define un nuevo depósito o sucursal, se crea una nueva columna con ese nombre. Teniendo en cuenta que podemos usar transacciones al ingresar una venta, compra o cualquier documento que mueva stock, estaría garantizado que el campo correspondiente en la tabla de productos muestre el stock final correcto. ¿O no?
En conclusión ¿qué harían ustedes? La respuesta debe tener en cuenta que se va a trabajar con MySQL, ya no con tablas nativas.
A) ¿Cómo guardarían el historial?
A1) Llevarían un sólo historial para todas las ubicaciones.
A2) Tendrían una tabla para cada ubicación.
A3) No llevarían historial por aparte, sino que lo armarían al momento que el cliente necesite verlo, leyendo los registros de ventas, compras, etc.
B) En caso de llevar historial por aparte...
B1) Calcularían el stock en cada registro al momento de crearlo.
B2) Calcularían el stock al momento de mostrar el historial pero sin guardarlo en la tabla.
C) En caso de llevar historial y guardar el stock en cada registro...
C1) Guardarían el stock final en el registro del producto.
C2) Lo consultarían tantas veces como ubicaciones hubiere en cada consulta que se haga del producto.
Creo que cubrí todo. Como verán, ya que los hice leer bastante, he tratado de por lo menos facilitarles la respuesta, aunque bienvenidos son los comentarios que respalden cada elección. Si me olvidé de alguna alternativa, por favor agréguenla, tienen todavía desde la D hasta la Z.
Muchas gracias y espero que sea un intercambio provechoso para todo el mundo.
Daniel Del Giudice