O esquema de banco de dados que eu posso usar para salvar diferentes tipos de faturamento de dados?
-
10-07-2019 - |
Pergunta
Eu tenho um sistema que cria uma ordem e que a ordem pode ser cobrado para uma conta de casa, enviou dinheiro na entrega (COD), ou cobrado a um cartão de crédito. Eu criei as tabelas a seguir:
ORDENS
order_id
billingoption_id
BILLINGOPTIONS
billingoption_id
Eu não tenho certeza de como a tabela seguinte deve ser construído para os dados de faturamento. Devo construir uma tabela separada para cada tipo de faturamento opção (ie. COD, cartões de crédito, e conta House)? Então eu teria uma outra coluna de chave estrangeira na tabela Pedidos que remete para um recorde para os dados de faturamento?
Solução
Você pode fazê-lo de qualquer maneira: uma mesa grande buzinando billingoptions
que tem campos que engloba todos os tipos, com nulos para campos que não se aplicam a um determinado tipo, ou um bando de mesas de bebê que "Star off" de uma tabela billingoptions
pai. Ambos têm suas vantagens e desvantagens.
Para a tabela buzinando grande,
- agradável-se que todos os dados podem ser facilmente referenciada em uma única tabela.
- Como acompanhar dependências chave estrangeira e realizar atualizações ou inserções é eficiente.
- Mas você precisa alterar a estrutura da tabela para adicionar novas opções de faturamento no futuro, e há a possibilidade de combinações inválidas de dados armazenados (por exemplo, tanto um tipo de cartão de crédito e uma bandeira COD sendo definida no mesmo registro ).
Para as tabelas pequena do bebê,
- agradável-se que os dados são particionados e reflete estrutura do objeto de seu programa de perto.
- É bom que você pode adicionar novas opções de pagamento ou aqueles alter existentes sem se preocupar com afetando os outros.
- As relações são muito explícitas. Você não pode acidentalmente ligar um depósito com um outro depósito, uma vez que a chave estrangeira vai exigir que ele seja ligado a uma aprovação.
- , mas você acaba introduzindo uma série de tabelas para o projeto, que requerem lotes de junções, pode ser uma dor de navegar, e não são tão eficientes quando se trata de inserções e atualizações.
No trabalho, acabamos indo com pequenas mesas de bebê. Parece algo como isto:
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....
Todos os tipos de pagamento compartilhar tabelas relacionadas três transação:
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)
Todos os nossos métodos de pagamento (cartão de crédito, PayPal, Google Checkout, cheque, dinheiro, loja de crédito e dinheiro ordem) são abstraídos para se encaixam nesta Aprovação -> Depósito -> Restituição metáfora, ea interface do usuário chama o mesmos métodos em um IPayment
e IPaymentProcessor
interfaces com diferentes implementações (CybersourcePaymentProcessor
, PayPalPaymentProcessor
, etc). A abstração tem trabalhado muito bem durante o ano passado e meio através destes métodos diferentes, embora às vezes a GUI irá exibir palavreado diferente para o usuário (por exemplo, ele vai dizer "Autorizar" e "Charge" em vez de "Aprovar" e "Depósito" para pagamentos com cartão de crédito, e a tela para inserir realiza de caixa Aprovar / Depósito passo de uma só vez.)
A esperança que faz sentido. Parece que você não está realmente armazenar informações de pagamento, mas é útil para pensar sobre onde estas coisas podem acabar.
Outras dicas
Foco nas coisas. coisas reais. Tente descrever as coisas simplesmente, diretamente, e em linguagem natural em primeiro lugar.
Então, quando você pedir orientação design, você pode fornecer definições. Em alguns casos, o ato de escrever definições fará a Crystalize design.
ordens são coisas. Quais são os atributos de um pedido? Cliente, produto, Pagamento / opções de faturamento.
Faturamento Opções são (quase) coisas. Você pode, aparentemente, definir e identificá-los. (Não tenho certeza que eu poderia. Da sua pergunta, parece que você pode ser capaz de fazer. Mas, sem um resumo de uma frase, eu não sei o que está acontecendo com bilião de possibilidades.
O que é um "dados de faturamento?" Que tipo de coisa é essa? Que atributos (ou propriedades) tem?
Como é que um "dados de faturamento" se relacionam com uma Ordem? Como ele se relaciona com a opção de faturamento?
Sinta-se livre para atualizar a questão com definições para cada coisa.