我正试图让我的脑海中浮现出令人难以置信的东西,他们称之为数据库设计并没有太大的成功,所以我将尝试通过一个例子说明我的问题。
我正在使用MySQL,这是我的问题:
说我想创建一个数据库来保存我的DVD集合。我有以下要包含的信息:
我想在这些之间建立关系,以提高效率,但不知道如何。
以下是我对数据库设计的看法:
电影表=> filmid,filmtitle,runningtime,description
年表=>年
流派表=>流派
导演表=>导演
演员表=> ACTOR_NAME
但是,我将如何创建这些表之间的关系?
另外,我为影片表创建了一个唯一的ID,主键自动递增,我是否需要为每个表创建一个唯一的ID?
最后,如果我要通过PHP表格将新电影更新到数据库中,我将如何插入所有这些数据(与关系和所有?)
感谢您提供的任何帮助, 基思
答案 0 :(得分:60)
您必须区分属性和实体。实体是一种东西 - 通常是名词。属性更像是一段描述信息。在数据库术语中,entity = table,attribute = field / column。
对于某些事情有一个单独的表,让我们使用director作为一个例子称为规范化。虽然在某些情况下它可能是好的,但在其他情况下它可能是不必要的(通常它会使查询更复杂 - 你必须加入所有东西 - 而且它更慢)。
在这种情况下,不需要年份表,因为除了年份本身之外,没有其他属性可以存储。最好对其进行非规范化并将年份存储在电影表本身中。
另一方面,董事则与众不同。也许你想要存储导演的名字,姓氏,出生日期,死亡日期(如果适用)等。你显然不希望每次你输入这个人的电影时输入导演的出生日期指示,所以为导演设立一个单独的实体是有意义的。即使你不想存储关于导演的所有这些信息(你只想要他们的名字),为它设置一个单独的表(并使用代理键 - 我会在一秒内得到它)是有用,因为它可以防止印刷错误和重复 - 如果你的某个人的名字拼写错误或输入不同(首先,最后一个与最后一个,第一个),那么如果你试图找到他们指导的其他电影,你就会失败。
对表使用代理键(主键)通常是个好主意。匹配整数比匹配字符串快得多。它还允许您自由更改名称,而无需担心存储在其他表中的外键(ID保持不变,因此您无需执行任何操作)。
你真的可以把这个设计放到相当远的地方,而这一切都是要弄清楚你想要存储在它里面的东西。
例如,不是每部电影都有一个导演,有些电影有多个导演......所以电影和导演之间会有多对多的关系,所以你需要一张表格,例如:
films_directors => **filmid, directorid**
更进一步,有时导演也是演员,反之亦然。因此,除了导演和演员表之外,您还可以使用单人表,并使用角色表加入该表。角色表将保持不同的位置 - 例如,导演,制作人,明星,额外,抓地力,编辑......它看起来更像是:
films => **filmid**, title, otherstuff...
people => **personid**, name, ....
roles => **roleid**, role name, ....
film_people => **filmid, personid, roleid**
genre => **genreid**, name, ...
film_genre => **genreid, filmid**
您可能还在film_people表中有一个role_details字段,该字段可能包含取决于角色的额外信息(例如,演员正在播放的部分的名称)。
我也将流派展示为多种多样的关系,因为电影可能属于多种类型。如果你不想要这个,那么电影只会包含一个类型,而不是film_genre表。
设置完成后,可以轻松查询和查找某个人所做的一切,或者一个人作为导演所做的一切,或者曾经导演过电影的所有人,或者所有涉及某个人的人电影..它可以继续下去。
答案 1 :(得分:19)
以下内容不是实际的MySQL代码。看起来你需要的更多是概念性的开始。所以这是一个数据库应该是什么样的模型。
对于影片中的每个演员,你都会在演员电影指数中添加一行。因此,如果演员5和13(这些演员的主键)出演电影4(同样是该电影的主键),你的索引中会有两行反映这一事实:一个电影ID = 4,和演员id = 5,另一个电影id = 4,演员id = 13。
希望有所帮助。
此外,这假设每部电影只有一个导演。如果您图书馆中的任何影片都有两位导演(如贫民窟的百万富翁),那么您需要将影片表中的导演ID分开,并创建一个导演电影索引,如上面的演员电影指数。
答案 2 :(得分:11)
这些是我使用的表格:
films (_id_, title, runningtime, description)
genres (_id_, name)
people (_id_, name, birthdate, etc...)
roles (_roleid_, rolename)
filmgenres (_filmid_, _genreid_)
castandcrew (_filmid_, _roleid_, _personid_)
没有董事和演员表,只需要一张人。这还可以包括机组成员(如果您想要追踪第二个Junior Assistant Dolly Grip是谁)。每部电影可以是任何数量的类型(例如喜剧和恐怖)。此外,人们可以在每部电影中扮演任意角色 - 那里有很多演员/导演。
角色表并不一定意味着演员正在演奏的角色,但它可以。它可能是“导演”,“制片人”,“演员”......甚至是“卢克天行者”,如果你想得到那么细粒度......我相信IMDB就是这么做的。
希望上面字段的名称应该提示外键,并且我将_underscores_
放在我使用的主键周围。
答案 3 :(得分:4)
您的电影表还需要指向流派,导演和演员表的链接。由于演员,至少会有多对多(一部电影将列出一个以上的演员,一个演员将在不止一部电影中),你需要一张表来链接它们。
Films Table => filmid, filmtitle, runningtime, description, genreid, directorid
Genre Table => genreid, genre
Director Table => directorid, director
Actors Table => actorid,actor_name
FilmActor link table => actorid, filmid (with a record linking each actor to each film)
任何可能多对多的表都需要链接表。
答案 4 :(得分:3)
我为影片表创建了一个唯一的ID,主键自动递增,我是否需要为每个表创建一个唯一的ID?
是的,每个表必须具有唯一ID。但是,这不一定是主要的自动递增键 - 它是使该特定实例唯一的任何东西。例如,对于电影,我认为标题+发行年份很常见 - 尽管你想要与电影爱好者(领域专家)核实以确保这一点。自动增量是一个后备 - 基本上,当你真的没有别的东西可以独立时。
您可以使用自动增量键以便在连接等中使用,但无论如何您应该对唯一性字段设置唯一约束。
至于实际设计,我建议如下:
Films => Primary Key(filmid), Unique Constraint(filmtitle, year),
runningtime, description,
Foreign Key(Genre), Foreign Key(DirectorId)
Genre Table => Primary Key(Genre)
Director Table => Primary Key(DirectorId), DirectorName
Actors Table => Primary Key(ActorId), ActorName
Films_Actors => Primary Key(Foreign Key(ActorId), Foreign Key(FilmId))
对于插页,坦率地说,它是一个PITA。您需要以相反的顺序插入(这是自动增量键可以是更大的PITA的地方 - 如果您可以在Actors和Directors表中添加出生日期或某些内容,那么唯一约束可以使其更容易)。
所以,你要插入Actor(s),Director,Film,然后是Films_Actors。理想情况下,所有这些都在一次交易中。此外,我假设已经填写了Genre,并且是一个选择列表 - 因此不需要插入。
答案 5 :(得分:3)
您可以下载Imdb架构here。
答案 6 :(得分:2)
我意识到你的问题已经得到解答,但我想指出你:
http://www.imdb.com/interfaces
IMDB提供其数据库的平面文本文件(减去主键)。您可能会发现这对于在您开始使用时填充数据库很有用,或者您可以在您的程序/网站中使用它,以便您只需搜索要添加到“DVD集合”的电影标题,并获得其余信息从这些中拉出来。
答案 7 :(得分:2)
有时演员是导演,反之亦然,也许你想要一个“人”表?
答案 8 :(得分:1)
你真的不需要一个YearTable,你需要的只是你电影表中的genre_id,director_id和actor_id列。
此外,您的流派,导演和演员表需要他们自己的唯一ID。
编辑:当然,这是假设每部电影只有1种类型,导演,和演员。可能并非如此。
要让很多演员属于很多电影,你需要一个单独的关系表。你可以称之为“moviesActors”(或actorsMovies),每一行都有一个actor_id和一个movie_id来说这个演员在这部电影中。
答案 9 :(得分:0)
每个表都应该有一个唯一的主键。
您应该read up上database normalization。
可能不需要年表。
如果是发布年份,那么这一年就可以存储在电影中。
如果一部电影中有多个导演,那么您将拥有一个单独的表格,该表格将保存电影表格和导演表格的主键。类似地,对于任何多对一或多对多的外键约束。特别是,我相信这适用于演员。