设计并存储货币汇率交叉表

6
我需要将货币汇率交叉表格(例如http://www.exchangerates.org.uk/currency/currency-exchange-rates-table.html)的值存储在关系型数据库管理系统(RDBMS)中,我使用的是MySql。
用户每天会更新数据,系统将会保留不同版本的数据。
我想知道您会如何设计表格或者您是否需要模型。
最简单的方法当然是使用一个包含“from”,“to”和“values”列的表格。
from: char(3)
to: char(3)
value: decimal(6,4)
inverse_value: decimal(6,4)

但我希望知道是否有其他(更好的)解决方案。

非常感谢。

编辑

如果特别关注性能和可扩展性,那么保留价值/反向价值结构,并给定90种货币,货币兑换交叉表每天需要4,050条记录。

如果每天创建一个新版本,在一年内将有1,478,250条记录,查询可能会受到影响。

我已经实现了这个表格,它运行得很好,渲染交叉表格非常快,我很满意。

我只是想知道是否有更好的方法来实现这个。


2
我会对“from”和“to”字段有些谨慎。如果它将用于任何显示(您不希望更改显示方式后破坏索引),则可能需要另一个与char(3)连接的id。除此之外...value和inverse_value是用来做什么的?个人而言,我只会使用from、to和rate。 - RonaldBarzell
是的,模式只是一个简化版本,在我的情况下,我有一个额外的表格用于带有整数ID的货币。此外,需要inverse_value,因为数字可能不同。 - Marco Fucci
有没有可能给其中一个答案打分? - Ewen
3个回答

4

看起来这是一个不错的开始,如果你只是每天更新这些值,我建议添加一个日期字段而不是日期时间字段。也许可以像这样:

currency_code_from: char(3)
currency_code_to: char(3)
conversion_value: decimal(6,4)
inverse_conversion_value: decimal(6,4)
effective_date: date()

我不确定您计划查询表格的各种方式,因为这将决定您的索引需求,但我可能会使用跨currency_code_fromcurrency_code_toeffective_date字段的复合主键,然后根据需要添加任何索引以满足您特定的查询。
然后,您可能需要有一个额外的表来关联存储货币名称和货币符号(如果需要显示),也许链接到国旗图像(如果您想使用它)。
currency_code: char(3)
currency_name: varchar(50)
currency_symbol: char(3)
currency_image: varchar(100)

这个表的主键应该是货币代码(currency_code)。

2

我个人不会使用“自然键”。相反,建议创建一个涉及国家/币种实体的表:

country
-------
country_id : integer not null auto_increment
name : varchar(255)
abbrev : varchar(255)
motto : varchar(255)
. . .

然后在你的交叉表中使用这些ID:

currency_exchange
-----------------
currency_exchange_id : integer not null auto_increment
from_country_id : integer
to_country_id : integer 
value : decimal(10,4)
inverse_value : decimal(10,4)

这让我可以更改国家名称为符号、全名或其他内容,而无需更改交叉表的定义。在查询转换值时,请将这两个表连接起来。
此外,我选择了decimal(10,4),建议您查找最大可能值。限制大小并稍后发现选择的大小过小不值得编程更新麻烦。它不占用足够的空间,以使处理这些错误变得有价值。对于用于名称的varchar也是如此。Varchars存储效率高。
此外,value不总是1.00吗?(也就是说,你总是将其从1转换为其他货币的倒数吗?)如果是这样,你可以从表中删除value列。
我个人喜欢在所有表上生成ID值,所以我在交叉表上放了一个,但有些人可能认为它是不必要的。我经常发现,当我选择省略它时,我希望我已经添加了它。
我可以看到为货币名称拥有另一个表:
currency
--------
currency_id : integer not null auto_increment
country_id : integer
name : varchar(255)
symbol : varchar(255)

我同意,我也不喜欢自然键,我的只是一个简化版本。我实际上对性能和可扩展性很感兴趣,我会更新帖子并尽力更清晰地表达。此外,该值始终!= 1,而理论上应为1/值的倒数可能会因买入/卖出的性质而有所不同。最后,感谢您关于小数的提示,这绝对是一个好观点! - Marco Fucci
关于性能等问题。我曾经有一个类似的交叉表(游戏对手之间的击杀次数),这正是我想到的方法。效果很好。 - Marvo

2

Marco,你可能需要一个日期字段或布尔值isCurrent,以便选择最新的ccy转换。

你想要买入和卖出数字吗?通常情况下,你要确保在购买和销售ccy之间有一定的余地,以确保组织不会亏损。这被一些人称为明智的商业方法,而被其他人称为勒索。

如果这些数字是手动输入的,请确保查看货币的上一个数字,如果差异> 3%,则警告用户。

唯一的问题是当汇率在一天中大幅波动时。你想在宣战之前只使用一个转换吗?

看起来你走在了正确的轨道上。


是的,那些是买入/卖出数字。我说客户将手动输入值只是为了简化事情。实际上,他将上传由内部工具自动生成的Excel表格。 - Marco Fucci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接