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

相关问题