代码之家  ›  专栏  ›  技术社区  ›  K. Ayoub

MySQL模式设计:一个具有类型列的表与多个表

  •  2
  • K. Ayoub  · 技术社区  · 6 年前

    我正在制作一个关于电影的网站,我想在一部电影和演员(导演、编剧和演员)之间建立一种关系,我有两种可能实现这一点,第一种是为每个演员创建一个表格:

    CREATE TABLE director(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));  
    CREATE TABLE writer(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));  
    CREATE TABLE actor(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));
    

    并在每个表和电影表之间建立多对多关系。
    第二种可能是为演员创建一个表,该表的类型列可以引用导演、作家或演员,并在该表和电影表之间建立多对多关系。。

    CREATE TABLE cast(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), type varchar(10));
    

    注: 对于actor,自动生成表将有一些额外的列:character_name、role。。。
    那么,在这种情况下,哪种可能性更好呢?

    3 回复  |  直到 6 年前
        1
  •  3
  •   Fikret Basic    6 年前

    我会采用第二种方法。它甚至与标准的SQL规则相对应。

    如果类型的强制转换(director、writer等)还具有一些附加属性(列),则可以进行一些修改。在这种情况下,建议将它们作为主表的子表。

    在您的情况下,主表将是“cast”。它将有ID和其他列。其他表将被创建,并对应于不同的cast成员,如table:“director”、“writer”。。。然后在每个子表之间与主“cast”表建立1-1关系。该关系在子表上是强制性的(即“director”在创建时必须与“cast”有关系)。在关系意义上,“director”的外键也是它的主键,它暗示着“cast”的主键。

    建议使用此方法,因为不仅可以向不同的强制转换成员添加其他列,而且还可以添加其他关系,以备以后扩展数据库时使用。您还可以添加“cast”的其他子表,而不改变与“movies”表相关的结构。

        2
  •  1
  •   sticky bit    6 年前

    两种方法都忽略了演员、导演、作家或。。。(通常)是一个人。那是真实的实体。一个人在电影中扮演的角色(演员,作家,…)实际上是一种关系属性。

    两种方法都会有裁员。如果有人在一部电影中扮演多个角色,比如导演和演员(想想希区柯克的客串),那么这个人就有两张唱片。这些数据在第一种方法中分布在两个表中,在第二种方法中分布在一个表中。一个人的属性,如名字等,会被存储两次,如果它们改变了,可能会互相矛盾,或者需要在两个地方都改变,等等。。

    所以我建议第三种方法:为人们提供一个表,存储一个人可以拥有的所有属性(name,…)。还有一张表格,将人们与电影联系起来,还可以显示一个人在电影中扮演的角色(演员、导演……)。

    有一个角色表也可能不是一个坏主意。

    例如。:

    CREATE TABLE people
                 (id integer AUTO_INCREMENT,
                  name varchar(50),
                  PRIMARY KEY (id));
    
    CREATE TABLE roles
                 (id integer AUTO_INCREMENT,
                  name varchar(10),
                  PRIMARY KEY (id));
    
    CREATE TABLE movies_people
                 (movie integer,
                  person integer,
                  role integer,
                  PRIMARY KEY (movie,
                               person,
                               role),
                  FOREIGN KEY (movie)
                              REFERENCES movies
                                         (id)
                              ON DELETE CASCADE,
                  FOREIGN KEY (person)
                              REFERENCES people
                                         (id),
                  FOREIGN KEY (role)
                              REFERENCES roles
                                         (id));
    
        3
  •  0
  •   Rishikesh Dhokare    6 年前

    第二种方法似乎比第一种更干净。不必维护3个不同的表,您只需获得 type 在一列中。

    此外,您可以使用 bit (0=director,1=writer,2=actor)而不是varchar(10)来存储 类型 .