Database-Design
我應該將 FOREIGN KEY 列定義為 NULLable 嗎?
我一直在開發一些數據庫結構來涵蓋以下業務規則:
- 一張發票有很多invoice_items。
- 一張發票可能有很多退款
- 退款有很多invoice_items。
- 所有物品都應來自同一張發票。
- 退款應始終有項目。
所以我想出瞭如下所示的實體關係圖(ERD):
我想看看退款中包含哪些invoice_items。
但是,在這種情況下,無法添加外鍵 (FK) (
InvoiceItems => refunds
)。原因是發票可能有也可能沒有退款。所以我修改了圖表如下:
在這裡我可以添加 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 ....
數據生成流程為
- 發票創建於 $$ invoice table $$
- 一個或多個 Invoice_items 創建於$$ invoice_item table $$ 參考步驟 1 中的 invoice_id。(注意 invoice_id 不能為 NULL,如$$ invoice_item table $$, 而refund_id 可以為空)
- 生成退款記錄時,關聯的 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 中保證應用程序級別的完整性。