Какую схему базы данных можно использовать для сохранения различных типов платежных данных?

У меня есть система, которая создает заказ, и этот заказ может быть выставлен на счет дома, отправлен наличными при доставке (COD) или снят с кредитной карты. Я создал следующие таблицы:

ЗАКАЗЫ
order_id
billingoption_id

BILLINGOPTIONS
billingoption_id

Я не уверен, как должна быть построена следующая таблица для данных выставления счетов. Должен ли я создать отдельную таблицу для каждого типа оплаты (например, наложенный платеж, кредитные карты и собственный счет)? Тогда у меня будет еще один столбец внешнего ключа в таблице «Заказы», ​​который будет ссылаться на запись для данных выставления счетов?


person Mark Fruhling    schedule 23.11.2008    source источник


Ответы (2)


Вы можете сделать это любым способом: большая гудящая таблица billingoptions, в которой есть поля, охватывающие все типы, с нулевыми значениями для полей, которые не относятся к данному типу, или куча дочерних таблиц, которые «стартуют» от родителя. billingoptions стол. Оба имеют свои преимущества и недостатки.

Для большого гудящего стола,

  • Удобно, что на все данные можно легко ссылаться в одной таблице.
  • Эффективно отслеживание зависимостей внешнего ключа и выполнение обновлений или вставок.
  • НО вам необходимо изменить структуру таблицы, чтобы добавить новые варианты выставления счетов в будущем, и существует вероятность того, что будут сохранены недопустимые комбинации данных (например, в одной и той же записи будут установлены как тип кредитной карты, так и флаг наложенного платежа).

Для маленьких детских столов,

  • Хорошо, что данные разделены и точно отражают структуру объекта вашей программы.
  • Приятно, что вы можете добавлять новые способы оплаты или изменять существующие, не беспокоясь о том, что это повлияет на другие.
  • Отношения ОЧЕНЬ явные. Вы не можете случайно связать депозит с другим депозитом, так как внешний ключ потребует, чтобы он был связан с утверждением.
  • НО вы в конечном итоге вводите в дизайн множество таблиц, которые требуют большого количества 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, чек, наличные, кредит в магазине и денежный перевод) абстрагируются, чтобы соответствовать этой метафоре «Утверждение -> Депозит -> Возврат», и пользовательский интерфейс вызывает те же методы на интерфейсы IPayment и IPaymentProcessor с разными реализациями (CybersourcePaymentProcessor, PayPalPaymentProcessor и т. д.). Абстракция за последние полтора года довольно хорошо работала в этих разрозненных методах, хотя иногда графический интерфейс будет отображать для пользователя разные формулировки (например, он будет говорить «Авторизовать» и «Оплата» вместо «Утвердить» и «Депозит» для платежей по кредитным картам, а экран для ввода наличных выполняет этап «Утвердить/Депозит» одним махом.)

Надеюсь, это имеет смысл. Похоже, вы на самом деле не храните информацию о платежах, но полезно подумать о том, где эти вещи могут оказаться.

person Nicholas Piasecki    schedule 23.11.2008

Сосредоточьтесь на вещах. Актуальные вещи. Старайтесь сначала описывать вещи просто, прямо и на естественном языке.

Затем, когда вы запрашиваете рекомендации по дизайну, вы можете предоставить определения. В некоторых случаях акт написания определений заставит дизайн кристаллизоваться.

Заказы — это вещи. Каковы атрибуты заказа? Клиент, Продукт, Способы оплаты/выставления счетов.

Варианты выставления счетов — это (почти) вещи. Можно, по-видимому, определить и идентифицировать их. (Я не уверен, что смог бы. Судя по вашему вопросу, вы могли бы это сделать. Но без резюме в одно предложение я не уверен, что происходит с Billion Options.

Что такое "платежные данные"? Что это за штука? Какими атрибутами (или свойствами) он обладает?

Как «Платежные данные» связаны с Заказом? Как это связано с опцией выставления счетов?

Не стесняйтесь обновлять вопрос определениями для каждой вещи.

person S.Lott    schedule 23.11.2008