Reputation: 175
I'm trying to normalize this relation:
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
Where ...
I'm not able to transform relation to 3FN. This is that I have tried:
To 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
To 2NF:
I identify critics
relation as critics ( critic_id (pk), critic_name )
Also reviews
relation as reviews(film_year (pk), film_name (pk), critic_id (pk), score)
But I don't know what to do with resultant relation:
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
What is wrong in my approach? Can someone translate this relation to 3FN? Thanks.
Upvotes: 1
Views: 172
Reputation: 324
Ok,
1St NF - No repeating elements or groups of elements
You did it: deduplicate cinemas
2nd NF: No partial dependencies on a concatenated key
In other word, ensure there is a value (couple of values) identifying uniquely the other attributes
Critic(critic_id, critic_name, score) (/* I guess the score is part of the critic*/)
Film(film_name, film_year): you could use those 2 fields to identify uniquely the film, but it won't be 3rd NF -> Add a PK film_id Film(film_id (FK), film_name (FK), film_year (FK))
Cinema (cinema_name): won't be in 3rd NF -> Add a PK cinema_id Cinema(cinema_id, cinema_name) Film(film_id, film_name, film_year)
You need to associate a film to a cinema, to a critic. Depending on the context of critic:
The score depends on the film and the cinema Show(cinema_id, film_id, critic_id)
The score depends only on the film Show(film_id, critic_id) where the primary key is the couple of foreign keys (identifies one couple of cinema/film/critic) and is in 3rd normal form (you don't process on of these 3 FK separaterly) Film(cinema_id (FK), film_id, film_name, film_year)
3rd NF: No Dependencies on Non-Key Attributes In other word, be sure that no attribute is identified by a part of a complex key. You don't have any attribute depending on the only complex key of the system (cinema_id/film_id/critic_id in show in alternative 1 only)
Sounds clear? Serge
Upvotes: 1
Reputation: 247630
My suggestion would be to use the following:
create table films
(
film_id int,
film_year int,
film_name varchar(50)
);
create table critics
(
critic_id int,
critic_name varchar(50)
);
After you create the table for the films
and critics
create a join table between the two
create table film_critic
(
film_id int,
critic_id int,
score int
);
Then to get the locations, create a table for premier cities/locations
create table premiere_locations
(
location_id int,
location_name varchar(50)
);
Finally create a join table between the film and the location cities
create table film_location
(
film_id int,
location_id int
);
Then to query your data you would use:
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
Upvotes: 7
Reputation: 324
I would have modeled differently. Based on the parameters, there would be 3 entities: - Cinemas (cinemas_debut) >> Note, you must create a primary key (i.e cinemas_id) - Films (film_year, film_name) >> Note, you must create a primary key (i.e. film_id) - Critics (critic_id (PK), critic_name, score)
Now, it is a matter of interpretation. In my opinion, the critics are related to 1 film played in one particular cinema. Therefore, I would create an association - Show(cinemas_id (FK), films_id (FK), critics_id (FK))
This way, you will have:
Does it sound better? Serge
Upvotes: 1