规范化问题

时间:2012-12-03 14:21:51

标签: database-design normalization

我正试图规范这种关系:

film_year  film_name  critic_id critic_name cinemas_debut           score
     2004  I robot          111        John  NY_cinema, LA_cinema       4 
     2004  I robot          222     Mathiew  NY_cinema, LA_cinema       5

哪里......

  • film_year和film_name识别一部电影。
  • Cinemas_debut是一个多值属性。
  • critic_id - > critic_name
  • film_year,film_name,critic_id - >评分

我无法将关系转换为3FN。这是我尝试过的:

  • 第1步

到1NF:

film_year  film_name  critic_id critic_name cinemas_debut           score
     2004  I robot          111        John  NY_cinema                  4 
     2004  I robot          222     Mathiew  LA_cinema                  5
     2004  I robot          111        John  NY_cinema                  4 
     2004  I robot          222     Mathiew  LA_cinema                  5
  • 第2步

到2NF:

我将critics关系标识为critics ( critic_id (pk), critic_name ) reviews关系reviews(film_year (pk), film_name (pk), critic_id (pk), score)也是film_year film_name critic_id cinemas_debut 2004 I robot 111 NY_cinema 2004 I robot 222 LA_cinema 2004 I robot 111 NY_cinema 2004 I robot 222 LA_cinema 但我不知道如何处理结果关系:

{{1}}

我的做法有什么问题?有人可以将此关系翻译为3FN吗?感谢。

3 个答案:

答案 0 :(得分:7)

我的建议是使用以下内容:

create table films
(
  film_id int,
  film_year int,
  film_name varchar(50)
);

create table critics
(
  critic_id int,
  critic_name varchar(50)
);

filmscritics创建表格后,在两者之间创建联接表

create table film_critic
(
  film_id int,
  critic_id int,
  score int
);

然后获取位置,为主要城市/位置创建一个表

create table premiere_locations
(
  location_id int,
  location_name varchar(50)
);

最后在电影和城市之间创建一个连接表

create table film_location
(
  film_id int,
  location_id int
);

然后查询您将使用的数据:

select f.film_year,
  f.film_name,
  c.critic_id,
  c.critic_name,
  fc.score,
  l.location_name
from films f
left join film_critic fc
  on f.film_id = fc.film_id
left join critics c
  on fc.critic_id = c.critic_id
left join film_location fl
  on f.film_id = fl.film_id
left join premiere_locations l
  on fl.location_id = l.location_id

请参阅SQL Fiddle with Demo

答案 1 :(得分:1)

我会以不同的方式建模。根据参数,将有3个实体: - 电影院(cinemas_debut)>>注意,您必须创建一个主键(即cinemas_id) - 电影(film_year,film_name)>>注意,您必须创建一个主键(即film_id) - 评论家(critic_id(PK),crit_name,得分)

现在,这是一个解释问题。在我看来,评论家与一部电影中的一部电影有关。因此,我会创建一个关联 - 显示(cinemas_id(FK),films_id(FK),critics_id(FK))

这样,您将拥有:

  • 电影院:2条记录(C1,C2)
  • 电影:1条记录(F1)
  • 评论家:2位评论家(CR1,CR2)
  • 显示:2条记录(C1-F1-CR1,C2-F1-CR2)

听起来更好吗? 哔叽

答案 2 :(得分:1)

好的,

  • 1St NF - 没有重复元素或元素组
    你做到了:重复数据删除电影院

  • 第二个NF:对连锁键没有部分依赖性 换句话说,确保存在唯一标识其他属性的值(几个值)

评论家(critic_id,critic_name,得分)(/ *我猜分数是评论家的一部分* /)

电影(film_name,film_year):你可以使用这两个字段来唯一地识别电影,但它不会是第3个NF - >添加PK film_id 电影(film_id(FK),film_name(FK),film_year(FK))

Cinema(cinema_name):不会出现在第3个NF中 - >添加PK cinema_id 电影院(cinema_id,cinema_name) 电影(film_id,film_name,film_year)

你需要将一部电影与电影,评论家联系起来。取决于评论家的背景:

  • 得分取决于电影和电影院 显示(cinema_id,film_id,critic_id)

  • 得分仅取决于电影 显示(film_id,critic_id),其中主键是几个外键(识别一对电影/电影/评论家)并且处于第3范式(你不分别处理这3个FK) 电影(cinema_id(FK),film_id,film_name,film_year)

  • 第3个NF:非关键属性没有依赖关系 换句话说,请确保复杂键的一部分没有标识任何属性。您没有任何属性,具体取决于系统中唯一的复杂键(仅在备选方案1中显示cinema_id / film_id / critic_id)

听起来很清楚? 哔叽