web-dev-qa-db-ja.com

MySql請求書とサブスクリプションスキーマ

Eコマースデータベースを構築し、サブスクリプションを追加しています。以下の簡略化された構造を参照してください。

orders
id, customer_id

order_items
id, order_id, product_id

invoices
id, order_id

subscriptions
id, customer_id, product_id, run_date

私が抱えている問題はinvoicesテーブルがorder_idを必要とすることですが、サブスクリプションは請求書を生成するだけです。元のorder_idをサブスクリプションテーブルに入れて系統を追跡することもできますが、invoicesテーブルに重複した注文IDがあるため、混乱を招きます。 orderorder_itemsを削除してinvoicesテーブルを保持し、invoice_itemsテーブルを追加して注文IDを完全にバイパスすることを試みましたが、保持する方が理にかなっていると思いましたなぜなら、人々はTシャツのような通常の製品も購入でき、それらは技術的に注文だからです。請求書が正しく生成されるようにテーブルを構成する推奨方法はありますか?注文は、単一購入の製品に対するものであり、サブスクリプションに対する請求書のみであるべきですか?

5
Naterade

十分な情報はありませんが、悲しいことにコメントを投稿する評判が足りないので、前提としていても頑張ります。

  1. 定期購読は定期的なイベントを示唆しています。たぶん毎月のTシャツ定期的であるため、何も生成されません作成時に注文します。定期的なイベントがトリガーされると(毎月のTシャツがリリースされると)、購読者は自動的に注文を受け取ります。これは、アプリケーション層に実装できるビジネスルールです。
    • 1.a.アプリケーション層でそれを制御できない場合は、サブスクリプション自体をトリガーされた定期的なイベントと区別するために追加のエンティティが必要になります。この目的のために、別のテーブルを使用して、トリガーされたサブスクリプションを追跡すると便利です。そのため、Subscriptionエンティティは、顧客と製品間の多対多の関係(特定の顧客が定期購入した商品が定期購入されているかどうかに関係なく、定期購入されているかどうかに関係なく)を解決し、Subscription_triggered_eventはそのような定期購読の定期的な発生をすべて追跡します。毎月のTシャツを購読して待っています。次の月次のTシャツがリリースされると、前述のSubscription_triggered_eventテーブルに新しい行が生成され、このテーブルが対応する注文の作成をトリガーできます。
  2. 各サブスクリプションが単一の注文を生成することを前提とする必要がありますか?それらが同じ注文の異なる注文ラインに結合される場合がありますか?つまり、今月のTシャツ月のマグカップ、リリースされたら、私は手に入れますか2つの注文または2つの製品を含む1つの注文?
    • 2.a.単一の注文が生成された場合は、Orderに外部キーを持つOrderエンティティとSubscriptionエンティティの間に関係を作成できます。しかし、私の意見では、これはすべての注文がサブスクリプションによって生成される場合にのみ有効です。それ以外の場合、ユーザーがサブスクリプションとは別に注文できる場合、このソリューションはモデルをダーティにし、サブスクリプションテーブルに明示的な外部キーではなく、アプリケーション層またはトリガーによって制御されるビジネスルールを個人的に作成します。
    • 2.b.複数のサブスクリプションオカレンスを単一の注文にマージできる場合は、トリガーまたはアプリケーションが単一の注文を作成し、オカレンスを持つすべての異なる製品をラインとして配置する必要があります。このソリューションでは、Subscription_triggeredトラッキングテーブルを使用するという以前の提案が非常に役立ちます。それ以外の場合は、コード内の軽量のビューで同じことを達成できます。
  3. 最後に、注文と請求書の関係は1対1であるため、管理は簡単です。ただし、注文が最終的な状態になるまで、請求書は生成されません。注文のワークフローを制御して、「請求可能」かどうか(つまり、いつ出荷されるか)を確認する必要がある場合があります。その制御フローがないと、注文を作成するときに請求書を自動的に生成する必要がありますが、参照整合性を維持するために注文明細を作成する前に注文を作成する必要があるため、これはトリガーでは機能しません。もちろん、これはデータベースの参照整合性を削除し、アプリケーション層で制御することで解決できます。

お役に立てれば。

1
LironCareto

注文請求書支払いパターンは、会計でよく見られるものです。これらのテーブルは、ビジネスモデルの「財務」の部分に属しています。入ってくるお金を顧客の要求に結びつけることができることは、十分に確立された慣行です。あなたの財務監査人はその証跡をたどり、そこの行を他のレコードと照合できると期待します。

Subscriptionsは、取引に持ち込むための他のチャネルとともに、モデルの「販売」部分に属します。サブスクリプションは複数の外部キーを請求書と共有する場合がありますが、それらは異なるライフサイクルを持つ別個の概念です。たとえば、サブスクリプションは有効期限が切れると削除される可能性がありますが、請求書はたとえば税務目的で7年間保持する必要があります。

質問に表示するのと同じようにテーブルを保持することをお勧めします。サブスクリプションが作成されると、対応する注文と請求書を自動的に生成します。これは、アプリケーションで、またはDBMSトリガーを介して実行できます。 SubscriptionsOrdersの間には1対1の関係があります。外部キー列をSubscriptionsに追加して、Ordersが注文のソースにとらわれないようにする必要があります。

1
Michael Green

説明が難しいという事実は、設計、期待、または認識されている要件に問題があることを示しています。

Subscriptionsは、クレジットカードなどから自動的に支払われますか? Invoiceが不要に見えるのはそのためですか?またはその他の理由。

あなたの現在の状態は:

Customersは、次の2つの方法のいずれかで製品を購入できます。

  1. Orders require Invoices。おそらくあなたはそれらが支払われるようにそれらを請求する必要があります。
  2. SubscriptionsにはInvoicesがありません。サブスクリプションは、クレジットカード、Paypalなどによって自動的に支払われる可能性があります。

Customerはユーザーとの対話方法を決定するため、そのCustomerには複数のSubscriptionsがあり、Ordersを配置することもあります。そして、私は顧客が好きならいつでもcancelSubscriptionできると思います。

したがって、お客様とお客様の両方が、注文とフルフィルメント(InvoiceまたはSubscription)の完全な記録を保持する理由があります。つまり、Invoiceに対しても、何らかのSubscriptionsが必要になる可能性があります。

これを処理する方法は2つあります。つまり、同じものとして扱うか、2つの異なるものとして扱います。

  1. Subscriptionsサブスクリプションインスタンスのフルフィルメント用のInvoiceを作成します。サブスクリプションInvoiceは、サブスクリプションInvoiceを識別するために、Invoiceに使用するスキームとは異なるスキーム(たとえばSUB-Number-Date)を持つことができますOrderの場合(eg INV:InvoiceNumber)。 [私は、サブスクリプションInvoiceがすでに支払われているとマークされると思います。]

  2. サブスクリプションのヘッダーと各フルフィルメントを追跡するログを含むSubscriptionsログを作成します。これにより、CustomersSubscriptionsが満たされるたびに詳細を追跡できます。サブスクリプションが早期にキャンセルされた場合、それは顧客に未使用の金額を払い戻すために使用できます。

組織がCustomers(個人または企業)をどのように見ているかは、ビジネスに最適なアプローチを決定するのに役立ちます。

どうしましょう? Order Invoiceをより複雑なSubscription Invoiceから分離する傾向があります。必要に応じて、注文、サブスクリプション、および(返品、再発送など)の合計の概要を会社および顧客向けに作成できます。

1
RLF