Почему моя таблица 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])
)
А затем поверните и внешний ключ.
Таким образом, если адрес требует исправления, он должен быть исправлен только в одном ряду - что, в конце концов, является точкой нормализации - исправления должны применяться только один раз.