我正在尝试建立一个存储电影信息的数据库。
Title
Plot
Genre
Rating
Director
唯一困扰我的是大多数电影不只有一种类型,我正在努力弄清楚如何将其存储在 MySQL 数据库中。起初我在想我只会有一个表并将所有类型存储在一列中,用逗号分隔它们,当我想检索它们时使用 PHP 将它们分开,但我不确定这是最好的方法因为我认为当列包含“恐怖、惊悚、动作”时,我将无法分类和搜索特定类型,例如恐怖。
我正在尝试建立一个存储电影信息的数据库。
Title
Plot
Genre
Rating
Director
唯一困扰我的是大多数电影不只有一种类型,我正在努力弄清楚如何将其存储在 MySQL 数据库中。起初我在想我只会有一个表并将所有类型存储在一列中,用逗号分隔它们,当我想检索它们时使用 PHP 将它们分开,但我不确定这是最好的方法因为我认为当列包含“恐怖、惊悚、动作”时,我将无法分类和搜索特定类型,例如恐怖。
我建议你应该遵循以下结构:
表名:电影
movieid, 标题, 情节, 评级, 导演
> sample data:
>
> 1 titanic Bollywood 10 James Cameron
表名:流派
流派,流派
> sample data:
> 1 Horror
> 2 Thriller
> 3 Action
> 4 Love
表名:电影流派
moviegenresid, 电影 ID, 流派 ID
> sample data:
> 1 1 2
> 2 1 4
查询是:
select m.*,group_concat(g.genre)
from movies m inner join moviegenres mg
on m.movieid=mg.movieid
inner join genres g
on g.genreid=mg.genreid
group by m.movieid
;
看小提琴
您要在此处建模的内容称为“多对多”关系,在建模“现实世界”分类时非常常见。
有很多关于如何处理这种关系的描述,包括:
不要试图通过在每部电影的一个字段中存储多种类型来跳过额外的交集表(例如,逗号分隔的列表)。这是一种非常常见的“反模式”,它会给你带来问题,也许今天不会,也许明天不会,但最终会。我建议任何从事数据库设计工作的人阅读 Bill Karwin 的“SQL Antipatterns”(http://pragprog.com/book/bksqla/sql-antipatterns)。它以相对初学者应该可以访问的方式编写,但包含很多我们这些应该知道更好的人需要不时提醒的内容(多对多关系,字段列表解决方案/问题,以及你应该做的,是本书首先介绍的内容之一)。
我将消除任意代理键movieID
,并genreID
作为消除关系数据库不必要开销的一种方式。由于title
和genre
是自然的唯一键,我们应该使用它们而不是要求数据库维护额外的、无意义的键和表(genres
参考答案中的表)的唯一性。这应该会提高大型关系数据库的速度和性能,并且是一种很好的做法。
表名:电影
主键:title
标题、情节、评级、导演
> sample data:
> Titanic Bollywood 10 James Cameron
表名:电影流派
主键:标题,流派
标题,流派
> sample data:
> Titanic Thriller
> Titanic Romance
这也使用户和机器的查询变得更加容易,因为您不必加入额外的表来通过任意 UID 解码流派。
有点晚了,但我从上面的顶级评论代码中做了一个简单的代码
select movieid, title, plot, rating, director, group_concat(genre)
from movies
natural join moviegenres
natural join genres;