Ratschläge zum Datenbankdesign

8

Ich entwerfe eine Datenbank, die unser Verkaufsteam als schnelles Tool für die Angebotserstellung verwenden kann. Ich hätte gerne ein Feedback zu einem bestimmten Aspekt des Designs.

Ein Angebot wird im Wesentlichen durch Auswahl einer Liste vordefinierter "Baugruppen" mit jeweils einem vereinbarten Preis erstellt. Eine vereinfachte Ansicht des Hauptformulars sieht folgendermaßen aus:

                                                  +------------ --- ---+
                                                  | 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 |     |  | 
+------------+------------+----------+------------+---+---+---+ --- +--+

Der Benutzer wählt eine vordefinierte Baugruppe aus, gibt die Menge ein und wählt alle erforderlichen Optionen aus. Für jede Baugruppe stehen möglicherweise bis zu 50 Optionen zur Verfügung. Eine Option ist auch eine vordefinierte Baugruppe (Unterbaugruppe) mit eigenem Preis. Die 'Gesamtkosten' für jede Linie werden berechnet als (Hauptmontagekosten * Menge) + Kosten aller Optionen.

Wenn der Benutzer seinen Cursor in ein Optionsfeld bewegt, werden ihm Name und Preis dieser Option bekannt gegeben.

Hier wird es kompliziert. Jede Baugruppe verfügt über eine eigene Liste verfügbarer Optionen. dh Option 1 für einen 'VSD55' stellt eine andere Unterbaugruppe dar als Option 1 für einen DOL5.0.

Was die Baugruppen betrifft, sind hier die vereinfachten Tabellen, die ich verwende:

+-----------------+    +------------------------+    +-----------------------------+
| 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              |    +-----------------------------+
                       +------------------------+

Die Tabelle 'assembly_option_link' definiert grundsätzlich, welche Optionen für jede Assembly verfügbar sind.

Nun zu den 'Zitat'-Tabellen:

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

Der schwierige Teil ist nun, wie ausgewählte Optionen gespeichert werden. Sollte ich die Tabelle 'quote_assembly' mit allen 50 Optionsfeldern erweitern, obwohl dies gegen die Normalisierungsregeln verstößt? Eine Baugruppe wird niemals mit allen 50 Optionen ausgewählt, daher scheint dies auch sehr ineffizient zu sein. Auf der positiven Seite ermöglicht diese Lösung, dass das Benutzereingabeformular direkt der Tabelle zugeordnet wird, was die Codierung vereinfacht.

Die 'normalisierte' Lösung wäre meiner Meinung nach, eine andere Tabelle wie diese zu erstellen:

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

Diese Lösung bedeutet, dass nur ausgewählte Optionen gespeichert werden. Anstatt die Option_Nummer zu speichern, kann ich auch die tatsächliche 'Assembly_Option_ID' speichern. Dies vereinfacht dann die Berechnung der Gesamtkosten für das Angebot, da ich nicht zwischen 'option_number' und 'Assembly_option_id' konvertieren muss, um die Kosten für die Assembly-Option nachzuschlagen. Der Hauptnachteil dieser Lösung ist jedoch, dass sie nicht gut zum Benutzereingabeformular passt. Ich denke, ich muss eine ausgefallene Codierung anwenden, um das Formular mit den Tabellen zu verbinden.

Kann hier bitte jemand eine Designberatung anbieten? Ich hoffe ich habe mich gut genug erklärt.

MEHR INFO Dies
ist auch ein detaillierter Angebotsbericht, der alle ausgewählten Optionen als separate Positionen unter der Hauptbaugruppe erweitert. Zum Beispiel:

+---------------------------------+------------+----------+------------+
| 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
quelle

Antworten:

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

Wenn mir jemand dieses Zitat geben würde, wäre meine erste Frage "Was ist Option 1 für den VSD55?" Die Antwort wäre "Ich weiß es nicht." Diese Informationen sind nicht im Zitat enthalten. In dem unwahrscheinlichen Fall, dass diese Person eine zweite Frage stellen muss , lautet diese Frage: "Was kostet es?" Wieder wäre die Antwort "Ich weiß es nicht." Es würde sofort eine sehr beunruhigende Stille folgen, in der sich die Person, die mir das Zitat überreichte, vorstellen würde, wie viel besser es sich anfühlen könnte, von einem Zug überfahren zu werden.

Optionen müssen Werbebuchungen im Angebot sein, zusammen mit ihrem Stückpreis, ihrer Menge und ihrem Gesamtpreis. Optionen müssen benannt und nicht nummeriert sein. Sie sollten auch direkt unter ihrer Elternversammlung erscheinen und nicht über die Hölle und die Hälfte von Georgia verstreut sein.

Wenn Sie einen Schuss auf mein Geld wollen, würden Sie besser machen es kristallklar , was soll ich werden immer für mein Geld.

An 50 Kontrollkästchen in einem Benutzeroberflächenformular ist nichts (viel) auszusetzen. Das macht es einfach, Optionen auszuwählen. Der UI-Code sollte jedoch die Kontrollkästchen lesen und die richtigen Informationen in normalisierte Tabellen einfügen.

Mike Sherrill 'Cat Recall'
quelle
Es hört sich so an, als würden Sie Ratschläge zu den Geschäftsprozessen geben, die nicht in Frage kommen. David versucht, die beste Art und Weise, die er für das ihm zugewiesene Projekt kennt, zusammenzufassen. ~ Nun stimme ich zu, dass eine Datenbank das Design beeinflussen sollte, wo sie es kann, aber manchmal kann dem nicht geholfen werden. Denken Sie auch daran, dass dies ein internes Tool ist (siehe erste Zeile)
jcolebrand
1
Fair genug Kommentare, brachte mich zum Lachen! Wir haben natürlich einen Angebotsbericht, der genau das tut, was Sie vorschlagen. Ich habe seitdem dieses Detail zur ursprünglichen Frage hinzugefügt, um weitere Diskussionen außerhalb des Themas zu vermeiden;)
David
3

Die letzte Option, die Sie geben, ist die Art und Weise, wie ich damit umgehen würde. Und geben Sie zwei gruppierte Tabellen zurück, eine für die "Hauptzeile" und eine für die gesammelten "Existiert" -Zeilen für die 50 Spalten. Angenommen, Sie können die Option einfach genug der entsprechenden Spalten-ID zuordnen (es sieht so aus, als könnten Sie dies ohne allzu große Schwierigkeiten tun).

Das wäre für die Iteration einfach genug, wenn man eine Sprache wie C # voraussetzt, in der LINQ verfügbar ist usw. Diese sind einfach genug, auch wenn sie ein wenig schleifen (es ist UI-Code, es muss irgendwann gemacht werden ). Oder Sie könnten einen Pivot in der Datenbank machen, bevor Sie zurückkehren ... das wäre schneller. Aber es wird immer noch die Komplexität beibehalten.

Aber dein Design klingt für mich.

jcolebrand
quelle
0

Das Hinzufügen Ihres zusätzlichen Tisches scheint mir auch ziemlich vernünftig zu sein.

Als ich mich mit einem ähnlichen Problem befasste, untersuchte ich das Speichern eines Baums in der Tabelle order_lines. Falls Sie etwas Ähnliches in Betracht gezogen haben, hatte ich:

  • ein zusätzliches parent_idFeld für order_linesund ein Fremdschlüssel, auf (parent_id, product_id)den verwiesen wird(order_line_id, product_id)

  • Eine Überprüfungsbeschränkung, um eine Option zu erhalten, würde einen Elternteil implizieren (in meinem Fall check((option_id is not null) = (parent_id is not null))).

Mit anderen Worten, ich habe der Benutzeroberfläche ein Wort darüber gegeben, wie Dinge gespeichert werden sollen:

+---------------------------------+------------+----------+------------+
| 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  |
+---------------------------------+------------+----------+------------+

Vom Standpunkt der UI-Codierung aus schien es richtig zu sein. Unter dem Gesichtspunkt der Geschäftsregeln fühlte es sich jedoch schnell falsch an, da es später eine Reihe von Problemen aufwirft. (Ich musste mich mit allen möglichen Sonderfällen bei Auslösern befassen.)

Also nicht zu empfehlen ... Soweit ich ähnliche Fälle erlebt habe, wird Ihr derzeitiger Ansatz später weniger problematisch sein.

Denis de Bernardy
quelle