IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Ma Gestion de stocks avec 2 triggers , votre avis


Sujet :

Langage SQL

  1. #1
    Invité
    Invité(e)
    Par défaut Ma Gestion de stocks avec 2 triggers , votre avis
    Bonjour tout le monde et bonne journée .

    Voilà j'ai un projet d'école, plus ou moins pour le fun, et j'ai un gestion de stock à faire.
    Pour l'instant, ma reflexion (Prôôôfonde) a abouti à ce schéma MCD :

    Nom : gestionstocks.png
Affichages : 1056
Taille : 14,1 Ko

    - La table stockCarburant est censée être en permanence à jour du calcul des stocks, afin d'être requêtée dans l'application, en AJAX.

    - Les deux tables venteCarburant et reassortCarburant sont des "journaux" statiques -et inaccessibles en modification et suppression(sauf action spéciale)- de mouvements de stocks, avec donc une colonne date, ils seront accessibles en lecture dans l'application. Admettons que j'ai 5 stations services, et un total de 30 citernes, ces tables vont (en théorie) s'alourdir très rapidement de dizaines de lignes... Ces tables auraient également une valeur en cas de litige.


    En fait, maintenant, je prévoie de créer 2 triggers :

    1 qui s'exécute lors d'une vente et qui décrémente le stock de x litres de carburant.
    1 qui s'exécute lors du remplissage de la citerne et qui incrémente le stock de x litres de carburant.

    Tout cela toujours en fonction de idciterne, parce que il y a des dizaines de citernes différentes.

    Les deux triggers sont placés sur les tables ventecarburant et reassortcarburant et pointent sur la table stockcarburant.



    Cette logique vous parait-elle bonne ?

    Mon but étant d'avoir une table renseignant les stocks toujours à jour, sans avoir à coder ce système avec du JS ou du PHP, ou même du JAVA.


    Pour l'instant, je n'ai pas encore réflechi à la syntaxe des triggers mais j'ai entendu parler de "NEW" et de "OLD", mais je flippe ... Ca à l'air sacrément dur !
    je précise que les champs date sont en Varchar parce que je travaille avec des objets date en JS, mais ça on s'en fout vis-à-vis du post .

    Faut-il ajouter un 3 ème trigger qui signale si le volume disponible est dépassé ? Merci
    Dernière modification par Invité ; 16/08/2016 à 14h27.

  2. #2
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Utiliser des triggers est effectivement une possibilité, mais je ne suis pas sur que cela soit la méthode la plus adaptée.

    Il vaudrait mieux que tu utilises des procédures stockées.

    Ensuite tu peux également rajouter des contraintes. Par exemple, une qui viendrait vérifier que le stock de carburant est >=0 (cela viendrait empêcher une vente trop importante par rapport aux réserves disponibles).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup, je vais essayer d'étudier les procédures stockées puis de choisir la solution la plus viable (Sans éliminer la possiblité du code back end finalement.).

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Quelques remarques concernant votre modèle :
    Tout d'abord il ne s'agit pas d'un MCD puisque vous décrivez des tables, il s'agit donc d'un MPD

    Ensuite, je suppose que c'est pour s'entrainer aux jointures que vous avez modélisé 3 tables, car une seule aurait suffi : dans le mesure où l'identifiant est le même dans les 3 tables et puisque les attributs, peu nombreux, sont les mêmes, il faut bien une et une seule table.

    Concernant les types de données, ne décrivez JAMAIS de colonne date avec un type autre que DATE (ou DATETIME ou TIMESTAMP), utiliser varchar pour une date est une hérésie très lourde de conséquences.
    Toute colonne de poids ou mesure, doit toujours être accompagnée d'une colonne indiquant l'unité de mesure correspondante.
    Ici le volume pour une personne qui fait le plein de sa voiture sera exprimé en litres, mais lorsque vous commanderez un réapprovisionnement, le livreur négociera probablement des prix à l'hectolitre, voire au mêtre cube.
    Si vous voulez totaliser correctement, il faut donc l'unité de mesure
    De plus decimal 2,0 est insuffisant (si vous gérez en litres, vous devrez refuser tous les clients poids lourd )

    Enfin, utiliser un type integer pour un identifiant est une bonne chose, mais choisir integer(11) est une mauvaise idée car vous augmentez inutilement la taille de l'identifiant, d'où une charge CPU et réseau inutile.
    Même si vous possédez un très grand nombre de stations service, avec un integer de base (encombrement 4 octets) vous pouvez gérer jusqu'à 4 294 967 295 pompes à essence !
    Je pense que ça devrait suffire

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Je ne voulais pas aborder la question du MPD dans la mesure où ce n'était pas le sujet de la question, mais suite au commentaire de escartefigue, quelques éléments m'interpelle

    Citation Envoyé par escartefigue Voir le message
    une seule aurait suffi : dans le mesure où l'identifiant est le même dans les 3 tables et puisque les attributs, peu nombreux, sont les mêmes, il faut bien une et une seule table.
    Depuis quand un nombre de colonnes faible indique qu'il faut tout regrouper au sein d'une seule et même table ? C'est la meilleure manière d'avoir des tables obèses avec des NULL induits.

    Citation Envoyé par escartefigue Voir le message
    Concernant les types de données, ne décrivez JAMAIS de colonne date avec un type autre que DATE (ou DATETIME ou TIMESTAMP), utiliser varchar pour une date est une hérésie très lourde de conséquences.
    D'accord en général. Le seul cas que je vois où l'on pourrait dérroger à cette règle, c'est si :
    • On ne fait pas de calcul sur la date (pas de comparaison, pas de calcul de date en ajoutant 1 mois, etc...) et...
    • ...La mise en forme de la date est aussi importante que la date elle même (et peut varier d'une date à l'autre) et/ou la date n'est pas forcément une date grégorienne.


    Citation Envoyé par escartefigue Voir le message
    Toute colonne de poids ou mesure, doit toujours être accompagnée d'une colonne indiquant l'unité de mesure correspondante.
    Ici le volume pour une personne qui fait le plein de sa voiture sera exprimé en litres, mais lorsque vous commanderez un réapprovisionnement, le livreur négociera probablement des prix à l'hectolitre, voire au mêtre cube.
    Si vous voulez totaliser correctement, il faut donc l'unité de mesure
    Ou s'assurer qu'une seule et même unité est utilisée au sein de la base. En pratique, je préfère une homogénéisation de l'unité utilisée (et je suffixe le nom de la colonne par l'unité en question). Cela facilite la manipulation des valeurs. Mais là, c'est une approche plus personnel

    Citation Envoyé par escartefigue Voir le message
    De plus decimal 2,0 est insuffisant (si vous gérez en litres, vous devrez refuser tous les clients poids lourd )

    Enfin, utiliser un type integer pour un identifiant est une bonne chose, mais choisir integer(11) est une mauvaise idée car vous augmentez inutilement la taille de l'identifiant, d'où une charge CPU et réseau inutile.
    Même si vous possédez un très grand nombre de stations service, avec un integer de base (encombrement 4 octets) vous pouvez gérer jusqu'à 4 294 967 295 pompes à essence !
    Je pense que ça devrait suffire
    Tout à fait d'accord. Autrement dit : toujours bien définir son type en fonction des données et des besoins
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 769
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 769
    Points : 52 720
    Points
    52 720
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Ensuite, je suppose que c'est pour s'entrainer aux jointures que vous avez modélisé 3 tables, car une seule aurait suffi : dans le mesure où l'identifiant est le même dans les 3 tables et puisque les attributs, peu nombreux, sont les mêmes, il faut bien une et une seule table.
    Évidemment non, le fait d'utiliser le même nom pour la clef de différentes tables est une imbécilité flagrante que l'on retrouve souvent chez les gens ne maitrisant pas la modélisation et faisant tout dans le MPD... Cependant dans ce MPD il manque les contraintes d'IR liant les tables...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par dorinf Voir le message
    Depuis quand un nombre de colonnes faible indique qu'il faut tout regrouper au sein d'une seule et même table ? C'est la meilleure manière d'avoir des tables obèses avec des NULL induits.
    Vous avez visiblement mal lu non seulement mon post, mais surtout le post initial : les 3 tables du modèle proposé ont en tout et pour tout un même idenfitiant et deux attributs identiques : quantité et date , soit 3 colonnes !
    Et vous parlez de table obèse

    Citation Envoyé par dorinf Voir le message
    D'accord en général. Le seul cas que je vois où l'on pourrait dérroger à cette règle, c'est si :
    • On ne fait pas de calcul sur la date (pas de comparaison, pas de calcul de date en ajoutant 1 mois, etc...) et...
    • ...La mise en forme de la date est aussi importante que la date elle même (et peut varier d'une date à l'autre) et/ou la date n'est pas forcément une date grégorienne.
    Quand bien même, une date en varchar implique de déléguer à l'application le contrôle de format pour éviter de mélanger dans une même colonne des valeurs tantot en AA-MM-JJ, CCAA-MM-JJ, JJ/MM/CCAA etc....
    Sans compter l'encombrement inutile lié à un format inadapté.
    Donc définitivement non, une date doit être stockée dans un format date

    Citation Envoyé par dorinf Voir le message
    Ou s'assurer qu'une seule et même unité est utilisée au sein de la base. En pratique, je préfère une homogénéisation de l'unité utilisée (et je suffixe le nom de la colonne par l'unité en question). Cela facilite la manipulation des valeurs. Mais là, c'est une approche plus personnel
    C'est une possibilité, mais rarement applicable, cas typique : une base articles, certains articles sont comptabilisés au mètre linéaire, d'autres à la pièce, au mètre cube, au pack, à la douzaine etc... Problème très courant dans l'industrie et la grande distribution
    Le cas où l'on ne peut avoir qu'une seule unité de mesure, hors MCD scolaire, est très marginal. Prévoir une unité de mesure associée à chaque mesure est donc une précaution nécessaire.

  8. #8
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Vous avez visiblement mal lu non seulement mon post, mais surtout le post initial : les 3 tables du modèle proposé ont en tout et pour tout un même idenfitiant et deux attributs identiques : quantité et date , soit 3 colonnes !
    Et vous parlez de table obèse
    Autrement dit : j'ai 20 tables avec 3 colonnes. Il vaut mieux en avoir 1 avec 22 colonnes ?

    Citation Envoyé par escartefigue Voir le message
    Quand bien même, une date en varchar implique de déléguer à l'application le contrôle de format pour éviter de mélanger dans une même colonne des valeurs tantot en AA-MM-JJ, CCAA-MM-JJ, JJ/MM/CCAA etc....
    Sans compter l'encombrement inutile lié à un format inadapté.
    Donc définitivement non, une date doit être stockée dans un format date
    Je m'attendais à cela. Et je persiste en donnant un exemple cette fois-ci
    Dans le domaine de la santé par exemple, et plus particulièrement des informations contenues dans la carte vitale, on gère des dates de naissances. Or, le format même de la date est utilisé dans certains algo (par exemple, calcul de l'INS-C). Aussi, dans ce cas, il est impératif de disposer de la date telle quelle est définie à la source et non d'avoir sa représentation, au risque d'avoir un calcul erroné

    Et c'est tellement bien foutu qu'en plus les dates peuvent ne pas être valides (genre 00/01/2000). Oui oui, ce n'est pas une erreur de saisie, le 0 janvier de l'année 2000 !
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  9. #9
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par dorinf Voir le message
    Autrement dit : j'ai 20 tables avec 3 colonnes. Il vaut mieux en avoir 1 avec 22 colonnes ?
    Mais bon sang ce n'est pas du tout ce que je dis, c'est très désagréable de voir mes propos déformés, et relisez !
    Je dis, dans ce cas précis : IL VAUT MIEUX UNE TABLE AVEC 3 COLONNES QUE 3 TABLES AVEC ÉGALEMENT 3 COLONNES

    Citation Envoyé par dorinf Voir le message
    Je m'attendais à cela. Et je persiste en donnant un exemple cette fois-ci
    Dans le domaine de la santé par exemple, et plus particulièrement des informations contenues dans la carte vitale, on gère des dates de naissances. Or, le format même de la date est utilisé dans certains algo (par exemple, calcul de l'INS-C). Aussi, dans ce cas, il est impératif de disposer de la date telle quelle est définie à la source et non d'avoir sa représentation, au risque d'avoir un calcul erroné

    Et c'est tellement bien foutu qu'en plus les dates peuvent ne pas être valides (genre 00/01/2000). Oui oui, ce n'est pas une erreur de saisie, le 0 janvier de l'année 2000 !
    Je connais très bien ce genre de problème pour être intervenu de nombreuses années dans le domaine de la prévoyance et de la retraite complémentaire, notamment dans la certification des NNI (on parle de NIR désormais) via le processus PRC, sans doute ceci vous parle-t-il.
    Le calendrier "lunaire" appliqué dans certains pays provoque des pseudo-dates déroutantes
    Donc, oui, il existe des dates non fiable dans ce secteur d'activité et dans bien d'autres.
    Et donc... ce ne sont pas des dates, du moins pas encore tant que non fiabilisées.
    Il faut en ce cas définir un champ non date, pas en varchar mais en char, le varchar pour une colonne de petite taille présente plus d'inconvénients que d'avantage : gestion de l'attribut longueur, risque de désorganisation des pages etc...

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Concernant la modélisation...

    Comme Escartefigue, j'opterais pour une seule table :
    1/ la table des stock n'a pas de raison d'être puisque le stock résulte du calcul de la somme des réassorts moins la somme des ventes... (faire une vue serait plus approprié)
    2/ les tables reassort et vente peuvent faire l'objet d'une seule table "mouvement", avec le volume des ventes en négatif.
    En cas d'évolution, (par exemple le besoin de préciser un fournisseur pour les réassorts uniquement), alors il conviendra de mettre en place un héritage.
    ainsi, pas de NULL inutiles mais globalement des requêtes simplifiées (ne serait-ce que, justement, pour la calcul des stocks)

    Avec tout cela... plus besoin de trigger.

    Concernant le stockage des dates... il me semble que tout le monde est d’accord !
    Pour stocker des dates, utiliser le format date
    Pour stocker du texte (même si le texte contient parfois des dates, ou quelque chose qui y ressemble), utiliser du [VAR]CHAR].

    Enfin, concernant l'ajout de l'unité, cela me semble superflu compte tenu de la simplicité du problème. En l'occurence, cela se résumera certainement en une colonne monotone contenant tout le temps l'information "litre"...
    Il me semble bien suffisant comme le stipule dorinf de convenir d'une unité (par exemple le litre) et de le préciser dans la nom de la colonne en effet (en plus de la doc )
    Si les réassorts se font en m3, la conversion devrait être à la portée de tous !
    Et si le besoin venait à évoluer, il ne sera pas trop tard pour ajouter une colonne indiquant l'unité.

  11. #11
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Ben un problème aussi trivial qui passionne autant les foules, c'est amusant.

    Concernant le choix de 1 ou 3 tables :

    - La table "stock" a toute sa raison d'être : c'est le point d'entrée, c'est ça qui permet de savoir de quelle citerne on parle.
    - Les deux tables "reassort" et "vente" peuvent en effet éventuellement être fusionnées, avec un "type" ou simplement l'utilisation d'un signe qui indique si on fait une sortie (-) ou une entrée (+).

    Concernant la vue pour déterminer le volume actuel de la citerne, je suis absolument contre.
    En effet, il y a des limites à vouloir normaliser à tous prix.
    Le volume doit être considéré comme une donnée à part entière, pour plusieurs raisons :

    - Premièrement, après 10 ans d'activité, avec des centaines de vente par jour et des dizaines de réassort par mois, la vue va être anormalement lente.
    => Dans ce cas, on pourrait opter, si le SGBD le permet, pour une colonne calculée (SQL Server par exemple le permet).

    - Deuxièmement, une citerne, c'est pas totalement hermétique. Il y a de l'évaporation. Aussi, quand on rempli une citerne, on risque d'en reverser, idem à la vente.
    => Par conséquent, après quelques opérations de remplissage/vidage, la somme des mouvements ne sera pas forcément égale au niveau de la citerne. Le delta va croître avec le temps. Et si on veut faire une régulation, on va devoir saisir un réassort ou une vente qui n'a pas eu lieu : on pollue les données pour résoudre une erreur de conception.

    On peut imaginer diverses solutions pour résoudre les deux problèmes, en s'entêtant à ne pas stocker le volume :
    - Créer une table "inventaire" ou ("relevé") horodatée, avec un volume.
    => Ainsi, on connaît le volume de la citerne en prenant le relevé le plus récent, puis en lui ajoutant toutes les entrées et sorties qu'il y a eu depuis. C'est pas mal, mais pour moi c'est encore une usine à gaz.

    - Purger la table des mouvements en remplaçant tous les anciens mouvements par un nouveau, à une date antérieure, ayant un solde égal à la somme des mouvements purgés.
    => On perd de l'info, et ça demande des traitements lourds pour pas grand chose.

    J'ai pas trop la tête à imaginer des usines à gaz, mais il y a certainement des tas de possibilités pour transformer ce problème simple en usine à gaz.

    Donc pour moi, trois tables :
    - Une table STOCK avec une colonne "VOLUME COURANT"
    - Une table MOUVEMENT avec deux vues qui pointent dessus "VENTE" et "REASSORT"
    - Une table RELEVE

    2 triggers :
    - Sur MOUVEMENT, incrémente/décrémente le volume de la citerne en fonction des lignes insérées SI LEUR DATE DE SAISIE EST ULTERIEURE A LA DERNIERE DATE DE RELEVE
    - Sur RELEVE, remplace le volume de la citerne par la ligne la plus récente (attention, pas forcément celle en cours de mise à jour), et y ajoute la somme des MOUVEMENTS ayant une date ultérieure à cette date

    Et là tu dois avoir un truc propre qui tiens la route, aussi bien d'un point de vue cohérence que d'historisation des données.

    Tu peux remplacer ces deux triggers, si tu utilises SQL Server, par une colonne calculée qui fait "volume dernier relevé + somme mouvements depuis le dernier relevé". Je trouve ça plus propre (un seul code à maintenir, plus simple qui plus est).
    On ne jouit bien que de ce qu’on partage.

  12. #12
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Mais bon sang ce n'est pas du tout ce que je dis, c'est très désagréable de voir mes propos déformés, et relisez !
    Je dis, dans ce cas précis : IL VAUT MIEUX UNE TABLE AVEC 3 COLONNES QUE 3 TABLES AVEC ÉGALEMENT 3 COLONNES
    Sauf que les tables n'ont pas la même structure ici. Elles ont presque la même structure. Faire une seule et même table revient à avoir un NULL induit pour les enregistrements de la table "stockcarburant". Et c'est en ça que cela peut être dangereux et mener à des tables obèses. C'est un processus à ne pas généraliser, même si je suis d'accord qu'ici, dans ce cas bien particulier cela n'aurait pas grande incidence.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  13. #13
    Invité
    Invité(e)
    Par défaut
    Je vous remercie infiniment, je ne pensais pas que mon post serait sujet à Polémique.

    Donc, je tente d'expliquer pourquoi j'ai abouti à ces 3 tables :

    - La table stockCarburant est censé être en permanence à jour du calcul des stocks, grâce aux triggers(ou procédures stockées) qui se déclenchent lors des mouvements de carburant(Je ne veux pas avoir à coder cette partie là en PHP/JS).

    -Les deux tables venteCarburant et reassortCarburant sont des "journaux" statiques -et inaccessibles en suppression et modification- de mouvements de stocks, avec donc une colonne date, ils seront accessibles en lecture dans l'application. Admettons que j'ai 5 stations services, et un total de 30 citernes, ces tables vont (en théorie) s'alourdir très rapidement de dizaines de lignes... Ces tables auraient également une valeur en cas de litige.

    Pourquoi je décide d'utiliser des triggers? Parce que j'ai déterminé qu'en calculant mes stocks avec du code PHP-Javascript sur une seule table, au fil du temps, au bout de deux ans, le calcul allait devenir très lourd, je préfère donc tenir une table stockCarburant en permanence à jour, comme j'ai pu voir d'autres exemples sur internet. De cette façon, une simple requête ajax donnera l'état des stocks d'une citerne en fonction de son ID. Une citerne ayant un numéro ID unique, elle sera forcément toujours à jour par ce biais.
    De plus, l'application doit renseigner en permanence du stock de carburant restant pour chaque citerne, et cela me parait plus facile avec le système à 3 tables.

    De plus, hier, j'ai du ajouter les colonnes suivantes à ma table reassortCarburant : idFournisseur, coutUnitaire, coutTotal
    et aussi à ma table venteCarburant : idClient,coutUnitaire,coutTotal


    Je suis tout à fait prêt à accepter que ce n'est pas la bonne démarche à adopter ... cependant, c'est la seule idée que j'ai eu... Heu... C'est du basique hein... Je ne sais même pas comment gérer encore les surplus éventuels de stock, de plus, la gestion des commandes interviendra également dans le futur, mais les tables demeureront identiques... Les réassorts seront seulement appliqués avec un délai dans le temps... Mais ça c'est une autre partie de l'app..

    Merci pour votre conseil vis-à-vis du champs date. Le problème étant que, provisoirement, je n'ai pas sous la main un système fiable de conversion 'objetDateJavascript'->'objetDateSQL', qui ne se fait pas forcément aisément aux premiers abords (De plus il faut également savoir faire l'inverse), cependant, je conçois que cela puisse être un problème vis-à-vis d'un utilisateur requétant en SQL sur la table, avec un critère de date, bien sur, cela ne fonctionnera pas.
    J'essayerais donc de réaliser une conversion fiable dès que possible.

    Par ailleurs j'ai déjà codé la partie insertion en angularJs, hier, d'un réassort de carburant, et je peux vous dire qu'il existe également des problèmes de point et de virgule dans les champs de type number, pas simple du tout à élucider. Les navigateurs ne sont pas standardisés à ce niveau !!

    Merci infiniment de vos conseils je vais essayer de m'en inspirer, je n'ai pas encore bien lu, je vais le faire cet après midi. Merci beaucoup pour l'idée de l'évaporation, de la table Unique, ainsi que de la vue !:D
    Dernière modification par Invité ; 16/08/2016 à 14h39.

  14. #14
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par devwebsympa Voir le message
    Par ailleurs j'ai déjà codé la partie insertion en angularJs, hier, d'un réassort, et je peux vous dire qu'il existe également des problèmes de point et de virgule dans les champs number pas simple du tout à élucider.
    Il s'agit très certainement d'un problème de culture. Les cultures anglosaxones utilisent le '.' comme séparateur décimal (et la virgule comme séparateur des milliers), tandis que les cultures francophones utilisent la ',' comme séparateur décimal (et un espace comme spérateur des milliers).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  15. #15
    Invité
    Invité(e)
    Par défaut
    - Deuxièmement, une citerne, c'est pas totalement hermétique. Il y a de l'évaporation. Aussi, quand on rempli une citerne, on risque d'en reverser, idem à la vente.
    => Par conséquent, après quelques opérations de remplissage/vidage, la somme des mouvements ne sera pas forcément égale au niveau de la citerne. Le delta va croître avec le temps. Et si on veut faire une régulation, on va devoir saisir un réassort ou une vente qui n'a pas eu lieu : on pollue les données pour résoudre une erreur de conception.
    On peut aussi labéliser cela comme étant de l'évaporation dans la table venteCarburant, mais en effet ce n'est pas du tout propre et logique. Ou alors créer une table spécifique "evaporation" ... ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1/ la table des stock n'a pas de raison d'être puisque le stock résulte du calcul de la somme des réassorts moins la somme des ventes... (faire une vue serait plus approprié)
    2/ les tables reassort et vente peuvent faire l'objet d'une seule table "mouvement", avec le volume des ventes en négatif.
    En cas d'évolution, (par exemple le besoin de préciser un fournisseur pour les réassorts uniquement), alors il conviendra de mettre en place un héritage.
    ainsi, pas de NULL inutiles mais globalement des requêtes simplifiées (ne serait-ce que, justement, pour la calcul des stocks)
    La vue du stock étant un calcul, au bout de 5 ans, cela risque pas d'etre long si il y a 10 00 enregistrements ? Merci

  16. #16
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    - La table "stock" a toute sa raison d'être : c'est le point d'entrée, c'est ça qui permet de savoir de quelle citerne on parle.
    Oui, si on considére que la table stock représente une citerne.
    Cela ne m'a pas semblé être le cas ici. J'avais supposé une table "citerne" non représentée sur le schéma. C'est la clef étrangère idCiterne dans la table des stocks qui m'a fait penser cela...


    Citation Envoyé par StringBuilder Voir le message
    - Premièrement, après 10 ans d'activité, avec des centaines de vente par jour et des dizaines de réassort par mois, la vue va être anormalement lente.
    => Dans ce cas, on pourrait opter, si le SGBD le permet, pour une colonne calculée (SQL Server par exemple le permet).
    On ne peut rien affirmer à ce niveau, puisqu'on ne connait pas le volume (des données, pas des citernes )prévu, ni le SGBD.
    Car en effet, avec SQL server, il suffit simplement d'indexer la vue, solution qui sera bien meilleure qu'une alternative à base de triggers.
    Si le "stock" est récupéré une fois par jour, la nuit, par un robot en charge de passer la commande de réassort du lendemain, alors les triggers vont ralentir (un peu) tout le système pour pas grand chose. Le robot peut attendre quelques minutes...
    Bref, avec ce qu'on connait du besoin, je resterais sur la solution une table + une vue : il ne sera pas trop tard ensuite pour dé normaliser si le besoin s'en fait sentir, en créant cette table de stock et les trigger si ça apparait la bonne solution


    Citation Envoyé par StringBuilder Voir le message
    - Deuxièmement, une citerne, c'est pas totalement hermétique. Il y a de l'évaporation. Aussi, quand on rempli une citerne, on risque d'en reverser, idem à la vente.
    => Par conséquent, après quelques opérations de remplissage/vidage, la somme des mouvements ne sera pas forcément égale au niveau de la citerne. Le delta va croître avec le temps. Et si on veut faire une régulation, on va devoir saisir un réassort ou une vente qui n'a pas eu lieu : on pollue les données pour résoudre une erreur de conception.
    là aussi c'est hypothétique, car rien ne dit qu'il faut gérer ce cas.
    Et si le cahier des charges le précise, alors il suffit de créer des mouvements adéquats, qui peuvent tout à fait être reconnus en tant que tel (et non des fausses ventes). là encore, mettre en place un héritage permettra de garder un modèle clair, mais efficace. Il n'y a aucune pollution de quoi que soit là dedans.

  17. #17
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Oui, si on considére que la table stock représente une citerne.
    Cela ne m'a pas semblé être le cas ici. J'avais supposé une table "citerne" non représentée sur le schéma. C'est la clef étrangère idCiterne dans la table des stocks qui m'a fait penser cela...
    Je pense que "idCiterne" s'appelle comme ça, y compris dans la table "mère", car c'est visiblement la mode d'apprendre le SQL avec des NATURAL JOIN.
    Du coup les identifiants ont le même nom partout, compris dans la table mère (du coup ça rend la lecture des tables imbittable quand il y a plusieurs FK, et surtout, les jeunes diplômés n'ont aucune idée de comment faire une auto-jointure... C'est beau ce qu'on apprend aux élève tiens !)

    Citation Envoyé par aieeeuuuuu Voir le message
    On ne peut rien affirmer à ce niveau, puisqu'on ne connait pas le volume (des données, pas des citernes )prévu, ni le SGBD.
    Car en effet, avec SQL server, il suffit simplement d'indexer la vue, solution qui sera bien meilleure qu'une alternative à base de triggers.
    Si le "stock" est récupéré une fois par jour, la nuit, par un robot en charge de passer la commande de réassort du lendemain, alors les triggers vont ralentir (un peu) tout le système pour pas grand chose. Le robot peut attendre quelques minutes...
    Bref, avec ce qu'on connait du besoin, je resterais sur la solution une table + une vue : il ne sera pas trop tard ensuite pour dé normaliser si le besoin s'en fait sentir, en créant cette table de stock et les trigger si ça apparait la bonne solution
    Je dirais que cependant, ça tombe sous le sens :
    - Il y a une table "réassort" et une table "vente". On est donc ici sur une activité d'achat/revente. Donc des marges faibles. Donc des volumes importants.
    - En général, quand on informatise une solution, avec une base de données qui plus est, c'est qu'on a un réel besoin d'une telle solution (on va pas dépenser des dizaines de milliers d'euros à informatiser un auto-entrepreneur qui a 5000 euros de CA annuel.
    - La plus erreur de conception, selon moi tout du moins, c'est d'ignorer la montée en charge et les performances en se disant "on verra bien plus tard s'il y en a bien besoin"
    => Fort de tout ça, vu que ça coûte pas plus cher de monter l'une ou l'autre des solutions, il faut opter en priorité pour celle qui restera la plus performante dans le temps.

    Sinon, ton problème de trigger, pas pigé : en aucun cas un trigger ralenti les lectures... La vue, à l'inverse, ralenti TOUTES les lectures.
    Donc un calcul simple à se poser, c'est : quel est le volume d'information à traiter dans ma vue VS le volume à traiter dans mon trigger.
    => La réponse à cette question fait d'emblée peser la balance pour l'une ou l'autre des deux solutions (mon intime conviction penche pour les triggers ou assimilés -colonne calculée persistante-)

    Citation Envoyé par aieeeuuuuu Voir le message
    là aussi c'est hypothétique, car rien ne dit qu'il faut gérer ce cas.
    Et si le cahier des charges le précise, alors il suffit de créer des mouvements adéquats, qui peuvent tout à fait être reconnus en tant que tel (et non des fausses ventes). là encore, mettre en place un héritage permettra de garder un modèle clair, mais efficace. Il n'y a aucune pollution de quoi que soit là dedans.
    C'est pour ça que les "PROGRAMMEURS" n'existent plus depuis 50 ans, et que depuis, il n'y a que des "ANALYSTES PROGRAMMEURS" et autres "INGENIEURS".
    En effet, on ne doit pas se contenter de suivre à la lettre un cahier des charges (surtout quand il tient en deux lignes) mais bien se poser les questions de l'évolution et des éléments qui n'ont pas été mentionnés dans le cahier des charges.
    Tous les document de spécifications fonctionnelles que j'écris contiennent à la fois ce qu'il faut faire, et ce qui a été écarté lors de l'analyse (histoire qu'on ne se repose pas les mêmes questions au moment de la mise ne œuvre)
    On ne jouit bien que de ce qu’on partage.

  18. #18
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Je pense que "idCiterne" s'appelle comme ça, y compris dans la table "mère", car c'est visiblement la mode d'apprendre le SQL avec des NATURAL JOIN.
    Du coup les identifiants ont le même nom partout, compris dans la table mère (du coup ça rend la lecture des tables imbittable quand il y a plusieurs FK, et surtout, les jeunes diplômés n'ont aucune idée de comment faire une auto-jointure... C'est beau ce qu'on apprend aux élève tiens !)
    Qu'avez-vous contre les jointures naturelles ?

    Si une même information est présente dans plusieurs tables (table de "jointures" issue d'une association avec 0,n sur chaque patte au niveau du MCD par exemple, ou héritage justement....), pourquoi les colonnes qui en résultent ne pourraient pas avoir le même nom ?

    C'est beau tiens !

  19. #19
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    J'ai rien contre le nommage des colonnes de manière sémantique.

    Et "jointure naturelle", c'est un ordre SQL, pas une règle de nommage.

    Si tu as une table :

    CLIENT (idClient, nom)
    COMMANDE (idClient, valeur)

    Alors tu peux faire :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from client
    natural join commande

    Et automatiquement, le SGBD (s'il supporte cette syntaxe), va rechercher dans les deux tables les colonnes qui ont le même nom, et va effecter une jointure de type "INNER JOIN" sur ces colonnes.

    Seul hic, demain, tu rajoutes "valeur" à ton client pour connaître mettons son encours, ou la valeur totale de ses achats.
    => Bah t'as plus une seule requête qui marche. Ou plus exactement, elles marchent encore, mais ne ramène plus du tout le même résultat !

    Aussi, obligé d'avoir un MPD (à jour et complet) sous les yeux pour comprendre les requêtes.

    Alors tu changes toutes tes requêtes pour utiliser :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select *
    from client 
    natural join commande using (idClient)

    Pas franchement plus lisible ou plus court qu'un inner join classique.
    Et ça empêche toute jointure "évoluée" avec des critères complexes (genre select * from client inner join commande on commande.idClient = client.idClient and commande.valeur > client.valeur / 10)

    Et le jour où tu dois faire une auto-jointure :

    CLIENT (idClient, nom, idSupperieur)

    => Bah t'es comme un con, t'as appris que le NATURAL JOIN, hyper limité, et tu te retrouve à faire des jointures en JavaScript car t'es persuadé qu'on peut pas le faire en SQL (c'est con quand même). Je me suis pris la tête une journée avec un stagiaire il y a 15 jours sur le sujet, donc c'est du vécu :o Et pourtant le stagiaire est loin d'être bête... Alors je te laisse imaginer le désastre avec les queues de promo...

    Et sinon, pour revenir au reproche initial :

    client (id, nom)
    commande (id, valeur, idClient)
    produit (id, nom)
    ligne_commande (id, idCommande, idProduit, quantite) -- La clé primaire saute aux yeux

    Devient, si tu utilises des jointures naturelles :
    client (idClient, nomClient)
    commande (idCommande, valeurCommande, idClient)
    produit (idProduit, nomProduit)
    ligne_commande (idLigneCommande, idCommande, idProduit, quantiteLigneCommande) -- La clé primaire saute pas vraiment aux yeux

    => En effet : chaque colonne de chaque table, y compris les colonnes de données, doivent impérativement être uniques et identiques dans tout le modèle des données.

    Par exemple, si on recopie le nom du produit dans la ligne de commande, car il peut évoluer dans le temps, mais on souhaite conserver la désignation sous laquelle a été effectuée la vente, alors on va se poser la question de : nomProduit ou nomLigneCommande car dans le premier cas, on peut faire des jointures par le nom, ce qui peut avoir un éventuel intérêt (par exemple, retrouver l'ID du produit qui a récupéré le nom du produit initialement vendu) ou l'en empêcher et ainsi permettre de faire des natural join entre ligne_commande et produit sans savoir spécifier un using.

    Bref, le language de requêtage vient perturber le MPD et le dictionnaire des données, ce qui est pour moi une hérésie.

    Un peut comme les gens qui utilisent un type "varchar" pour stocker une date car ils savent pas faire autrement pour requêter la base depuis JavaScript (juste un exemple, pour bien cerner )
    On ne jouit bien que de ce qu’on partage.

  20. #20
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    Wow.
    Je vais pas m’étaler ici, mais y a de quoi débattre.

    Pour faire court, c'est pas mal de préfixer le nom des colonnes par un trigramme faisant référence à chaque table.
    Client(cli_id, cli_nom)
    Commande(cmd_id, cli_id#, cmd_valeur)

    Bref, soit moins négatif sur la jointure naturelle. C'est l'opérateur de base l'algèbre relationnelle.
    Suivant la définition que l'on a de l'algèbre relationnel, c'est un opérateur primitif qui sert à définir les autres opérateurs, comme la jointure externe par exemple.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AC-2010] [démo] Gestion de stock avec les évènements de table
    Par f-leb dans le forum Contribuez
    Réponses: 5
    Dernier message: 16/02/2013, 19h25
  2. gestion de stock avec une macro excel
    Par tchiph dans le forum Conception
    Réponses: 2
    Dernier message: 18/03/2011, 07h41
  3. Intégration d'une application de gestion de stock avec E-business suite
    Par ando0098 dans le forum Interfaces de programmation
    Réponses: 1
    Dernier message: 04/06/2010, 10h30
  4. Mise à jour automatique du stock avec un trigger
    Par jack911 dans le forum Requêtes
    Réponses: 7
    Dernier message: 19/10/2008, 11h51
  5. Recherche base access pour gestion de stock avec picking
    Par Cedric1979 dans le forum Access
    Réponses: 3
    Dernier message: 15/02/2006, 14h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo