我可以使用哪种数据库架构来保存不同类型的结算数据?

时间:2008-11-23 01:51:55

标签: design-patterns database-design architecture schema billing

我有一个创建订单的系统,该订单可以记入房屋账户,发送货到付款(COD)或收取信用卡。我创建了以下表格:

订单
ORDER_ID
billingoption_id

BILLINGOPTIONS
billingoption_id

我不确定如何为结算数据构建下一个表格。我应该为每种类型的结算选项(即COD,信用卡和众议院账户)建立一个单独的表吗?然后我会在Orders表上有另一个外键列,它会引用记帐数据的记录吗?

2 个答案:

答案 0 :(得分:8)

专注于事物。实际的事情。尝试简单,直接地用自然语言描述事物。

然后,当您要求设计指导时,您可以提供定义。在某些情况下,写定义的行为将使设计结晶。

订单是件事。订单的属性是什么?客户,产品,付款/结算选项。

结算选项是(差不多)的事情。显然,您可以定义和识别它们。 (我不确定是否可以。从您的问题来看,您似乎可以。但如果没有一句话摘要,我不确定Billion Options会发生什么。

什么是“结算数据?”这是什么东西?它有哪些属性(或属性)?

“结算数据”如何与订单相关联?它与结算选项有何关系?

随意更新每个问题的定义问题。

答案 1 :(得分:8)

你可以这样做:一个大的鸣笛billingoptions表,其中包含所有类型的字段,不适用于给定类型的字段为NULL,或者是一堆婴儿表父级billingoptions表的“明星关闭”。两者都有其优点和缺点。

对于大喇叭表,

  • 很高兴所有数据都可以在一个表中轻松引用。
  • 跟踪外键依赖关系并执行更新或插入是很有效的。
  • 但是您需要更改表格结构以便将来添加新的结算选项,并且存储数据的无效组合的可能性(例如,信用卡类型和COD标志都设置在同一记录中)。

对于小型婴儿餐桌,

  • 很好的是数据被分区并且紧密反映了程序的对象结构。
  • 很高兴您可以添加新的付款方式或更改现有付款方式,而不必担心影响其他付款方式。
  • 关系非常明确。您不能将存款与另一笔存款意外关联,因为外键需要将其与批准相关联。
  • 但是你最终在设计中引入了很多表,这些表需要大量的JOIN,可能很难导航,并且在插入和更新方面效率不高。

在工作中,我们最终选择了小婴儿餐桌。它看起来像这样:

Table Orders:
--> OrderId PK
--> (Lots of Other Fields)

Table Payments:
--> PaymentId PK
--> OrderId (FK) [There may be more than one payment per order]
--> PaymentType [Restricted field contains values like 
       'PAYPAL' or 'CREDIT', you use this to know which 
       baby table to look up that can contain additional 
       information]

Table PaymentsPayPal:
--> PaymentPayPalId PK
--> PaymentId FK points to Table Payments
--> TransactionNo
--> (Other PayPal specific fields)

Table PaymentsCheck:
--> PaymentCheckId PK
--> PaymentId FK points to Table Payments
--> RoutingNo
--> (Other e-check specific fields)

+ other tables for remaining payment types....

所有付款类型共享三个与交易相关的表格:

Table PaymentApprovals:
--> PaymentApprovalId PK
--> PaymentId FK points to Table Payments
--> Status [Some flag meaning 'Succeeded', 'Failed', 'Reversed', etc]
--> ProcessorMessage [Something the service sent back, like '(M) CVV2 Matched']
--> Amount
--> (Other administrative fields)

Table PaymentDeposits:
--> PaymentDepositId PK
--> PaymentApprovalId FK points to Table PaymentApprovals
--> Status
--> ProcessorMessage
--> Amount
--> (Other administrative fields)

Table PaymentRefunds:
--> PaymentRefundId PK
--> PaymentDepositId FK points to Table PaymentDeposits
--> Status
--> ProcessorMessage
--> Amount
--> (Other administrative fields)

我们所有的付款方式(信用卡,PayPal,Google Checkout,支票,现金,商店信用和汇票)都是抽象的,以适应此批准 - >存款 - >退款隐喻,UI在具有不同实现的IPaymentIPaymentProcessor接口上调用相同的方法(CybersourcePaymentProcessorPayPalPaymentProcessor等)。在过去的一年半中,抽象在这些不同的方法中运作良好,尽管有时GUI会向用户显示不同的措辞(例如,它会说“授权”和“收费”而不是“批准”和信用卡付款的“存款”,以及输入现金的屏幕一下子执行批准/存款步骤。)

希望这是有道理的。听起来你实际上并没有存储支付信息,但考虑这些事情最终会在哪里发挥作用是有用的。