Conseils de conception de base de données

8

Je suis en train de concevoir une base de données pour notre équipe de vente à utiliser comme un outil de soumission rapide. J'aimerais avoir des commentaires sur un aspect particulier de la conception.

Un devis est essentiellement constitué en sélectionnant une liste d '«assemblages» prédéfinis, chacun avec un prix convenu. Une vue simplifiée du formulaire principal ressemble à ceci:

                                                  +------------ --- ---+
                                                  | Assembly options   |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly  | unit cost  | quantity | total cost | 1 | 2 | 3 |     |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55      | £10'000    | 2        | £25'500    | 1 | 1 |   |     |  | 
| RDOL2.2    | £2'000     | 1        |  £1'500    |   | 1 |   |     |  | 
| DOL5.0     | £1'000     | 1        |  £1'200    |   |   | 1 |     |  | 
+------------+------------+----------+------------+---+---+---+ --- +--+

L'utilisateur sélectionne un assemblage prédéfini, saisit la quantité et sélectionne les «options» requises. Chaque assemblage a potentiellement jusqu'à 50 options disponibles. Une option est également un assemblage prédéfini (sous-assemblage) avec son propre prix. Le «coût total» pour chaque ligne est calculé comme (coût d'assemblage principal * quantité) + coût de toutes les options.

Lorsque l'utilisateur déplace son curseur dans une case d'option, le nom et le prix de cette option lui sont communiqués.

Maintenant, c'est là que ça se complique. Chaque assemblage possède sa propre liste d'options disponibles. c'est-à-dire que l'option 1 pour un «VSD55» représente un sous-ensemble différent de l'option 1 pour un DOL5.0.

En ce qui concerne les assemblages, voici les tableaux simplifiés que j'utilise:

+-----------------+    +------------------------+    +-----------------------------+
| assembly        |    | assembly_option        |    | assembly_option_link        |
+-----------------+    +------------------------+    +-----------------------------+
| assembly_id (PK)|    | assembly_option_id (PK)|    | assembly_option_link_id (PK)|
| assembly_name   |    | assembly_option_name   |    | assembly_id (FK)            |
| unit_cost       |    | option_number          |    | assembly_option_id (FK)     |
+-----------------+    | unit_cost              |    +-----------------------------+
                       +------------------------+

Le tableau 'assembly_option_link' définit essentiellement les options disponibles pour chaque assembly.

Maintenant, pour les tableaux «devis»:

 +-----------------+    +------------------------+    
 | quote           |    | quote_assembly         |    
 +-----------------+    +------------------------+    
 | quote_id (PK)   |    | quote_assembly_id (PK) |
 | quote_name      |    | assembly_id (FK)       |
 +-----------------+    | quantity               |
                        +------------------------+    

Maintenant, la partie délicate est de savoir comment stocker les options sélectionnées. Dois-je développer la table 'quote_assembly' avec tous les 50 champs d'options même si cela enfreint les règles de normalisation. Un assemblage ne sera jamais sélectionné avec les 50 options, ce qui semble également très inefficace. Sur le plan positif, cette solution permet au formulaire de saisie utilisateur de mapper directement sur le tableau, ce qui facilite le codage.

La solution «normalisée», je pense, serait de créer un autre tableau comme celui-ci:

+------------------------------+
| quote_assembly_option        |
+------------------------------+
| quote_assembly_option_id (PK)|
| quote_assembly_id (FK)       |
| assembly_option_id (FK)      |
| quantity                     |
+------------------------------+

Cette solution signifie que seules les options sélectionnées sont stockées. De plus, plutôt que de stocker l'option_number, je peux stocker le 'assembly_option_id' réel. Cela rend ensuite le calcul du coût total du devis plus simple car je n'ai pas besoin de convertir entre 'option_number' et 'assembly_option_id' pour rechercher le coût de l'option d'assemblage. L'inconvénient majeur de cette solution est qu'elle ne convient pas au formulaire de saisie utilisateur. Je pense que je devrai appliquer un codage sophistiqué pour interfacer le formulaire avec les tables.

Quelqu'un peut-il offrir des conseils de conception ici s'il vous plaît? J'espère que je me suis bien expliqué.

PLUS D'INFO
Le est également un rapport de devis détaillé qui développe toutes les options sélectionnées en tant qu'éléments de ligne distincts sous l'assemblage principal. Par exemple:

+---------------------------------+------------+----------+------------+
| assembly                        | unit cost  | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55                           | £10'000    | 2        |   £20'000  |
|   - Seal leak protection        | £ 5'000    | 1        |   £ 5'000  |   <-option 1
|   - Motor over temp protection  | £   500    | 1        |   £   500  |   <-option 2
+---------------------------------+------------+----------+------------+
|                                 |            |          |   £25'500  |
+---------------------------------+------------+----------+------------+
David
la source

Réponses:

3
                                                  +------------ --- ---+
                                                  | Assembly options   |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly  | unit cost  | quantity | total cost | 1 | 2 | 3 |     |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55      | £10'000    | 2        | £20'000    | 1 | 1 |   |     |  | 

Si quelqu'un me remettait cette citation, ma première question serait "Quelle est l'option 1 pour le VSD55?" La réponse serait "je ne sais pas". Cette information n'est pas sur le devis. Dans le cas peu probable où cette personne aurait pu répondre à une deuxième question, cette question serait «Combien cela coûte-t-il? Encore une fois, la réponse serait «je ne sais pas». Un silence très troublant s'ensuivit immédiatement, au cours duquel la personne qui me remit la citation imaginait à quel point il serait préférable d'être renversé par un train.

Les options doivent être des éléments de ligne du devis, ainsi que leur prix unitaire, leur quantité et leur prix total. Les options doivent être nommées et non numérotées. Ils devraient également apparaître directement sous leur assemblée parentale, pas dispersés dans tout l'enfer et la moitié de la Géorgie.

Si vous voulez tirer sur mon argent, vous feriez mieux de préciser clairement ce que je suis censé obtenir pour mon argent.

Il n'y a rien (beaucoup) de mal avec 50 cases à cocher sur un formulaire d'interface utilisateur. Cela facilite le choix des options. Mais le code de l'interface utilisateur doit lire les cases à cocher et insérer les bonnes informations dans les tableaux normalisés.

Mike Sherrill 'Cat Recall'
la source
On dirait que vous offrez des conseils sur les processus commerciaux, qui ne sont pas en option, que David essaie d'encapsuler de la meilleure façon qu'il connaisse pour le projet qui lui a été attribué. ~ Maintenant, je suis d'accord qu'un dba devrait influencer le design là où il le peut, mais parfois cela ne peut pas être aidé. Gardez également à l'esprit qu'il s'agit d'un outil interne (voir la première ligne)
jcolebrand
1
Assez juste des commentaires, ça m'a fait rire! Nous avons bien sûr un rapport de cotation qui fait exactement ce que vous proposez. J'ai depuis ajouté ce détail à la question d'origine pour éviter d'autres discussions hors sujet;)
David
3

La dernière option que vous donnez est la façon dont j'irais avec. Et renvoyez deux tables groupées, une pour la "ligne principale" et une pour les lignes "existe-t-il" collectées pour les 50 colonnes. En supposant que vous pouvez mapper l'option à son ID de colonne approprié assez facilement (il semble que vous le puissiez sans trop de difficultés).

Ce serait assez facile pour l'itération, en supposant un langage comme C #, où vous avez LINQ disponible, etc. Celles-ci sont assez faciles à faire, même si elles impliquent un peu de boucle (c'est du code UI, cela doit être fait à un moment donné) ). Ou vous pouvez faire un pivot dans la base de données avant de revenir ... ce serait plus rapide. Mais cela maintiendra toujours la complexité.

Mais votre conception me semble saine.

jcolebrand
la source
0

L'ajout de votre table supplémentaire me semble également assez solide.

Face à un problème similaire de ma part, j'ai exploré le stockage d'un arbre dans la table order_lines. Dans le cas où vous envisagez quelque chose de similaire, j'avais:

  • un parent_idchamp supplémentaire pour order_lines, et une clé étrangère de sorte que (parent_id, product_id)ferait référence(order_line_id, product_id)

  • Une contrainte de vérification pour faire avoir une option impliquerait un parent (dans mon cas check((option_id is not null) = (parent_id is not null))).

En d'autres termes, je laisse l'interface utilisateur avoir un mot sur la façon dont les choses doivent être stockées:

+---------------------------------+------------+----------+------------+
| assembly                        | unit cost  | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55                           | £10'000    | 2        |   £20'000  |
|   - Seal leak protection        | £ 5'000    | 1        |   £ 5'000  |
|   - Motor over temp protection  | £   500    | 1        |   £   500  |
+---------------------------------+------------+----------+------------+

Du point de vue du codage de l'interface utilisateur, cela semblait juste. Mais il s'est rapidement senti mal du point de vue des règles commerciales, en ce sens qu'il a introduit une variété de problèmes en cours de route. (J'ai dû gérer toutes sortes de cas spéciaux dans les déclencheurs.)

Donc pas recommandé ... Dans la mesure où j'ai connu des cas similaires, votre approche actuelle sera moins sujette aux problèmes sur la route.

Denis de Bernardy
la source