0

我已經創建了這個數據庫。看起來它工作正常,除了我被告知我的表「事件」不是第三範式。我不明白爲什麼它不是第三種正常形式。我認爲這可能是因爲城市和郵政編碼應該始終相同,但大城市可以有多個郵政編碼,而且我沒有看到只爲城市和他們的郵政編碼創建另一個表的重點,相關到事件表。爲什麼我的SQL表格不是3個正常格式

同樣抱歉,如果某些名稱或屬性使用系統保留的某些名稱命名不正確。我不得不把代碼翻譯成英文,因爲我用我的母語寫了它:)。謝謝你的幫助。

Create table [article] 
(
    [id_article] Integer Identity(1,1) NOT NULL, 
    [id_author] Integer NOT NULL, 
    [id_category] Integer NOT NULL, 
    [title] Nvarchar(50) NOT NULL, 
    [content] Text NOT NULL, 
    [date] Datetime NOT NULL, 
Primary Key ([id_article]) 
) 
go 

Create table [author] 
(
    [id_author] Integer Identity(1,1) NOT NULL, 
    [name] Nvarchar(25) NOT NULL, 
    [lastname] Nvarchar(25) NOT NULL, 
    [email] Nvarchar(50) NOT NULL, UNIQUE ([email]), 
    [phone] Integer NOT NULL, UNIQUE ([phone]), 
    [nick] Nvarchar(20) NOT NULL, UNIQUE ([nick]), 
    [passwd] Nvarchar(50) NOT NULL, 
    [acc_number] Integer NOT NULL, UNIQUE ([acc_number]), 
Primary Key ([id_author]) 
) 
go 

Create table [event] 
(
    [id_event] Integer Identity(1,1) NOT NULL, 
    [id_author] Integer NOT NULL, 
    [name] Nvarchar(50) NOT NULL, 
    [date] Datetime NOT NULL, UNIQUE ([date]), 
    [city] Nvarchar(50) NOT NULL, 
    [street] Nvarchar(50) NOT NULL, 
    [zip] Integer NOT NULL, 
    [house_number] Integer NOT NULL, 
    [number_registered] Integer Default 0 NOT NULL Constraint [number_registered] Check (number_registered <= 20), 
Primary Key ([id_event]) 
) 
go 

Create table [user] 
(
    [id_user] Integer Identity(1,1) NOT NULL, 
    [name] Nvarchar(15) NOT NULL, 
    [lastname] Nvarchar(25) NOT NULL, 
    [email] Nvarchar(50) NOT NULL, UNIQUE ([email]), 
    [phone] Integer NOT NULL, UNIQUE ([phone]), 
    [passwd] Nvarchar(50) NOT NULL, 
    [nick] Nvarchar(20) NOT NULL, UNIQUE ([nick]), 
Primary Key ([id_user]) 
) 
go 

Create table [commentary] 
(
    [id_commentary] Integer Identity(1,1) NOT NULL, 
    [content] Text NOT NULL, 
    [id_article] Integer NOT NULL, 
    [id_author] Integer NULL, 
    [id_user] Integer NULL, 
Primary Key ([id_commentary]) 
) 
go 

Create table [category] 
(
    [id_category] Integer Identity(1,1) NOT NULL, 
    [name] Nvarchar(30) NOT NULL, 
Primary Key ([id_category]) 
) 
go 

Create table [registration] 
(
    [id_user] Integer NOT NULL, 
    [id_event] Integer NOT NULL, 
Primary Key ([id_user],[id_event]) 
) 
go 


Alter table [commentary] add foreign key([id_article]) references [article] ([id_article]) on update no action on delete no action 
go 
Alter table [article] add foreign key([id_author]) references [author] ([id_author]) on update no action on delete no action 
go 
Alter table [event] add foreign key([id_author]) references [author] ([id_author]) on update no action on delete no action 
go 
Alter table [commentary] add foreign key([id_author]) references [author] ([id_author]) on update no action on delete no action 
go 
Alter table [registration] add foreign key([id_event]) references [event] ([id_event]) on update no action on delete no action 
go 
Alter table [commentary] add foreign key([id_user]) references [user] ([id_user]) on update no action on delete no action 
go 
Alter table [registration] add foreign key([id_user]) references [user] ([id_user]) on update no action on delete no action 
go 
Alter table [article] add foreign key([id_category]) references [category] ([id_category]) on update no action on delete no action 
go 

編輯: 你認爲它可以這樣工作嗎?我製作了另一張名爲「位置」的表格,其中包含以前在事件表中的所有地址信息,並創建了id_event PFK。

Create table [event] 
(
    [id_event] Integer Identity(1,1) NOT NULL, 
    [id_author] Integer NOT NULL, 
    [name] Nvarchar(50) NOT NULL, 
    [datr] Datetime NOT NULL, 
    [number_registered] Integer Default 0 NOT NULL Constraint [number_registered] Check (number_registered <= 20), 
Primary Key ([id_event]) 
) 
go 


Create table [location] 
(
    [city] Char(1) NOT NULL, 
    [id_event] Integer NOT NULL, 
    [street] Char(1) NOT NULL, 
    [house_number] Char(1) NOT NULL, 
    [zip] Char(1) NOT NULL, 
Primary Key ([id_event]) 
) 
go 


Alter table [event] add foreign key([id_auhtor]) references [author] ([id_author]) on update no action on delete no action 
go 

Alter table [location] add foreign key([id_event]) references [event] ([id_event]) on update no action on delete no action 
go 
+0

我想說審稿人是正確的這不是...畢竟你沒有一個不同的郵政編碼,城市和街道表。但是...你想要嗎?完美的標準化並不總是「正確」的方式。 – Liath

+5

兩個事件是否可以在同一地址發生?如果是這樣,我會認爲分離應該是所有的地址列到一個單獨的表中。但是,通常,僅通過查看錶定義,就無法確定表是否處於第三範式。無論他們是否取決於實際的*數據*。 –

+0

@Liath:如果它不在3NF中,則必須有傳遞依賴。它在哪裏? –

回答

1

回答這個問題。

你是對的,數據庫不是第三範式。正如你已經確定的那樣,有機會規範化各種郵政編碼,城市和街道。這將導致每個郵政編碼(等)的行,你會有每個FKs。

個人而言,我不這樣做。這顯然取決於應用程序,但在我的系統中,我更感興趣的是獲取用戶的地址,而不是擁有特定郵政編碼的所有用戶。

取決於你打算如何使用你的數據第三法線可能不是最有效的方式來存儲你的數據。

+1

好的,假設我們爲郵政編碼創建了一個郵政編碼表。進一步說,我們決定成爲關係純粹主義者,併爲此表使用自然主鍵 - 郵政編碼是唯一的,所以我們將使用它。現在,來自'event'表的外鍵將是...郵政編碼。我認爲,通過將郵政編碼轉換爲單獨的表格,您不會達到任何形式的規範化。 –

+0

非常好的一點 - 我個人認爲你所希望達到的所有效果都是使用ID鍵來最大限度地減少某些痕跡的大小......但是我認爲你會使數據更難以查詢和複雜化。 – Liath

+0

我編輯我的帖子與我的嘗試,使其正確。你怎麼看待這件事?你認爲它會起作用並完成第三種標準形式嗎? – Arcane

1

根據您的編輯 - 關閉,但我會轉過身來。我給location一個location_id列(PK),刪除其event_id列,然後讓event是:

Create table [event] 
(
    [id_event] Integer Identity(1,1) NOT NULL, 
    [id_author] Integer NOT NULL, 
    id_location Integer NOT NULL, /* Or null? does every event have to have a location */ 
    [name] Nvarchar(50) NOT NULL, 
    [datr] Datetime NOT NULL, 
    [number_registered] Integer Default 0 NOT NULL Constraint [number_registered] Check (number_registered <= 20), 
Primary Key ([id_event]) 
) 

再反向外鍵也是如此。

這樣,如果地址需要更正它只需要在一行中糾正 - 這畢竟是歸一化點 - 使得更正只需要應用一次。

+0

所以它會是這樣嗎? http://i.imgur.com/Uav7Mqs.png – Arcane

+0

@奧術 - 是的,這就是我所期望的(考慮到我期望出現在這些名字的表格中的假想數據 - 就像我在我的對你的問題提出最初的評論,但實際上不可能知道表格是否被標準化,而實際上不知道數據的外觀和實際使用的用途) –

+0

好的,作者將如何使用INSERT腳本添加事件?他會在id_location中輸入什麼內容?我認爲,如果它像我一樣處於弱勢實體,他將不得不輸入地址,但現在看起來並不像。 – Arcane

相關問題