2010-10-18 1 views
7

Sto cercando di creare un modello db di varie unità e la loro relazione l'una con l'altra. Ad esempio, 36 pollici = 3 piedi = 1 metro = 9144 metri, ecc. Questo tavolo contiene anche tazze in once, libbre, kg, grammi, cm e tutti i tipi di misure.Come si modella una tabella per la conversione di unità?

Come si fa? Stavo pensando a qualcosa di simile:

 
Amount | Units | ConversionFactor | ConversionUnits 
1  | foot | 12    | inches 
1  | yard | 36    | inches 

Ma francamente, questa sembra una pessima idea. Cercare di capire quanti metri in un cortile sarebbe molto contorto, e non credo che potrei mai memorizzare tutte le conversioni di cui ho bisogno.

Quali altre idee ci sono? So che questo è un problema risolto. Grazie!

+0

Perché avete bisogno di memorizzare unità di conversione in un database? Non cambieranno. –

+1

Ah, quanto sarebbe semplice se voi aveste adottato il sistema metrico. Ma questa è un'altra discussione. – steinar

+0

Perché voglio conservare gli alimenti e le loro informazioni nutrizionali. Voglio inserire una ricetta in grammi e accenderla a once ogni volta che ne ho voglia. –

risposta

5

Store conversions to SI units, non ad altre unità non metriche. Quindi puoi convertire tra le unità senza dover conoscere la conversione esplicita.

Unit   | Class  | Base Unit Multiplier 
------------------------------------------------------ 
foot   | length  | 0.304800610 
yard   | length  | 0.914401830 
square foot | area  | 0.092903040 
... 

Così 14 piedi nei cantieri è:

14 feet * 0.304800610 = 4.26720854 meters 
4.26720854 meters * 0.914401830⁻¹ = 4.66666667 yards 
+1

-1 per unità SI - questa soluzione è probabilmente utile in situazioni in cui le unità SI sono la norma, altrimenti è probabile che introduca errori di arrotondamento (se la conversione tra piedi e metri, ad esempio). Contro-bilanciato di +1 per includere la classe. –

+3

@Mark - Le unità SI * sono * la norma (per 6 miliardi di noi, comunque :) Inoltre, potresti avere errori di arrotondamento anche con unità imperiali, ad es. '1 piede = 0,000189393939394 miglia'. – Seth

+0

in quale Portland sei? :) Normalmente suggerirei di scegliere l'unità di conversione più piccola possibile come unità base. –

2

penso che lo schema proposto dal post originale va bene, oltre a non compresi classe (come nella risposta di Seth) - non si vuole provare convertire tra pinte e pollici.

La conversione tra due unità in cui nessuno di loro è l'unità di conversione viene semplicemente ottenuta recuperando i record di conversione di entrambe le unità e dividendo un fattore per l'altro (ad esempio 36/12 = 3 piedi in un cantiere).

Se si è particolarmente preoccupati dell'accuratezza, è possibile garantire che tutte le unità di una determinata classe abbiano voci per tutte le altre unità della stessa classe - questo mi sembra comunque eccessivo.

3

Scegli un'unità di base per ogni dimension che ti interessa (leggi questa pagina wiki, sarà utile). Ad esempio, se la maggior parte dei tuoi dati è in unità SI, scegli il chilogrammo per la massa, il secondo per il tempo, il metro per la distanza e così via. Se la maggior parte dei tuoi dati è in unità USA, scegli unità da US customary units, ad esempio sterlina per massa, piede per lunghezza, secondi per tempo.

Quindi memorizzare, per ogni unità reale che si desidera essere in grado di gestire, il fattore di conversione sull'unità di base dimensionalmente appropriata. Quindi, se si sceglie di piedi come unità di base della distanza, negozio

Unit Dimension Factor 
Foot Distance  1 
Metre Distance  3.28084 
Mile Distance  5280 

Per effettivamente fare una conversione, una volta che hai controllato che le dimensioni corrispondono, basta moltiplicare per il Factor dell'unità di origine, e dividere per il Factor dell'unità di destinazione. Ad esempio, per ottenere da metri a miglia, moltiplicare per 3,28,084 mila, poi dividere per 5280.

2
CREATE TABLE UnitConversion 
(
    [FromUnit] NVARCHAR(100), 
    [ToUnit] NVARCHAR(100), 
    [FromOffset] DECIMAL(29,10), 
    [Multiplicand] DECIMAL(29,10), 
    [Denominator] DECIMAL(29,10), 
    [ToOffset] DECIMAL(29,10) 
) 

ToUnit = (FromUnit + FromOffset) * Moltiplicando/Denominatore + ToOffset