1

我正在尝试使这种关系正常化:

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 是一个多值属性。
  • 批评者 ID -> 批评者姓名
  • 电影年、电影名、影评人 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                 

我的方法有什么问题?有人可以将这种关系翻译成 3FN 吗?谢谢。

4

3 回答 3

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

于 2012-12-03T14:38:29.500 回答
1

我会以不同的方式建模。根据参数,将有 3 个实体: - Cinemas (cinemas_debut) >> 注意,您必须创建主键(即cinemas_id) - Films (film_year, film_name) >> 注意,您必须创建主键(即 film_id ) - 评论家(critic_id (PK)、critic_name、score)

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

这样,您将拥有:

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

听起来更好吗?哔叽

于 2012-12-03T14:40:00.760 回答
1

行,

  • 1St NF - 没有重复的元素或元素组
    你做到了:去重电影院

  • 2nd NF:对连接键没有部分依赖
    换句话说,确保有一个值(几个值)唯一地标识其他属性

Critic(critic_id,critic_name, score) (/*我猜分数是critic的一部分*/)

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

Cinema (cinema_name): 不会在 3rd NF -> 添加一个 PK cinema_id Cinema(cinema_id, cinema_name) Film(film_id, film_name, film_year)

你需要将电影与电影院、评论家联系起来。根据批评者的上下文:

  • 分数取决于电影和电影院放映(cinema_id,film_id,critic_id)

  • 分数仅取决于电影 Show(film_id,critic_id),其中主键是一对外键(标识一对电影/电影/评论家)并且是第 3 范式(您不处理这 3 个FK 单独)电影(cinema_id (FK)、film_id、film_name、film_year)

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

听起来很清楚?哔叽

于 2012-12-03T15:12:42.383 回答