design-patterns - 我可以使用什么数据库模式来保存不同类型的账单数据?

标签 design-patterns database-design architecture schema billing

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

订单
订单编号
billingoption_id

账单选项
billingoption_id

我不确定应该如何为计费数据构建下一个表。我应该为每种类型的计费选项(即 COD、信用卡和家庭账户)建立一个单独的表吗?那么我是否会在 Orders 表上有另一个外键列来引用账单数据的记录?

最佳答案

您可以采用任何一种方式:一个巨大的 billingoptions 表,其中包含包含所有类型的字段,对于不适用于给定类型的字段为 NULL,或者一堆从父 billingoptions 表“开始”的婴儿表。两者各有优缺点。

对于大喇叭表,

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

对于小婴儿 table ,

  • 很高兴数据被分区并密切反射(reflect)了程序的对象结构。
  • 很高兴您可以添加新的支付选项或更改现有的支付选项,而不必担心影响其他选项。
  • 关系非常明确。您不会意外地将一笔存款与另一笔存款关联起来,因为外键需要将其与批准关联起来。
  • 但您最终会在设计中引入大量表格,这需要大量 JOIN,导航起来可能很痛苦,并且在插入和更新方面效率不高。

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

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 接口(interface)上的相同方法与不同的实现(Cyber​​sourcePaymentProcessorPayPalPaymentProcessor 等)。在过去一年半的时间里,抽象在这些不同的方法中运行良好,尽管有时 GUI 会向用户显示不同的措辞(例如,它会说“授权”和“收费”而不是“批准”和信用卡支付的“存款”,输入现金的屏幕一口气执行批准/存款步骤。)

希望这是有道理的。听起来好像您实际上并没有存储付款信息,但考虑一下这些东西最终会放在哪里是很有用的。

关于design-patterns - 我可以使用什么数据库模式来保存不同类型的账单数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/312006/

相关文章:

javascript - Javascript 中的单例设计模式

php - 没有方法重载的 PHP 中的抽象工厂

database - 如何存储在事件期间一起发生的对象集?

model-view-controller - MVC 的替代品是什么?

design-patterns - 持久的 RESTful 交互

javascript - 哪个是最安全的内存泄漏方法

java - 需要帮助识别此代码中使用的 'override method' 模式

mysql - 仅使用实体关系图查询 MYSQL 格式 [脑力挑战]

java - hibernate中的实体类映射,复杂关系

java - EIP/Apache Camel - 如何同时处理消息,但按组原子处理?