2012-08-14 71 views
3

我是数据库设计的新手,请耐心等待。我使用PHP和MySQL。 我有一个'电影'表,其中包含一些关于电影的细节。这包括类型,其具有(如果我理解正确的话)与电影的多对多关系,暗示单个电影可以属于不同类型,并且单个类型可以属于不同电影。数据库设计:外键和规范化

从我收集的数据库设计中,将这种关系存储在一张表中并不是一个好主意,因为它会违反First Normal形式或Second Normal形式规则。 我会如何设计我的桌子来避免这种情况;我需要为每个流派分别创建一张桌面还是......?

这导致我到我的下一个问题:单独的表需要有外键来标识哪些信息属于哪一行。从理论上讲,如果我有一个唯一的关键字来标识每部电影,然后我想用它来在一张单独的表中标识一个导演,那么我将如何在MySQL中创建这种关系?

谢谢你的时间 - 如果我有什么不清楚的地方,请让我知道,我会尽我所能来澄清。

回答

4

这包括流派,其具有(如果我理解正确)许多 一对多的关系与电影,暗示一部电影可能属于 以不同的流派和单一的流派可以属于不同的电影。

没错。

从我收集有关数据库设计,存储这种 关系中一个表是不是一个好主意

权。你正在寻找松散的东西沿着这些线。

create table movies (
    movie_id integer primary key 
    -- other columns 
); 

create table genres (
    genre varchar(15) primary key 
    -- other columns? 
); 

create table movie_genres (
    movie_id integer not null, 
    genre varchar(15) not null, 
    primary key (movie_id, genre), 
    foreign key (movie_id) references movies (movie_id), 
    foreign key (genre) references genres (genre) 
); 

董事,假设有每部电影只有一个导演,你可以用它来代替电影台以上

create table movies (
    movie_id integer primary key, 
    director_id integer not null, 
    foreign key (director_id) references directors (director_id) -- not shown. 
    -- other columns 
); 
+0

非常感谢您提供了非常全面的答案,特别感谢您解答外键问题。 – styke 2012-08-14 13:03:05

2

您需要一张表电影,一张表流派和一张表Movies_and_Genres。前两个包含可使用mysql自动增量字段类型创建的唯一主键。第三个表格包含这些主键对。

create table movies (id integer not null primary key auto_increment, title ...); 
create table genres (id integer not null primary key auto_increment, genre ...); 
create table movies_and_genres (id_movie integer not null, id_genre integer not null); 

至于董事,这是一个数据建模的问题。如果一部电影可以有多个导演,那么你需要一个导演和一个movies_and_directors表格。否则,您只需要电影表中的导演表和导演列。

2

你需要/应该使用junction tables

电影:

| id | title | rating | 
----------------------- 
| 1 | foo | 5 | 
| 2 | bar | 4 | 

流派:

| id | name | 
---------------- 
| 1 | comedy | 
| 2 | romance | 

导演:

| id | name | 
---------------- 
| 1 | hello | 
| 2 | world | 

MOVIE_GENRE:

| id | movie_id | genre_id | 
---------------------------- 
| 1 |  1 |  1 | 
| 2 |  1 |  2 | 
| 3 |  2 |  1 | 

movie_director:

| id | movie_id | director_id | 
------------------------------- 
| 1 |  1 |  1  | 
| 2 |  2 |  1  | 
| 3 |  2 |  2  | 
2

你说的很对,你所需要的就是有一个电影表(例如tbl_movies);

pk id 
     name 
     ... etc 

一个流派表(例如tbl_genres);

pk id 
     name 
     ... etc 

和一个链接两个表(例如tbl_movie_genres)的表;

fk id_movies 
fk id_genres 

您可以设置tbl_movie_geners的PK是两个外键,也可以设置一个独立的PK(例如id如上面的tbl_moviestbl_genres表)。

这种方式,你可以列出每部电影的许多流派,他们通过tbl_movie_genres表链接;例如:

tbl_movies: 
id name 
1  Movie 1 
2  Movie 2 

tbl_genres: 
id name 
1  Horror 
2  Action 
3  Rom Com 

tbl_movie_genres 
id_movies id_genres 
1   3 
2   1 
2   2 

会告诉你,'电影1'是一个rom com,'电影2'是一个动作恐怖。

1

为了满足多对多的关系,使用连接表中包含外键都在电影和流派表:

MOVIE 
----- 
ID (PK) 

GENRE 
----- 
ID (PK) 

MOVIE_GENRE 
----------- 
MOVIE_ID (FK that references MOVIE(ID)) 
GENRE_ID (FK that references GENRE(ID)) 

这里MOVIE表有ID一个主键,GENRE表有主键IDMOVIE_GENRE表有两个外键引用:一个到MOVIE.ID,另一个到GENRE.IDMOVIE_GENRE的主键可以是(MOVIE_ID,GENRE_ID)的组合键,因为这将是唯一的,但您也可以使用合成键。

对于与导演表和关系处理,如果是一个一对多的关系(多部电影有一个董事),只需添加一个外键MOVIE表:

DIRECTOR 
-------- 
ID (PK) 

MOVIE 
----- 
ID (PK) 
DIRECTOR_ID (FK TO DIRECTOR(ID)) 

如果即使你需要支持另一个多对多的关系(许多导演对许多电影),使用上面的连接表方法。