您必须区分属性和实体。实体是事物——通常是名词。属性更像是一段描述信息。在数据库行话中,实体 = 表,属性 = 字段/列。
对于某些事情有一个单独的表,让我们以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 表,电影将只包含一个genreid。
一旦设置好,就很容易查询和查找给定的人所做的一切,或者一个人作为导演所做的一切,或者曾经导演过电影的每个人,或者与特定电影相关的所有人。它可以一直持续下去。