我正在尝试构建一个存储电影信息的数据库。
Title
Plot
Genre
Rating
Director
唯一困扰我的是,大多数电影不仅仅有一种类型,我正在努力弄清楚如何将它存储在MySQL数据库中。起初我以为我只有一个表并将所有类型存储在一列中,用逗号分隔它们,当我想要检索它们时使用PHP将它们分开,但我不确定这是最好的方法因为我认为我将难以排序和搜索特定的类型,例如当柱子包含'恐怖,惊悚,行动'时的恐怖。
答案 0 :(得分:10)
我建议您遵循以下结构:
tablename:movies
movieid,title,plot,rating,director
> sample data:
>
> 1 titanic Bollywood 10 James Cameron
tablename:genres
genreid,genre
> sample data:
> 1 Horror
> 2 Thriller
> 3 Action
> 4 Love
tablename:moviegenres
moviegenresid,movieid,genreid
> 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
;
请参阅fiddle
答案 1 :(得分:8)
您希望在此处建模的内容称为“多对多”关系,在建模“真实世界”分类时非常常见。
有很多关于如何处理这种关系的描述,包括:
不要试图通过在每个电影的一个字段中存储多个类型来跳过额外的交集表(例如,以逗号分隔的列表)。这是一种非常常见的“反模式”,会引起你的问题,也许不是今天,也许不是明天,而是最终。我建议任何使用数据库设计的人给Bill Karwin的“SQL Antipatterns”(http://pragprog.com/book/bksqla/sql-antipatterns)一个读数。它是以相对初学者应该可以访问的方式编写的,但包含了很多我们这些应该知道更好的人需要不时提醒(多对多关系,一个字段列表解决方案) /问题,以及你应该做的事情,是本书所涵盖的第一件事。
答案 2 :(得分:2)
我将消除任意代理键movieID
和genreID
,以消除关系数据库的必要开销。由于title
和genre
是自然的唯一键,我们应该使用它们,而不要要求数据库来维护多余的,无意义的键和表(参考答案中的genres
表)的唯一性。 。这应该可以提高大型关系数据库的速度和性能,这是一个好习惯。
表名:电影
主键:标题
标题,剧情,等级,导演
> sample data:
> Titanic Bollywood 10 James Cameron
表名:电影类型
主键:标题,体裁
标题,体裁
> sample data:
> Titanic Thriller
> Titanic Romance
这也使查询对于用户和计算机都容易得多,因为您不必加入额外的表即可通过任意UID解码类型。
答案 3 :(得分:0)
有点晚了,但是我从上面的顶部注释代码中做了一个简单的代码
select movieid, title, plot, rating, director, group_concat(genre)
from movies
natural join moviegenres
natural join genres;