Почему моя таблица 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

РЕДАКТИРОВАТЬ: Как вы думаете, это может работать так? Я создал еще одну таблицу под названием location со всей информацией об адресе, которая ранее была в таблице событий, и сделал PFK id_event.

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

2 ответа

Решение

Ответить на вопрос.

Вы правы, база данных не в 3-й нормальной форме. Как вы определили, есть возможность нормализовать различные почтовые индексы, города и улицы. Это привело бы к строке для каждого почтового индекса (и т. Д.), И у вас были бы FK для каждого.

Лично я этого не делаю. Очевидно, это зависит от приложения, но в моих системах я больше заинтересован в получении адреса пользователя, а не всех пользователей, имеющих определенный почтовый индекс.

В зависимости от того, как вы намереваетесь использовать ваши данные, третий нормальный режим может оказаться не самым эффективным способом хранения ваших данных.

На основании ваших правок - закрыть, но я бы все перевернул. Я бы дал 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])
) 

А затем поверните и внешний ключ.

Таким образом, если адрес требует исправления, он должен быть исправлен только в одном ряду - что, в конце концов, является точкой нормализации - исправления должны применяться только один раз.

Другие вопросы по тегам