Pregunta

Necesito una tabla para almacenar el estado de una transacción financiera. El estado de esta transacción puede ser modelado aproximadamente por esta clase.

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

Mi diseño inicial del esquema se ve así:

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)
)

Dos cosas me preocupan:

  1. Cada transacción se realiza en función de una moneda. No he pensado lo suficiente en cuanto a si podría necesitar respaldar transacciones que pueden ocurrir en varias monedas. Asumiendo que no cambia; entonces, ¿no es más eficiente en el espacio mantener solo una columna de moneda? ¿Me arrepentiré de esta solución simplista?
  2. Dado que cada elemento de Money es un objeto de valor, ¿debería guardar todos los objetos de Money en una tabla de Money separada y hacer que la tabla original use moneyIds como claves foráneas para la tabla de Money?

Es decir,

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
)

¿Hay diseños alternativos?

Gracias lazyweb.

¿Fue útil?

Solución

La moneda y el valor monetario son dos conceptos diferentes, por lo que sería mejor separarlos. No es necesario hacer una tabla separada para los "valores", pero sería mejor tener una para las monedas porque estas son entidades separadas. El nuevo diseño se vería así:

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
)

Además, verifique si el decimal (7,5) tiene suficiente espacio para sus escenarios, se ve un poco bajo. Hay un viejo dicho: "Mejor prevenir que lamentar". :)

Otros consejos

  1. Si en el futuro necesita admitir transacciones entre dos monedas, debería ser posible modelar esto como dos transacciones con una de cada moneda.
  2. Parece que sus objetos Money son, semánticamente, valores en lugar de entidades. Por lo tanto, no veo la necesidad de separarlos como entidades.

¿Qué tal una tercera idea?

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)
)

Todos los valores monetarios de una transacción deben ser de la misma moneda, ¿verdad?

Si no es una exageración, vaya un paso más allá y almacene todas las cantidades / valores en una moneda única y mantenga una tabla de tasas de cambio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top