다른 유형의 청구 데이터를 저장하기 위해 어떤 데이터베이스 스키마를 사용할 수 있습니까?
-
10-07-2019 - |
문제
주문을 작성하는 시스템이 있으며 주문은 하원 계좌에 청구되거나 배송시 현금을 보냈거나 신용 카드에 청구 할 수 있습니다. 다음 테이블을 만들었습니다.
명령
주문 아이디
BillingOption_id
청구서
BillingOption_id
청구 데이터를 위해 다음 테이블을 어떻게 구축 해야하는지 잘 모르겠습니다. 각 유형의 청구 옵션 (예 : 대구, 신용 카드 및 주택 계정)에 대해 별도의 테이블을 작성해야합니까? 그러면 청구 데이터에 대한 레코드를 참조 할 주문 테이블에 다른 외국 키 열이 있습니까?
해결책
당신은 어느 쪽이든 할 수 있습니다 : 큰 혼란 billingoptions
모든 유형을 포함하는 필드가있는 테이블, 주어진 유형에 적용되지 않는 필드 용 Nulls 또는 부모의 "별"이되는 많은 아기 테이블이있는 테이블 billingoptions
테이블. 둘 다 그들의 장점과 단점이 있습니다.
큰 혼란 테이블을 위해
- 모든 데이터가 단일 테이블에서 쉽게 참조 할 수 있다는 것이 좋습니다.
- 외국 키 종속성을 추적하고 업데이트 또는 인서트를 수행하는 것이 효율적입니다.
- 그러나 향후 새로운 청구 옵션을 추가하려면 테이블 구조를 변경해야하며, 데이터의 잘못된 데이터 조합이 저장 될 가능성이 있습니다 (예 : 신용 카드 유형과 동일한 레코드로 설정되는 대구 플래그).
작은 아기 테이블의 경우
- 데이터가 분할되어 프로그램의 객체 구조를 면밀히 반영하는 것이 좋습니다.
- 새로운 결제 옵션을 추가하거나 다른 사람에게 영향을 미치는 것에 대해 걱정하지 않고 기존 결제 옵션을 변경할 수 있다는 것이 좋습니다.
- 관계는 매우 명백합니다. 외국 키는 승인과 연결되어 있어야하므로 실수로 다른 예금으로 입금을 연결할 수 없습니다.
- 그러나 결국 많은 결합이 필요한 디자인에 많은 테이블을 도입하게됩니다. 많은 결합이 필요한 것은 탐색해야 할 고통이 될 수 있으며 삽입 및 업데이트와 관련하여 효율적이지 않습니다.
직장에서, 우리는 작은 아기 테이블을 가지고 갔다. 다음과 같이 보입니다.
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, Check, Cash, Store Credit 및 Money Order) 은이 승인에 적합하도록 추상화되며 UI는 동일한 방법을 호출합니다. an IPayment
그리고 IPaymentProcessor
구현이 다른 인터페이스 (CybersourcePaymentProcessor
, PayPalPaymentProcessor
, 등). 추상화는 지난 1 년 반 동안 이러한 다른 방법에 걸쳐 꽤 잘 작동했지만 때로는 GUI가 사용자에게 다른 언어를 표시 할 때가 있습니다 (예 : "승인"대신 "승인"및 "청구"라고 말할 수 있습니다. 신용 카드 지불에 대한 "예금", 현금 입력 화면은 승인/입금 단계를 한 번에 수행합니다.)
그것이 말이되기를 바랍니다. 실제로 결제 정보를 저장하지 않는 것 같지만 이러한 것들이 어디에서 끝날 수 있는지 생각하는 것이 유용합니다.
다른 팁
사물에 집중하십시오. 실제 것들. 간단하고 직접적으로 그리고 자연어로 먼저 사물을 설명하십시오.
그런 다음 디자인 지침을 요청하면 정의를 제공 할 수 있습니다. 어떤 경우에는 정의를 작성하는 행위가 설계를 결정화하게합니다.
명령 일입니다. 주문의 속성은 무엇입니까? 고객, 제품, 지불/청구 옵션.
청구 옵션 (거의) 사물입니다. 당신은 분명히 그것들을 정의하고 식별 할 수 있습니다. (나는 내가 할 수 없다. 당신의 질문에서, 당신은 할 수있을 것 같다. 그러나 일회용 요약이 없으면, 나는 10 억 옵션으로 무슨 일이 일어나고 있는지 잘 모르겠다.
"청구 데이터"란 무엇입니까? 이게 무슨 일이야? 어떤 속성 (또는 속성)이 있습니까?
"청구 데이터"는 주문과 어떤 관련이 있습니까? 청구 옵션과 어떤 관련이 있습니까?
각각의 정의로 질문을 자유롭게 업데이트하십시오.