it-swarm.com.de

Beste Möglichkeit, Einheiten in einer Datenbank zu speichern

Ich habe eine große (SQLServer) Datenbank mit Hunderten von Spalten geerbt, die Beträge der einen oder anderen Sache darstellen. Die Einheiten für diese Werte (z. B. "Gallonen", "Zoll" usw.) werden im Feld MS_Description der erweiterten Eigenschaften gespeichert. Ich frage mich, ob es einen besseren Weg gibt, diese Informationen zu speichern. Ich nehme an, es ist für Dokumentationszwecke in Ordnung, aber es wäre schwierig, robuste Einheitenumrechnungsberechnungen basierend auf diesen Daten durchzuführen. Zum jetzigen Zeitpunkt bin ich noch nicht bereit, eine invasive Änderung vorzunehmen. Wenn ich jedoch die Möglichkeit dazu bekomme, welche Empfehlung wird in dieser Hinsicht empfohlen? Zu den Optionen, die sich auf meinem Kopf befinden, gehören:

  • Ändern Sie den Spaltennamen in eingeschlossene Einheiten (z. B. "TotalVolumeInGallons". Dies würde die Informationen ein wenig leichter verfügbar machen, scheint mir aber immer noch schwach zu sein.)
  • Fügen Sie eine separate Spalte "Einheiten" hinzu, die jeder Spalte "Betrag" entspricht (diese Spalte kann nvarchar OR) sein. Dies kann ein Fremdschlüssel für eine separate Einheitentabelle sein, der die Berechnung der Einheit erleichtert Konvertierungen. Andererseits könnte das Hinzufügen so vieler Spalten die Größe meiner Datenbank ziemlich verdoppeln - mit schrecklich redundanten Daten.)
  • Erstellen Sie ein neues Feld in den erweiterten Eigenschaften, das speziell für Einheiten vorgesehen ist. (Leider glaube ich nicht, dass dies ein Fremdschlüssel für eine Einheitentabelle sein kann.)
  • Gibt es eine andere Idee, die ich übersehen habe?

PDATE : Nachdem ich die Antwort von @Todd Everett gelesen hatte, kam mir eine mögliche Lösung in den Sinn, also werde ich meine eigene Frage beantworten. (Siehe unten)

21
kmote

Nachdem ich die Antwort von @Todd Everett gelesen hatte, kam mir eine Lösung, und ich werde meine eigene Frage beantworten. Ich denke, ich werde eine separate ColumnUnits -Tabelle mit vier Spalten erstellen: Schema, Table, Column, UnitsID (wobei UnitsID FK für eine separate UnitsOfMeasure -Tabelle ist), wodurch eine bestimmte Spalte der zugehörigen Maßeinheit zugeordnet wird. Der größte Nachteil dieser Idee ist natürlich, dass Entwickler daran denken müssen, diese Tabelle zu bearbeiten, wenn sie eine Spalte oder Tabelle umbenennen. [ Verwenden Sie möglicherweise einen DDL-Trigger ? ], sonst bricht das System . Unter der Annahme, dass solche Umbenennungen selten sind und der Entwicklungsladen klein ist (in meinem Fall nur eine Person), sollte diese Architektur funktionsfähig sein. Der Vorteil ist, dass keine invasiven Änderungen an der aktuellen Datenbank vorgenommen werden müssen und ich den Wert nur einmal für jede Spalte speichern muss, anstatt einmal pro Zeile, wie es meine zweite Option in meinem ursprünglichen Beitrag erfordern würde.

3
kmote

Da Sie Hunderte von Spalten erwähnen, würde ich ein EAV-Design in Betracht ziehen. Während Joe Celko warnt davor , denke ich, dass es in Ihrem Anwendungsfall anwendbar sein kann. Es hört sich so an, als ob alle Ihre "Beträge" Zahlen sind. Sie würden also die von Joe beschriebenen Casting-Probleme und die Notwendigkeit vermeiden, jeden "Wert" zu einer Zeichenfolge zu machen. Es funktioniert sogar noch besser, wenn alle Beträge ganze Zahlen sind, kann aber auch funktionieren, wenn einige dezimal sind. In Anbetracht der Maßeinheiten könnten Sie einen Schritt weiter gehen und ein Modell im Stil eines "universellen Datenmodells" implementieren, das auf diesem Artikel von David Hay basiert und auch in seinem Buch Datenmodellmuster: Konventionen des Denkens . Dieses Modell hat den zusätzlichen Vorteil, dass Sie konfigurieren können, welche "Beträge" für welche "Dinge" gelten, wenn Sie dies benötigen. Ein zusätzlicher Schritt, der im Buch auf Seite 175 gezeigt wird, ist eine Maßeinheit-Umrechnungstabelle, mit der Sie zwischen den verschiedenen Maßeinheiten umrechnen können. Hier ist ein Beispiel:

UOM Conversion              

UOM From    UOM To        Cal Step  Operator Factor Constant
Kilograms   Pounds        1         *        2.2
Celsius     Fahrenheit    1         *        1.8
Celsius     Fahrenheit    2         +               32

Dies besagt, dass der erste Schritt zur Umwandlung von Kg in Lb darin besteht, Kg mit 2,2 zu multiplizieren. Es gibt auch eine Konstante, wenn eine Konvertierung auch einen konstanten Wert enthalten muss, und die Möglichkeit, mehrere Schritte zu erstellen. Wenn Sie also beispielsweise Celsius in Fahrenheit umrechnen, multiplizieren Sie Celsius mit 1,8 und addieren dann 32. Der Schlüssel wäre der von UOM, der in UOM und der Berechnungsschritt.

Das sind meine 2 Cent wert. Ich hoffe, diese Referenzen geben Ihnen Anlass zum Nachdenken, falls Sie jemals die Möglichkeit haben sollten, das aktuelle Design neu zu starten.

12
Todd Everett

Alle Arbeit.

Beachten Sie, dass Sie im zweiten Fall keine Äpfel und Orangen hinzufügen können und die Daten daher außerordentlich leicht falsch interpretiert werden können.

Beachten Sie auch, dass Conversions nicht sehr sicher sein können und anfällig für Rundungsfehler, Überläufe usw. sind.

Darüber hinaus gibt es physikalische Probleme wie das spezifische Gewicht und die Temperatur. Um 20 Gallonen Wasser in Pfund umzuwandeln, müssen Sie die Dichte des Wassers kennen. Die Dichte des Wassers ändert sich jedoch mit der Temperatur. Daher müssen Sie möglicherweise entweder die Dichte gleichzeitig mit der Messung oder die Temperatur in ähnlicher Weise kennen und einen Volumenkorrekturfaktor verwenden.

Bei den Extended-Eigenschaften ist dies nur für die Dokumentation gut - ein guter Spaltenname ist besser für die Dokumentation. Das Problem mit der Spalte, die sich namentlich in einer festen Einheit befindet, besteht darin, dass Sie sich beim Wechseln der Maßeinheiten in eine Ecke begeben - ein neuer Kunde möchte Öl in Fässern und nicht in Gallonen - und das wäre in Ordnung, da seine Daten vorliegen eine eigene Datenbank, aber der Spaltenname ist jetzt irreführend.

Eine andere Möglichkeit besteht darin, kanonische Versionen zusätzlich zu den unterschiedlichen Originalmaßen in festen Einheiten (d. H. Immer Kilogramm und Meter) zu speichern. Aggregierte Operationen an den festen Einheiten sollten in Ordnung sein (außer Sie würden beispielsweise keine Temperaturen hinzufügen), aber Sie verlieren nicht die ursprüngliche Messung.

8
Cade Roux

Eine einfache Lösung, die in der Vergangenheit für mich gut funktioniert hat, besteht darin, alle Ihre Daten in den Basiseinheiten zu speichern. Beispielsweise kann Ihre Basiseinheit für Längen Millimeter und Ihre Basiseinheit für Gewichte Kilogramm sein. Diese Lösung kann dazu führen, dass einige Ihrer vorhandenen Daten in die Basiseinheit konvertiert werden müssen, sofern dies noch nicht geschehen ist.

Sobald Sie alle Daten in den Standardbasiseinheiten haben, müssen Sie die Einheit nicht mehr in der Datenbank selbst speichern, da dies jetzt eine systemweite Annahme ist. Die angezeigten Einheiten, die für jeden Einheitentyp erforderlich sind (z. B. ob mm, Zoll, cm, m für die Länge angezeigt werden sollen), werden zu einem Anwendungs-/Clientdomänenproblem, das im lokalen Speicher gespeichert werden kann.

Die Einheitenumrechnungstabellen für die Umrechnung zwischen den verschiedenen unterstützten Einheiten können in Ihrer Anwendung fest codiert werden, da sich neue Maßeinheiten äußerst selten ändern.

N.B. Eine verwandte Lösung für ein anderes Problem ist, dass beim Speichern von Zeitstempeln in einer Datenbank in immer in der Basiseinheit - UTC gespeichert .

Weitere verwandte Fragen und Antworten zum Thema ...

7
dodgy_coder

Da jede Einheit in eine andere Einheit des gleichen Typs umgewandelt werden kann Mit der Formel:

y = ((x + xOffset) * multiplicand / denominator) + yOffset

Ich würde eine Tabelle erstellen, die die Einheitentypen plus diese 4 Werte enthält.

From Unit     To Unit      Unit Type    From Offset    Multiplicand    Denominator    To Offset
'milligrams'  'grams'      'mass'       0              1               1000           0
'grams'      'kilograms'   'mass'       0              1               1000           0
'grams'      'ounces'      'mass'       0              100000          2835           0
'ounces'     'pound'       'mass'       0              1               16             0

Nachdem Sie alle Messungen hinzugefügt haben, in die und von denen Sie wahrscheinlich konvertieren werden, befinden Sie sich auf beiden Seiten der Liste. Führen Sie eine Abfrage aus, in der Sie die inverse Operation einfügen, indem Sie einfach die Offsets negieren und Multiplikand und Nenner sowie To Unit und From Unit austauschen.

Um eine Konvertierung zwischen allen Typen hinzuzufügen, kann eine Querverbindung mit einigen Filtern die verbleibenden Konvertierungen einfügen.

5
peroyhav