第一範式、外鍵和發票實體類型
因此,我在為我的數據庫設計大學作業做一些 DBA Stack Exchange 研究時,遇到了題為“違反第 3 範式? ”的問題,這與我自己的問題非常相似,但本質上並不能回答我的問題。
我有三個不同的對象及其可以
Invoices
為它們生成的屬性:
Plants
- 工廠編號
- 植物名稱
- 工廠價格
Courses
- 課程編號
- 課程費用
- 員工編號
- 客戶ID
GardenRentals
- 花園ID
- 客戶ID
- 花園位置
- 花園式
- 月租費
我的問題是,我可以有一個主要
Invoice
實體類型,通過外鍵使用其他實體類型(即 、 和 )的詳細資訊Plants
嗎Courses
?GardenRentals
(請記住,anInvoice
可能只是關於這三件事之一或多件事)。我問的原因是因為如果我要進行Invoice
購買Plant
,那麼顯然那個特定Invoice
的不是使用實體類型的數據Course
,也不是GardenRentals
實體類型的數據,因此這會使這兩個屬性中的外鍵為 NULL(假設我理解正確)。因此,擁有這些 NULL 將違反第一範式 (1NF)。
但所謂的“修復”將是擁有三種不同的發票實體類型,涵蓋“可能”
Invoice
為它們生成的每個實體類型。對我來說,這似乎並不正確,也沒有絲毫效率(也就是說,性能不是這裡的一個因素,因為它是一個純粹的理論任務)。另外,如果將外鍵用作實體類型的屬性,那麼我的理解是否正確,那麼相應的條目將成為使用的數據的替代品?(這意味著如果不總是使用該關係,則該條目將因此為 NULL)。這種想法背後的原因是每個實體類型都可以用一個表來表示,每個屬性由一個列表示,每個新條目都是該表中的一行。這種理解有缺陷嗎?
這是基於我的理解,它可能會根據您的確切要求而改變。
- 一張發票必須至少屬於一種發票類型。
- 一個發票類型可能有多個發票。
發票類型:
- 植物
- 培訓班
- 花園出租
對於上述要求,ER 圖將是:
我希望這個答案會對你有所幫助。
我在這裡回答了一個類似的問題。您需要的是一個 Products 表,其中包含所有可開票產品(植物、課程、花園)共有的數據,每個產品的另一個子表提供每個不同產品獨有的附加數據。
給定產品的 ID 值,將根據 Products 中找到的 type 值通過子表收集完整的產品資訊。事實上,創建三個視圖(方便地命名為植物、課程和花園)來顯示每種產品的所有資訊會非常有用。
create table Products( ID int auto_generated primary key, Type char( 1 ) check( Type in( 'P', 'C', 'G' ), Price currency; constraint UQ_Product_ID_Type unique( ID, Type ) );
如果 ID 本身是唯一的,為什麼要使用 (ID, Type) 組合創建唯一約束?所以聚合欄位可以是外鍵引用的目標。
發票表將是這樣的:
create table Invoices( ID int auto_generated primary key, ProdID int not null, ProdType char( 1 ) not null; ... constraint FK_Invoice_Product foreign key( ProdID, ProdType ) references Products( ID, Type ) );
例如,如果產品中的 ID 被指定為課程或植物,這種設計就不可能為花園創建發票。