2008-11-13 22 views
66

Esta no es realmente una cuestión de "programación" (no es específica de ningún idioma o base de datos), sino más de diseño y arquitectura. También es una cuestión del tipo "Cuál es la mejor manera de hacer X". Espero que no cause mucha controversia "religiosa".Diseño de la base de datos de inventarios

En el pasado he desarrollado sistemas que de una forma u otra, mantienen algún tipo de inventario de artículos (no relevante qué artículos). Algunos utilizan lenguajes/bases de datos que no admiten transacciones. En esos casos, opté por no guardar el artículo cantidad a mano en un campo en el registro del artículo. En cambio, la cantidad disponible se calcula sumando el inventario recibido - total del inventario vendido. Esto ha resultado en casi ninguna discrepancia en el inventario debido al software. Las tablas están indexadas correctamente y el rendimiento es bueno. Existe un proceso de archivo en caso de que la cantidad de registro comience a afectar el rendimiento.

Ahora, hace unos años comencé a trabajar en esta empresa, y heredé un sistema que realiza un seguimiento del inventario. Pero la cantidad se guarda en un campo. Cuando se registra una entrada, la cantidad recibida se agrega al campo de cantidad para el artículo. Cuando se vende un artículo, se resta la cantidad. Esto ha resultado en discrepancias. En mi opinión, este no es el enfoque correcto, pero los programadores anteriores aquí lo juran.

Me gustaría saber si hay un consenso sobre cuál es la forma correcta de diseñar dicho sistema. También qué recursos están disponibles, impresos o en línea, para buscar orientación al respecto.

Gracias

+13

Cuando dice "los programadores anteriores aquí lo juran", ¿quiere decir que juran cada vez que tienen que trabajar en ello? – MusiGenesis

Respuesta

47

He visto ambos enfoques en mi empresa actual y definitivamente me inclinaría hacia el primero (calcular los totales basados ​​en transacciones de valores).

Si solo está almacenando una cantidad total en un campo en alguna parte, no tiene idea de cómo llegó a ese número. No hay historial de transacciones y puede terminar con problemas.

El último sistema que escribí hace un seguimiento del stock almacenando cada transacción como un registro con una cantidad positiva o negativa. He encontrado que funciona muy bien.

+1

+1 Tuve el mismo dilema y creo que esta es la mejor opción – INS

+3

@Neil. ¿Puede comentar sobre el rendimiento de este enfoque? parece ser el enfoque preferido, pero si tiene cientos de productos y miles de transacciones, ¿cómo o cuándo calcula los totales acumulados? ¿o solo está almacenando el total acumulativo en otro lugar con la tranquilidad de saber que puede volver a calcular si es necesario? –

+0

@Simon Es lógico pensar que sería considerablemente menos eficiente que solo consultar un campo. Debo decir que nunca lo perfilé con una gran cantidad de productos. Sería mejor intentarlo y ver qué tipo de rendimiento obtiene en su conjunto de datos. Luego, decida si vale la pena almacenar en caché la cantidad en alguna parte. –

3

optaría por el primer camino, donde

se calcula la cantidad disponible inventario total recibida - total de inventario vendido

la manera correcta, IMO.

EDIT: También me gustaría tener en cuenta las pérdidas/daños en el sistema, pero estoy seguro de que tiene eso cubierto.

9

Depende, los sistemas de inventario son mucho más que simplemente contar elementos. Por ejemplo, para fines contables, es posible que necesite conocer el valor contable del inventario en base al modelo FIFO (Primero en entrar, primero en salir). Eso no se puede calcular por simple fórmula de "totalización de inventario recibido - total de inventario vendido". Pero su modelo podría calcular esto fácilmente, porque modifican el valor contable a medida que avanzan. No quiero entrar en detalles porque esto no es un problema de programación, pero si lo juran, quizás no entendieron completamente todos sus requisitos que deben cumplir.

4

Es importante tener en cuenta el sistema existente y el costo y el riesgo de cambiarlo.Trabajo con una base de datos que almacena un tipo de inventario como el tuyo, pero incluye ciclos de auditoría y ajustes de tiendas al igual que los recibos. Parece que funciona bien, pero todos los involucrados están bien capacitados, y el personal del almacén no es exactamente rápido para aprender nuevos procedimientos.

En su caso, si está buscando un poco más de seguimiento sin cambiar toda la estructura de db, le sugiero que agregue una tabla de seguimiento (similar a su solución de transacción) y luego registre los cambios en el Nivel del inventario. No debería ser demasiado difícil actualizar la mayoría de los cambios en el nivel de inventario para que también dejen un registro de transacción. También puede agregar una tarea periódica para hacer una copia de seguridad del nivel de inventario en la tabla de transacciones cada dos horas aproximadamente para que, incluso si pierde una transacción, puede descubrir cuándo sucedió el cambio o volver a un estado anterior.

Si quiere ver cómo funciona una gran aplicación, eche un vistazo a SugarCRM, tienen un módulo de administración de inventario aunque no estoy seguro de cómo almacena los datos.

1

Veo algunas ventajas de tener las dos columnas, pero no estoy siguiendo la parte sobre las discrepancias: parece implicar que tener las dos columnas (dentro y fuera) es menos propenso a la discrepancia que una sola columna (corriente). ¿Porqué es eso?

7

ambos son válidos, dependiendo de las circunstancias. El primero es mejor cuando se cumplen las siguientes condiciones:

  • el número de elementos a suma es relativamente pequeño
  • existen pocas o ninguna casos excepcionales a tener en cuenta (devoluciones, ajustes, et al)
  • el inventario la cantidad de artículo no se necesita muy a menudo

, por otro lado, si usted tiene un gran número de artículos, varios casos excepcionales, y el acceso frecuente, será más eficiente para mantener la cantidad del artículo

en cuenta también que si el sistema tiene discrepancias entonces tiene errores que deben ser localizados y eliminados

he hecho los sistemas de ambas maneras, y ambas formas se puede trabajar muy bien - siempre y cuando no ignorar ¡los insectos!

+0

hmm. vuelve no es realmente excepcional ¿verdad? a menos que esté vendiendo artículos puramente perecederos o cualquier otra cosa que no pueda ser revendida –

+2

@Simon: uno de los primeros sistemas de inventario que escribí fue para una heladería personalizada.Las devoluciones no solo fueron excepcionales, sino que fueron prácticamente imposibles ;-) –

3

Creo que esta es una pregunta general sobre mejores prácticas para hacer un recuento (relativamente) caro cada vez que necesita un total vs. hacerlo que cuenta cada vez que algo cambia, luego almacenar el conteo en un campo y leer ese campo cuando necesites un total

Si no pudiera usar las transacciones, iría con el recuento en vivo cada vez que necesitara un total. Si hay transacciones disponibles, sería seguro realizar las operaciones de actualización del inventario y el ahorro del total contabilizado dentro de la misma transacción, lo que garantizaría la precisión del conteo (aunque no estoy seguro de que esto funcione con múltiples usuarios). golpeando la base de datos).

Pero si el rendimiento no es realmente un gran problema (y las bases de datos modernas son lo suficientemente buenas para contar filas que rara vez me preocuparía por esto), me quedaría con el conteo en vivo cada vez.

0

es no tener una o dos columnas, lo que quería decir con "un total de inventario recibido - total del inventario vendido" es algo como esto:

Select sum(quantity) as inventory_received from Inventory_entry 
Select sum(quantity) as inventory_sold from Sales_items 

continuación

Qunatity_on_hand = inventory_received - inventory_sold 

Por favor, tenga en cuenta que simplifiqué esto y mi explicación inicial. Sé que hay mucho más para inventariar que simplemente hacer un seguimiento de las cantidades, pero en este caso, ese es el problema y lo que queremos solucionar. En este punto, el motivo para cambiarlo es precisar el costo de soportar los problemas causados ​​por el diseño actual.

También quería mencionar que, si bien esto no es una "codificación" pregunta está relacionada con algoritms y diseño que en mi humilde opinión, son temas muy importantes.

Gracias a todos por sus respuestas hasta el momento.

Nelson Mármol

+1

El inconveniente de esta solución en particular es que el rendimiento empeorará con el tiempo, ya que debe mantener un registro de todo el inventario recibido o vendido indefinidamente, en orden para obtener la cantidad actual correcta! –

0

Nos resolver diferentes problemas, pero nuestro enfoque de algunos de ellos podría ser interesante para usted.

permitimos que el sistema para hacer una "mejor estimación", y dar a los usuarios información periódica sobre cualquiera de esas conjeturas que se ven mal.

aplicar esto a inventario, usted podría tener 3 campos:

inventory_received 
inventory_sold 
estimated_on_hand 

A continuación, puede ejecutar un proceso a lo largo de las líneas de (todos los días?):

SELECT * 
FROM Inventory 
WHERE estimated_on_hand != inventory_received - inventory_sold 

Por supuesto, esto confía en los usuarios que miran esta alerta y hacen algo al respecto.

Además, podría tener una función para restablecer el inventario de alguna manera, ya sea actualizando inventory_sold/received, o tal vez agregando otro campo "inventory_adjustment", que podría ser positivo o negativo.

... solo algunos pensamientos. Espero que sea útil.

5

Tome una mirada en el modelo de datos ARTS (Asociación de Estándares de Tecnologías de venta al por menor) (http://nrf-arts.org). Utiliza una tabla StockLedger con un registro de cada elemento y los cambios en el inventario se rastrean en InventoryJournalEntries.

1

He trabajado en sistemas que resuelvan este problema antes. Creo que la solución ideal es una columna precalculada, que te ofrece lo mejor de ambos mundos. Su total sería un campo en algún lugar, por lo tanto, no hay costosas búsquedas, pero no se puede desconectar con el resto de sus datos (la base de datos mantiene la integridad). No recuerdo qué RDMS admiten columnas precalculadas, pero si no tiene transacciones, es posible que tampoco estén disponibles.

Es posible que falsifique columnas precalculadas (de forma muy efectiva ... No veo ninguna desventaja) utilizando desencadenantes. Sin embargo, probablemente necesites transacciones. En mi humilde opinión, mantener la integridad de los datos cuando se está haciendo este tipo de desnormalización controlada es el único uso legítimo para un desencadenante.

1

Django-inventory orientado más a activos fijos, pero podría darle algunas ideas.

IE: ItemTemplate (clase) -> ItemsOnHand (instancia)

ItemsOnHand puede estar vinculado a más ItemTemplates; Ejemplo de impresora & requiere cartuchos de tinta. Esto también permite establecer puntos de Reorden para cada ItemOnHand.

Cada ItemsOnHand está vinculado a InventoryTransactions, esto permite una fácil auditoría. Para evitar el cálculo de artículos reales de miles de transacciones inventadas, se utilizan puntos de control que son solo un saldo + una fecha. Para calcular elementos en consulta manual, busque el punto de control más reciente y comience a agregar o sustraer elementos para encontrar el saldo actual de los artículos. Definir nuevos puntos de control periódicamente.

Cuestiones relacionadas