5 mysql sql database-design many-to-many join
我正在尝试构建一个存储电影信息的数据库.
Title
Plot
Genre
Rating
Director
Run Code Online (Sandbox Code Playgroud)
困扰我的唯一一件事是,大多数电影不仅仅有一种类型,我正在努力弄清楚如何将它存储在MySQL数据库中.起初我以为我只有一个表并将所有类型存储在一列中,用逗号分隔它们,当我想要检索它们时使用PHP将它们分开,但我不确定这是最好的方法因为我认为我很难排序和搜索特定的类型,例如恐怖,当列包含'恐怖,惊悚,行动'.
Pra*_*nan 10
我建议你应该遵循以下结构:
tablename:电影
movieid,标题,情节,评级,导演
> sample data:
>
> 1 titanic Bollywood 10 James Cameron
Run Code Online (Sandbox Code Playgroud)
tablename:流派
genreid,流派
> sample data:
> 1 Horror
> 2 Thriller
> 3 Action
> 4 Love
Run Code Online (Sandbox Code Playgroud)
tablename:moviegenres
moviegenresid,movieid,genreid
> sample data:
> 1 1 2
> 2 1 4
Run Code Online (Sandbox Code Playgroud)
查询是:
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
;
Run Code Online (Sandbox Code Playgroud)
看小提琴
你想在这里建模的东西被称为"多对多"关系,在建模"真实世界"分类时非常常见.
有很多关于如何处理这种关系的描述,包括:
不要试图通过在每个电影的一个字段中存储多个类型来跳过额外的交集表(例如,以逗号分隔的列表).这是一个非常常见的"反模式",会导致你的问题,也许不是今天,也许不是明天,但最终.我建议任何使用数据库设计的人都会给Bill Karwin的"SQL Antipatterns"(http://pragprog.com/book/bksqla/sql-antipatterns)一个阅读.它是以相对初学者应该可以访问的方式编写的,但包含了很多我们这些应该知道更好的人需要不时提醒(多对多关系,一个字段列表解决方案) /问题,以及你应该做的事情,是本书涵盖的第一件事.
我将消除任意代理键movieID,并genreID作为消除关系数据库不必要的开销的一种方法。由于title和genre是自然的唯一键,因此我们应该使用它们,而不是要求数据库维护额外的、无意义的键和表(genres引用答案中的表)的唯一性。这应该可以提高大型关系数据库的速度和性能,并且是一个很好的实践。
表名:电影
主键:标题
标题、剧情、评分、导演
> sample data:
> Titanic Bollywood 10 James Cameron
Run Code Online (Sandbox Code Playgroud)
表名:moviegenres
主键:标题、类型
标题、类型
> sample data:
> Titanic Thriller
> Titanic Romance
Run Code Online (Sandbox Code Playgroud)
这也使得用户和机器的查询变得更加容易,因为您不必加入额外的表来通过任意 UID 解码流派。