在SQL中设计多种类型的支付方案?

时间:2016-08-25 17:01:22

标签: sql database database-design rdbms

我有支付系统,我可以为订单支付两种类型。

  1. 在线 - 移动支付
  2. 离线 - 现金/支票
  3. 我已经记入了4张表,我只是为了简单而概述了重要的列而不是一切。

    List of table Names
    
    Payment
    CashPaymentDetails
    ChequePaymentDetails
    MobilePaymentDetails
    
    Schema Details
    
    CashPaymentDetails
    cash_id int
    cash_amount decimal(18,2)
    
    ChequePaymentDetails
    cheque_id int
    cheque_amount decimal(18,2)
    cheque_type
    
    MobilePaymentDetails
    mobile_id int
    mobile_amount decimal(18,2)
    
    Payment
    payment_id int
    payment_amount  decimal(18,2)
    fk_cash_id int (foreign key reference to CashPaymentDetails table)
    fk_cheque_id (foreign key reference to ChequePaymentDetails table)
    fk_mobile_id (foreign key reference to MoblePaymentDetails table)
    

    用户可以做现金/支票/手机,只有一种支付方式,这使我的两个外键为NULL,我认为是开销,因为如果我前进了10种不同类型的支付方式,9 Fk引用将为NULL

    付款

    Payment_id payment_amount fk_cash_id fk_cheque_id fk_mobile_id
    1 300 1 NULL NULL
    2 200 NULL 1 NULL
    3 400 NULL NULL 1
    

    创建此架构应该是什么样的优化设计?

3 个答案:

答案 0 :(得分:0)

你的设计很好(不是唯一的选择,但很好)。我会在表格中添加一个约束,以确保实现一个 - 也就是一个 - 付款类型:

alter table payment
    add constraint chk_one_payment
        check ((fk_cash_id is not null and fk_cheque_id is null and fk_mobile_id is null) or
              (fk_cash_id is null and fk_cheque_id is not null and fk_mobile_id is null) or
              (fk_cash_id is null and fk_cheque_id is null and fk_mobile_id is not null)
             );

还有其他方式来表示一种关系。例如,您可以拥有:

  • PaymentType(其中一个"现金","支票","手机")
  • PaymentAmount
  • CheckType(如果适用)

不同类型的付款具有几乎相同的列,因此在您的情况下这是非常合理的。对于某些关系,不同的类型具有非常不同的列,并且希望在他们自己的表中。

答案 1 :(得分:0)

为PaymentMethod创建表并在Payments表中引用其PK,然后根据付款方式,您可以在相应的付款方式表中进行适当的输入。我还在[CashPaymentDetails]中添加了Payment_id,[ChequePaymentDetails]& [MobilePaymentDetails]表。

Schema Details

[PaymentMethods]
Payment_Method_id int
Payment_Method_Description varchar(50)  --  ("cash", "cheque", "mobile" etc)

[Payment]
Payment_id int
Payment_Method_id int
payment_amount  decimal(18,2)


[CashPaymentDetails]
cash_id int
payment_id int
cash_amount decimal(18,2)

[ChequePaymentDetails]
cheque_id int
payment_id int
cheque_amount decimal(18,2)
cheque_type

[MobilePaymentDetails]
mobile_id int
payment_id int
mobile_amount decimal(18,2)

答案 2 :(得分:-1)

我的建议是这样的。 在Payment表上,删除所有这些外键并添加这两个字段。

processor_type enum['bank', 'cheque', 'card']
transaction_id fk to the processor table. 

有了这个,每次更新/添加新处理器时,您只需要更新枚举,以便它采用新的支付处理器集。 transaction_id是相应表的外键,具体取决于processor_type。

如果您使用的是laravel,则可以使用多态关系 这是我的建议。