Database-Design

我應該將 FOREIGN KEY 列定義為 NULLable 嗎?

  • December 6, 2016

我一直在開發一些數據庫結構來涵蓋以下業務規則:

  • 一張發票有很多invoice_items
  • 一張發票可能有很多退款
  • 退款有很多invoice_items
  • 所有物品都應來自同一張發票
  • 退款應始終有項目

所以我想出瞭如下所示的實體關係圖(ERD):

ERD 1

我想看看退款中包含哪些invoice_items

但是,在這種情況下,無法添加外鍵 (FK) ( InvoiceItems => refunds)。原因是發票可能有也可能沒有退款

所以我修改了圖表如下:

ERD 2

在這裡我可以添加 FK ( refund_invoice_items=> invoice_items)

問題

我認為這可以解決 FK 問題,所以:您認為這是一種合適的方法還是對此有任何想法?

主要問題是,如果我可以在 FK 列中儲存 NULL 標記,第一個範例會更好嗎?(在我的情況下,我總是向定義為 FK 的列添加 NOT NULL 約束)

對我來說,你的第一個圖表已經足夠好了(從物理模型的角度來看),細節如下:

[invoice table]
invoice_id primary key
....

[refund table]
refund_id primary key,
invoice_id NOT NULL, -- FK
....

[invoice_item table]
invoice_item_id primary key,
invoice_id NOT null, -- FK
refund_id NULL  -- FK
....  

數據生成流程為

  1. 發票創建於 $$ invoice table $$
  2. 一個或多個 Invoice_items 創建於$$ invoice_item table $$ 參考步驟 1 中的 invoice_id。(注意 invoice_id 不能為 NULL,如$$ invoice_item table $$, 而refund_id 可以為空)
  3. 生成退款記錄時,關聯的 invoice_id 將在記錄內,並且一個或多個 invoice_item 記錄(屬於該 invoice_id)將因此更新其refund_id 列。

但是,對於純標準化數據模型,您的第二個模型更健壯(注意,您目前的模型圖有錯字,REFUNDS 和 REFUNDS_INVOICE_ITEMS 之間的關係應該是 1:N而不是N:1)。模型 2 的主要優點是它可以滿足您的完整性要求(而模型 1 無法滿足):

所有(退款)項目應來自同一張發票

注意:我添加*(退款)*

但是模型 1 更適合現實世界的性能(更少的連接),我經常會為了性能犧牲空間。在這種情況下,模型 1 將有很多 invoice_items,refund_id 為 NULL,而在模型 2 中,您沒有這樣的顧慮。

因此,歸根結底,您需要在性能/便利性和嚴格的業務要求之間取得平衡。在模型 2 中,您的完整性由數據庫本身保證,您需要在模型 1 中保證應用程序級別的完整性。

引用自:https://dba.stackexchange.com/questions/157352