web-dev-qa-db-fra.com

Conception de la base de données d'inventaire

Il ne s'agit pas vraiment de "programmation" (n'est spécifique à aucun langage ou base de données), mais plutôt de conception et d'architecture. C'est aussi une question du type "Quelle est la meilleure façon de faire X". J'espère que cela ne cause pas beaucoup de controverse "religieuse".

Dans le passé, j'ai développé des systèmes qui, d'une manière ou d'une autre, gardent une certaine forme d'inventaire des articles (sans pertinence quels articles). Certains utilisent des langues/bases de données qui ne prennent pas en charge les transactions. Dans ces cas, j'ai choisi de ne pas enregistrer l'article quantité en stock dans un champ de l'enregistrement d'article. Au lieu de cela, la quantité en stock est calculée en totalisant l'inventaire reçu - total de l'inventaire vendu. Cela n'a entraîné pratiquement aucun écart dans l'inventaire en raison des logiciels. Les tables sont correctement indexées et les performances sont bonnes. Il existe un processus d'archivage au cas où la quantité d'enregistrement commencerait à affecter les performances.

Il y a quelques années, j'ai commencé à travailler dans cette entreprise et j'ai hérité d'un système de suivi des stocks. Mais la quantité est enregistrée dans un champ. Lorsqu'une entrée est enregistrée, la quantité reçue est ajoutée au champ de quantité de l'article. Lorsqu'un article est vendu, la quantité est soustraite. Cela a entraîné des écarts. À mon avis, ce n'est pas la bonne approche, mais les programmeurs précédents ne jurent que par elle.

J'aimerais savoir s'il existe un consensus sur la bonne façon de concevoir un tel système. Quelles sont également les ressources disponibles, imprimées ou en ligne, pour obtenir des conseils à ce sujet.

Merci

72
nmarmol

J'ai vu les deux approches dans mon entreprise actuelle et je pencherais certainement vers la première (calcul des totaux sur la base des transactions boursières).

Si vous ne stockez qu'une quantité totale dans un champ quelque part, vous ne savez pas comment vous êtes arrivé à ce nombre. Il n'y a pas d'historique transactionnel et vous pouvez vous retrouver avec des problèmes.

Le dernier système que j'ai écrit stocke les pistes en stockant chaque transaction sous forme d'enregistrement avec une quantité positive ou négative. J'ai trouvé que cela fonctionne très bien.

49
Neil Aitken
16
Patrick Cuff

Cela dépend, les systèmes d'inventaire vont bien au-delà du simple comptage des articles. Par exemple, à des fins de comptabilité, vous devrez peut-être connaître la valeur comptable de l'inventaire en fonction du modèle FIFO (premier entré, premier sorti). Cela ne peut pas être calculé par un simple "inventaire total" reçu - formule du total des stocks vendus ". Mais leur modèle pourrait calculer cela facilement, car ils modifient la valeur comptable au fur et à mesure. Je ne veux pas entrer dans les détails car ce n'est pas un problème de programmation mais s'ils le jurent, peut-être que vous ne comprenait pas pleinement toutes leurs exigences, ils doivent s'adapter.

9
lubos hasko

les deux sont valables, selon les circonstances. Le premier est meilleur lorsque les conditions suivantes sont réunies:

  • le nombre d'articles à additionner est relativement faible
  • il y a peu ou pas de cas exceptionnels à considérer (retours, ajustements, etc.)
  • la quantité d'articles en stock n'est pas nécessaire très souvent

d'autre part, si vous avez un grand nombre d'articles, plusieurs cas exceptionnels et un accès fréquent, il sera plus efficace de maintenir la quantité d'articles

notez également que si votre système présente des anomalies alors il a des bugs qui doivent être traqués et éliminés

j'ai fait des systèmes dans les deux sens, et les deux peuvent fonctionner très bien - tant que vous n'ignorez pas les bugs!

7
Steven A. Lowe

Jetez un œil au modèle de données ARTS (Association for Retail Technology Standards) ( http://nrf-arts.org ). Il utilise une table StockLedger avec un enregistrement de chaque article et les modifications de l'inventaire sont toutes suivies dans InventoryJournalEntries.

5
Eddie Deyo

Je pense que c'est en fait une question générale sur les meilleures pratiques pour faire un décompte (relativement) cher à chaque fois que vous avez besoin d'un total par rapport à faire ce décompte chaque fois que quelque chose change, puis stocker le décompte dans un champ et lire ce champ chaque fois que vous avez besoin d'un total.

Si je ne pouvais pas utiliser de transactions, j'utiliserais le décompte en direct chaque fois que j'avais besoin d'un total. Si des transactions sont disponibles, il serait sûr d'effectuer les opérations de mise à jour de l'inventaire et d'économiser le total recompté dans la même transaction, ce qui garantirait l'exactitude du comptage (bien que je ne suis pas sûr que cela fonctionnerait avec plusieurs utilisateurs frapper la base de données).

Mais si les performances ne sont pas vraiment un énorme problème (et les bases de données modernes sont assez bonnes pour compter les lignes que je ne m'inquiéterais même pas à ce sujet), je m'en tiendrai à chaque fois au décompte en direct.

4
MusiGenesis

Il est important de considérer le système existant et le coût et le risque de le changer. Je travaille avec une base de données qui stocke les stocks un peu comme la vôtre, mais elle comprend des cycles d'audit et stocke les ajustements tout comme les reçus. Cela semble bien fonctionner, mais toutes les personnes impliquées sont bien formées et le personnel de l'entrepôt n'est pas exactement rapide à apprendre de nouvelles procédures.

Dans votre cas, si vous recherchez un peu plus de suivi sans modifier toute la structure de la base de données, je vous suggère d'ajouter une table de suivi (un peu comme dans votre solution de `` transaction ''), puis de consigner les modifications au niveau de l'inventaire. Il ne devrait pas être trop difficile de mettre à jour la plupart des modifications apportées au niveau de l'inventaire afin qu'elles laissent également un enregistrement de transaction. Vous pouvez également ajouter une tâche périodique pour sauvegarder le niveau d'inventaire dans la table des transactions toutes les deux heures environ, de sorte que même si vous manquez une transaction, vous pouvez découvrir quand la modification s'est produite ou revenir à un état précédent.

Si vous voulez voir comment une grande application peut-elle jeter un œil à SugarCRM , ils ont un module de gestion des stocks, mais je ne sais pas comment il stocke les données.

4
Eric Goodwin

J'opterais pour la première façon, où

la quantité disponible est calculée en totalisant l'inventaire reçu - total de l'inventaire vendu

La bonne façon, l'OMI.

EDIT: Je voudrais également tenir compte de toute perte de stock/dommages dans le système, mais je suis sûr que vous avez couvert cela.

3
Galwegian

Django-inventaire davantage axé sur les immobilisations, mais pourrait vous donner quelques idées.

IE: ItemTemplate (classe) -> ItemsOnHand (instance)

ItemsOnHand peut être lié à d'autres modèles ItemTemplates; Exemple L'imprimante et les cartouches d'encre sont nécessaires. Cela permet également de définir des points de réorganisation pour chaque ItemOnHand.

Chaque ItemsOnHand est lié à InventoryTransactions, ce qui permet un audit facile. Pour éviter de calculer les articles en stock réels à partir de milliers de transactions invétoires, des points de contrôle sont utilisés qui ne sont qu'un solde + une date. Pour calculer les éléments disponibles, recherchez le point de contrôle le plus récent et commencez à ajouter ou à soustraire des éléments pour trouver le solde actuel des éléments. Définissez périodiquement de nouveaux points de contrôle.

2
Roberto Rosario

J'ai déjà travaillé sur des systèmes qui résolvent ce problème. Je pense que la solution idéale est une colonne précalculée, qui vous offre le meilleur des deux mondes. Votre total serait un champ quelque part, donc pas de recherches coûteuses, mais il ne peut pas se désynchroniser avec le reste de vos données (la base de données maintient l'intégrité). Je ne me souviens pas quels RDMS prennent en charge les colonnes précalculées, mais si vous n'avez pas de transactions, cela pourrait ne pas être disponible non plus.

Vous pourriez potentiellement simuler des colonnes précalculées (très efficacement ... je ne vois aucun inconvénient) en utilisant des déclencheurs. Vous auriez probablement besoin de transactions cependant. À mon humble avis, le maintien de l'intégrité des données lorsque vous effectuez ce type de dénormalisation contrôlée est la seule utilisation légitime d'un déclencheur.

2
rmeador

Je peux voir un certain avantage à avoir les deux colonnes, mais je ne suis pas en train de suivre la partie sur les écarts - vous semblez impliquer que le fait d'avoir les deux colonnes (en entrée et en sortie) est moins sujet aux écarts qu'une seule colonne (actuelle). Pourquoi donc?

1
JoeBloggs

N'ayant pas une ou deux colonnes, ce que je voulais dire par "total des stocks reçus - total des stocks vendus" est quelque chose comme ceci:

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

ensuite

Qunatity_on_hand = inventory_received - inventory_sold

Veuillez garder à l'esprit que j'ai trop simplifié cela et mon explication initiale. Je sais qu'il y a beaucoup plus à inventer que de simplement garder une trace des quantités, mais dans ce cas, c'est le problème qui réside et ce que nous voulons résoudre. À ce stade, la raison du changement est précisément le coût de prise en charge des problèmes causés par la conception actuelle.

Je voulais également mentionner que bien que ce ne soit pas une question de "codage", elle est liée aux algoritmes et à la conception, à mon humble avis, qui sont des sujets très importants.

Merci à tous pour vos réponses jusqu'à présent.

Nelson Marmol

0
nmarmol

Nous résolvons différents problèmes, mais notre approche de certains d'entre eux pourrait vous intéresser.

Nous permettons au système de faire une "meilleure supposition" et donnons aux utilisateurs des commentaires réguliers sur toutes ces suppositions qui semblent fausses.

Pour appliquer cela à l'inventaire, vous pouvez avoir 3 champs:

inventory_received
inventory_sold
estimated_on_hand

Ensuite, vous pouvez exécuter (quotidiennement?) Un processus dans le sens de:

SELECT * 
FROM   Inventory
WHERE  estimated_on_hand != inventory_received - inventory_sold

Bien sûr, cela dépend des utilisateurs qui regardent cette alerte et y font quelque chose.

En outre, vous pouvez avoir une fonction pour réinitialiser l'inventaire, en mettant à jour l'inventaire_vendu/reçu, ou peut-être en ajoutant un autre champ "inventaire_ajuste", qui peut être positif ou négatif.

... juste quelques réflexions. J'espère que c'est utile.

0
AJ.