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 zu Dokumentationszwecken in Ordnung, aber es wäre schwierig, robuste Berechnungen zur Einheitenumrechnung basierend auf diesen Daten durchzuführen. Zu diesem Zeitpunkt bin ich noch nicht bereit, eine invasive Änderung vorzunehmen. Wenn ich jedoch die Möglichkeit dazu bekomme, was ist diesbezüglich die empfohlene Best Practice? Zu den Optionen, die mir aus dem Kopf gehen, könnten gehören:
- Ändern Sie den Spaltennamen in eingeschlossene Einheiten (z. B. "TotalVolumeInGallons". Dies würde die Informationen ein wenig leichter verfügbar machen, aber es scheint mir immer noch schwach.)
- Fügen Sie eine separate "Einheiten" -Spalte hinzu, um jeder "Betrag" -Spalte zu entsprechen (diese Spalte könnte nvarchar sein ODER ein Fremdschlüssel für eine separate Einheitentabelle, wodurch die Berechnung von Einheitenumrechnungen vereinfacht wird Viele Spalten könnten die Größe meiner Datenbank ziemlich verdoppeln - mit furchtbar redundanten Daten.)
- Erstellen Sie ein neues Feld in den erweiterten Eigenschaften, das speziell für Einheiten bestimmt 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?
UPDATE: Nachdem ich @Todd Everetts Antwort gelesen hatte, kam mir eine mögliche Lösung in den Sinn, sodass ich meine eigene Frage beantworten werde. (Siehe unten)
Antworten:
Da Sie Hunderte von Spalten erwähnen, würde ich ein EAV-Design in Betracht ziehen . Während Joe Celko davor warnt , denke ich, dass es in Ihrem Anwendungsfall anwendbar sein könnte. Es hört sich so an, als wären alle Ihre "Beträge" Zahlen, sodass Sie die von Joe beschriebenen Casting-Probleme und die Notwendigkeit vermeiden würden, 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önnen Sie einen Schritt weiter gehen und ein Modell im Stil eines "universellen Datenmodells" implementieren, das auf diesem Artikel von David Hay basiert und in seinem Buch " Datenmodellmuster: Konventionen des Denkens" beschrieben ist. 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 weiterer Schritt, der in dem Buch auf Seite 181 gezeigt wird, ist eine Maßeinheitenkonvertierungstabelle, mit der Sie zwischen den verschiedenen Maßeinheiten konvertieren können. Hier ist ein Beispiel:
Dies besagt, dass der erste Schritt, um von Kg zu Lb zu konvertieren, 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 zu UOM und der Berechnungsschritt.
Das sind meine 2 Cent wert. Ich hoffe, diese Referenzen geben Ihnen Anlass zu guten Überlegungen, falls Sie jemals die Gelegenheit haben sollten, einen Neustart des aktuellen Designs durchzuführen.
quelle
Alle Arbeit.
Beachten Sie, dass Sie im zweiten Fall keine Äpfel und Apfelsinen hinzufügen können und die Daten daher außergewöhnlich leicht falsch interpretiert werden können.
Beachten Sie auch, dass Konvertierungen nicht sehr sicher sind und Rundungsfehler, Überläufe usw. verursachen können.
Darüber hinaus gibt es physikalische Probleme wie das spezifische Gewicht und die Temperatur. Um 20 Gallonen Wasser in Pfund umzuwandeln, müssten Sie die Dichte des Wassers kennen. Da sich die Dichte des Wassers jedoch mit der Temperatur ändert, 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 erweiterten Eigenschaften ist dies nur für die Dokumentation hilfreich - ein guter Spaltenname ist besser für die Dokumentation. Das Problem mit der Spalte, die namentlich in einer festen Einheit enthalten ist, besteht darin, dass Sie sich in eine Ecke stürzen, wenn Sie die Maßeinheiten ändern eine eigene Datenbank, aber der Spaltenname ist jetzt irreführend.
Eine andere Möglichkeit besteht darin, kanonische Versionen zusätzlich zu den variierenden Originalmaßen in festen Einheiten (dh immer Kilogramm und Meter) zu speichern. Aggregierte Operationen an den festen Einheiten sollten in Ordnung sein (außer Sie würden zum Beispiel keine Temperaturen hinzufügen), aber Sie verlieren nicht die ursprüngliche Messung.
quelle
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 Standard-Basiseinheiten 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 lokal 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.
Eine verwandte Lösung für ein anderes Problem ist, dass beim Speichern von Zeitstempeln in einer Datenbank diese immer in der Basiseinheit (UTC) gespeichert werden .
Weitere verwandte Fragen und Antworten zum Thema ...
/programming/12977021/best-practice-for-storing-weights-in-a-sql-database
Hier finden Sie einige gute Informationen, warum die Verwendung eines Gleitkomma-Spaltentyps die beste Methode zum Speichern von Messungen in der realen Welt ist.
quelle
Da jede Einheit in eine andere Einheit desselben Typs umgewandelt werden kann, gilt folgende Formel:
Ich würde eine Tabelle erstellen, die die Einheitentypen plus diese 4 Werte enthält.
Nachdem Sie auf beiden Seiten der Liste alle Maße hinzugefügt haben, zu denen Sie wahrscheinlich konvertieren werden, führen Sie eine Abfrage aus, in der Sie die inverse Operation einfügen, indem Sie einfach die Offsets negieren und den Multiplikanden und den Nenner sowie die Einheiten To und From vertauschen.
Um die Konvertierung zwischen allen Typen hinzuzufügen, kann ein Cross-Join mit einigen Filtern die verbleibenden Konvertierungen einfügen.
quelle
Nachdem ich die Antwort von @Todd Everett gelesen hatte, fiel mir eine Lösung ein, und ich werde meine eigene Frage beantworten. Was ich denke , ich werde eine separate zu tun ist , erstellen
ColumnUnits
Tabelle mit vier Spalten:Schema
,Table
,Column
,UnitsID
(wo UnitsID ist FK in eine separateUnitsOfMeasure
Tabelle), so dass die Abbildung jeder gegebenen Spalte mit ihrer zugehörigen Maßeinheit. Offensichtlich ist der größte Nachteil dieser Idee, dass Entwickler daran denken müssen, diese Tabelle zu bearbeiten, wenn sie eine Spalte oder Tabelle umbenennen [ vielleicht einen DDL-Trigger verwenden ? ], sonst bricht das System zusammen. Unter der Annahme, dass solche Umbenennungen selten sind und der Dev-Shop 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.quelle