将资金持有到数据库中。设计决定

时间:2009-01-09 07:51:54

标签: mysql database-design currency

我需要一张表来存储金融交易的状态。 此交易的状态可以由此类大致建模。

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表的外键吗?
  3. 即,

    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。

4 个答案:

答案 0 :(得分: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)是否有足够的空间用于您的方案,它看起来有点低。有一句古老的谚语:“安全而不是抱歉”:)

答案 1 :(得分:2)

  1. 如果将来您确实需要支持两种货币之间的交易,则应该可以将其建模为两种交易,并使用每种货币之一。
  2. 看起来你的Money对象在语义上是值而不是实体。因此,我认为不需要将它们作为实体分开。

答案 2 :(得分: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)
)

一笔交易的所有货币价值必须是相同的货币,对吗?

答案 3 :(得分:-3)

如果不是过度杀伤,请更进一步,将所有金额/价值存储在一种货币中并维持汇率表。