我希望在20年或更长时间内存储约2000个基金的每日基金数据。起初我想我会创建一个巨大的表,每个基金一列,每个日期一行。我在尝试创建这个表时遇到了麻烦,并且还意识到像这样的表会有很多NULL值(几乎一半的值都是NULL)。
是否有更有效的方法来构建表或数据库,以便在数百(或数千)天内快速查找和获取特定基金的数据?
我想到的另一种方法是使用三列(date,fund_id,fund_value)。然而,这对我来说似乎不是最优的,因为date和fund_id都会重复多次。只有几百万个数据点(而不是几千个)似乎很浪费。
哪个更好?或者有更好的方法来实现这一目标吗?
答案 0 :(得分:0)
您考虑的三栏方法是正确的。由于缺少值,不会浪费空间,您可以随时添加和删除资金。
搜索“数据库规范化”,这是涵盖此类设计决策的学科。
编辑:我应该补充一点,当然,您可以自由地在该表中包含其他指标。由于历史数据实际上是静态的,您也可以存储“自前一天以来的变化”,严格来说这是多余的,但可能有助于优化某些查询,例如“向我显示当天价值下降的所有资金”。 / p>
答案 1 :(得分:0)
你提到的三列很好。 fund_value
是fund_id
fund_date
的价格。因此fund_id
和fund_date
将成为此表的PK。我不明白你的意思是“只有几百万个数据点只是为了约会......”如果你有20k的资金,一个特定的日期将出现在最多20k行 - 每个基金一个。这不是不必要的重复。这对于在特定日期唯一地识别特定基金的价值是必要的。如果您在表格中添加fund_name
,那么 将是不必要的重复。我们假设基金名称不会每天变化。关于每个基金的不变(静态)数据将包含在单独的表中。然后,此表的字段fund_id
将是对静态表的FK引用。
查询特定日期的资金价值:
select fund_date as ValueDate, fund_id, fund_value
from fund_value_history
where fund_date = @aDate
and fund_id = @aFund -- to limit to a particular fund
显示基金从一天到下一天增加的日期:
select h1.fund_date, h2.fund_value as PreviousValue,
h1.fund_value PresentValue
from fund_value_history h1
join fund_value_history h2
on h2.fund_id = h1.fund_id
and h2.fund_date =(
select max( fund_date )
from fund_value_history
where fund_id = h2.fund_id
and fund_date < h2.fund_date )
where h2.fund_value < h1.fund_value
and fund_id = @aFund;
这将是一个相当大的结果集,但您可以修改WHERE子句以显示,例如,特定日期的值大于前一天的所有基金,或所有基金(或特定基金)的值特定日期和前一天,或任何数量有趣的结果。
然后,您可以加入静态表以添加基金名称或任何其他描述性数据。