将项目维度存储在表格中的最佳方法是什么?

时间:2013-12-05 00:46:14

标签: c# sql-server asp.net-mvc

我正在创建一个应用程序,用户将键入项目尺寸,例如宽度,高度,深度以及项目的重量。

public class ItemDimensions{

 public int width {get;set;}
 public int height {get;set;}
 public int depth {get;set;}
 public int weight {get;set;}

}

第一个问题是在数据库中存储这些维度的最佳值类型是什么? int string double decimal ..?

在用户界面上,将为用户提供选择维度类型以输入详细信息的选项。例如,他们可能会选择输入厘米或英寸。对于重量,他们可能会选择输入kg gr或stone等。处理这个问题的最佳方法是什么?理想情况下,我只存储一个值,而不是为每个不同的维度类型创建一个额外的列。

我自己的方法是创建一个dimensionType表,当用户选择维度时,可以说宽度高度和深度为cm,它将保持外键的维度类型,并存储数据。然后让我们说如果用户想要以英寸为单位查看它,它将检查数据的类型并进行转换。这是对这些类型的维度数据的正确方法还是有更好的方法来处理这些?

2 个答案:

答案 0 :(得分:1)

我会采用与你相同的方法。您可以将项目与其类型一起存储在主表中。您的模型使用int进行维度,但是您也允许使用十进制值 - 在SQL Server中存储它的最佳类型是decimal

你可以拥有主表

Item table
--
... -- other fields
Width decimal(38,6) -- you can decide on precision
Height decimal(38,6) -- you can decide on precision
Depth decimal(38,6) -- you can decide on precision
DimentionTypeId int FK -- the 3 above would use the same dimention type?
Weight


DimentionType table
--
DimentionTypeID int PK
Description
... -- other fields

您可以在应用程序中使用DimentionType进行查找(例如,使用维度类型填充组合框)。

答案 1 :(得分:0)

一般的经验法则是以标准格式存储您的数据,无论是长度/宽度/高度/重量或日期/时间信息等物理尺寸。如果您期望不同的单位或格式(或时区),请在存储数据之前进行一些转换,以便您知道它是可靠的,可用的格式。

测量由两部分信息组成:值和单位说明符。如果您希望用户在输入值时能够选择单位,则必须决定是否要将测量值以其原始[值,单位]格式存储,或将输入的数据转换为标准化单位,只需存储转换后的值。

例如,假设我输入的长度值为1.5 inch。您可以将值存储在两个字段中(例如LengthValueLengthUnit),或者您可以决定将值转换为标准单位(例如米)并将其存储在单个{{1}中值为Length的字段。如果用户想再次看到该值,您可以用米给它,或者使用转换方法将其转换为她选择的单位。

数据的标准表示的优点是,它可以提出简单的数据问题,例如“有多少项目的长度在150毫米到300毫米之间?”:

0.0381

或者体积小于1立方米的所有物品的平均重量怎么样?

SELECT COUNT(*)
FROM Items
WHERE Length BETWEEN 0.150 AND 0.300

如果您想存储[value,unit],那么您需要一个转换表,以便您提出这些问题:

SELECT AVG(Weight)
FROM Items
WHERE (Length * Width * Height) < 1

更复杂的是:

SELECT COUNT(*)
FROM
(
    SELECT i.LengthValue * c.Factor AS Length
    FROM Items i
    JOIN Conversion c ON c.FromUnit = i.LengthUnit
    WHERE i.ToUnit = 'm'
) l
WHERE Length BETWEEN 0.150 AND 0.300

似乎是一个人为的例子,但我在生产中看到过这样的代码。

这不仅是丑陋的代码,而且非常低效。即使您将单位说明符作为索引存储到单位表中或作为转换表的索引,查询复杂性仍然太高。

这里的缺点是,如果您允许数据​​库中的不同单元,那么 使用这些值的每个查询执行此类操作。即使您知道数据库中的每个当前长度值都已输入SELECT AVG(WeightKg) FROM ( SELECT i.LengthValue * lc.Factor AS LengthM, i.WidthValue * wc.Factor AS WidthM, i.HeightValue * hc.Factor AS HeightM, i.WeightValue * mc.Factor AS WeightKg FROM Items i JOIN Conversion lc ON lc.FromUnit = i.LengthUnit JOIN Conversion wc ON wc.FromUnit = i.WidthUnit JOIN Conversion hc ON hc.FromUnit = i.HeightUnit JOIN Conversion mc ON mc.FromUnit = i.WeightUnit -- 'm' for 'mass' WHERE lc.ToUnit = 'm' AND wc.ToUnit = 'm' AND hc.ToUnit = 'm' AND mc.ToUnit = 'Kg' ) d WHERE (LengthM * WidthM * HeightM) < 1 ,您也无法保证始终如此。