views:

49

answers:

3

I'm looking to create a db model of various units and their relation to each other. For instance, 36 inches = 3 feet = 1 yard = .9144 meters etc. This table would also store cups in ounces, pounds, kg, grams, cm and all sorts of measurements.

How do you do this? I was thinking about something like this:

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

But frankly, this seems like a terrible idea. Trying to figure out how many feet in a yard would be very convoluted, and I don't think I could ever store all the conversions I need.

What other ideas are there? I know this is a solved problem. Thanks!

+3  A: 

Store conversions to SI units, not to other non-metric units. Then you can convert between units in without needing to know the explicit conversion.

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

So 14 feet in yards is:

14 feet * 0.304800610 = 4.26720854 meters
4.26720854 meters * 0.914401830⁻¹ = 4.66666667 yards
Seth
-1 for SI units - this solution is only likely to be useful in situations where SI units are the norm, otherwise it is likely to introduce rounding errors (if converting between feet and yards, for example). Counter-balanced by +1 for including Class.
Mark Bannister
@Mark - SI units *are* the norm (for 6 billion of us, anyway :) Besides, you may get rounding errors with imperial units too, e.g.: `1 foot = 0.000189393939394 miles`.
Seth
@Seth - which Portland are you in? :) I would normally suggest picking the smallest possible conversion unit as the base unit.
Mark Bannister
+1  A: 

I think the original post's proposed schema is fine, apart from not including Class (as in Seth's answer) - you don't want to try to convert between pints and inches.

Converting between two units where neither of them is the conversion unit is simply achieved by retrieving both units' conversion records and dividing one factor by the other (eg. 36/12 = 3 feet in a yard).

If you are particularly concerned about accuracy, you could ensure that all units for a given class have entries for all other units in the same class - this strikes me as overkill, though.

Mark Bannister
+1  A: 

Pick a base unit for each dimension you are interested in (read that wiki page, it'll be useful). For example, if most of your data is in SI units, you would pick kilogram for mass, second for time, metre for distance, and so on. If most of your data is in US units, pick units from the US customary units, for example pound for mass, foot for length, second for time.

Then store, for each actual unit you want to be able to handle, the conversion factor to the dimensionally-appropriate base unit. So if you choose foot as your base unit of distance, store

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

To actually do a conversion, once you've checked that the dimensions match, simply multiply by the Factor of the source unit, and divide by the Factor of the destination unit. For example, to get from metres to miles, multiply by 3.28084, then divide by 5280.

AakashM