2009-01-09 62 views
4

我需要一张表来存储金融交易的状态。 这个事务的状态可以粗略地由这个类建模。坚持把钱存入数据库。设计决策

class FinancialTransaction 
{ 
    Integer txId, 
    Money oldLimit, 
    Money newLimit, 
    Money oldBalance, 
    Money newBalance, 
    Date txDate 
} 
class Money 
{ 
    Currency curr, 
    BigDecimal amount 
} 

我的模式的最初设计是这样的:

CREATE TABLE tx 
(
    txId bigint(20) unsigned NOT NULL, 
    oldlimit_currency varchar(3) NULL, 
    oldlimit_amount decimal(7,5) default 0.00, 
    newlimit_currency varchar(3) NULL, 
    newlimit_amount decimal(7,5) default 0.00, 
    ----snipped---- 
    PRIMARY KEY (txId) 
) 

有两件事情让我担心:

  1. 每一笔交易的发生基于一种货币。我还没有想到我是否需要支持可能以多种货币发生的交易。假设它不会改变;那么维持一个货币列不是更节省空间吗?我会后悔这个简单的解决方案吗?
  2. 由于每个Money项目都是一个值对象,我应该将所有Money对象保存到单独的Money表中并让原始表使用MoneyIds作为Money表的外键?

也就是说,

CREATE TABLE tx 
(
    txId bigint(20) unsigned NOT NULL, 
    oldlimit_money_id int NOT NULL, 
    newlimit_money_id int NOT NULL, 
    ----snipped---- 
    PRIMARY KEY (txId), 
    FOREIGN KEY (oldlimit_money_id) REFERENCES MONEY(id) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    FOREIGN KEY (newlimit_money_id) REFERENCES MONEY(id) ON DELETE NO ACTION ON UPDATE NO ACTION 
) 

有没有其他的设计?

谢谢lazyweb。

+0

为什么您将钱存储在事务中,而不是通过SQL事务创建引用_Transaction_的新_Money_条目,然后再执行SUM()以检出状态。这样你可以更好地追踪涉及的金额。 – 2009-01-09 08:17:32

回答

4

货币和货币价值是两个不同的概念,所以更好地将它们分开。没有必要为'价值'制作一个单独的表格,但是最好有一个用于货币,因为这些是单独的实体。新设计将如下所示:

CREATE TABLE tx 
(
    id bigint(20) unsigned primary key, 
    old_limit_currency_id int not null references CURRENCY(id), 
    old_limit_value decimal(7,5) not null, 
    new_limit_currency_id int not null references CURRENCY(id), 
    new_limit_value decimal(7,5) not null 
) 

此外,检查十进制(7,5)是否有足够的空间用于您的方案,它看起来有点低。有句老话:“安全性高于遗憾”

+0

感谢您指出小数点(7,5)。我一定会和DBA一起审查这个问题。 – ashitaka 2009-01-09 09:33:04

2
  1. 如果将来您确实需要支持两种货币之间的交易,那么应该有可能将此模型作为两种交易的一种货币进行建模。
  2. 看起来你的Money对象在语义上是值而不是实体。因此我不认为有必要将它们作为实体分开。
-3

如果这不是一个矫枉过正的行为,更进一步,将所有的金额/价值存储在一个货币,并维持一个汇率表。

+0

您需要维护整个汇率历史记录才能执行有效的计算,以便在过去引用交易 – miceuz 2009-01-09 09:13:31

2

什么约三分之一的想法:

CREATE TABLE tx 
(
    txId bigint(20) unsigned NOT NULL, 
    currency varchar(3) NOT NULL, 
    oldlimit decimal(7,5) default 0.00, 
    newlimit decimal(7,5) default 0.00, 
    ----snipped---- 
    PRIMARY KEY (txId) 
) 

一个交易的所有货币价值必须是同一种货币的,对不对?

+0

这是我可能考虑的一个不错的优化。谢谢 – ashitaka 2009-01-09 09:31:03