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

创建相关表以避免可能的空字段

  •  0
  • Ayoub k  · 技术社区  · 6 年前

    假设我有一个名为 电影明星 包含以下列:

    CREATE TABLE `movie_celebrity` (
      `id` int(11) NOT NULL,
      `movie_id` int(11) NOT NULL,
      `celebrity_id` int(11) NOT NULL,
      `movie_celebrity_type_id` int(11) NOT NULL,
      `role` varchar(10) DEFAULT NULL,
      `character_name` varchar(50) DEFAULT NULL
    )
    

    所以如果名人的类型是 主任 role character_name 仅当类型为时,才会为空 演员 此字段将被填充。

    这真的是个糟糕的设计吗?或者这只是有点低效?
    我假设为这两列创建一个单独的表会更好。

    (包括架构)

    电影表:

    CREATE TABLE `movie` (
      `id` int(11) NOT NULL,
      `name` varchar(100) NOT NULL,
      `poster` varchar(255) DEFAULT NULL,
      `release_Date` date NOT NULL,
      `runtime` time NOT NULL,
      `storyline` text NOT NULL,
      `rated` varchar(10) DEFAULT NULL,
      `rating` float(2,1) NOT NULL DEFAULT '0.0',
      `inserted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
    )
    

    CREATE TABLE `celebrity` (
      `id` int(11) NOT NULL,
      `name` varchar(100) NOT NULL,
      `picture` varchar(255) DEFAULT NULL,
      `date_of_birth` date NOT NULL,
      `biography` text NOT NULL
    )
    

    CREATE TABLE `movie_celebrity` (
      `id` int(11) NOT NULL,
      `movie_id` int(11) NOT NULL,
      `celebrity_id` int(11) NOT NULL,
      `type` varchar(10) NOT NULL,
      `role` varchar(10) DEFAULT NULL,
      `character_name` varchar(50) DEFAULT NULL
    )
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Schwern    6 年前

    看来你想做一张“演员和工作人员”的组合表。取决于你用它做什么,把它们都放在一张桌子上可能是个好主意,或者最好有单独的“演员”和“剧组”。我想从一个组合表开始,看看效果如何。如果不成功,你可以把桌子分开 create a view 向后兼容。

    movie_celebrity_type_id 是指“作家”或“演员”或“导演”之类的 role 代表“领导”或“支持”。这似乎很奇怪。许多电影没有定义“领导”和“支持”的演员阵容。很多名人都是编剧,演员和制片人。阿尔弗雷德希区柯克就是一个很好的例子。

    你的 movie celebrity 桌子很好,不过我可能会打电话给他们 persons . 我会这样设计连接他们的桌子:

    create table cast_and_crew (
        id integer primary key auto_increment,
        movie_id integer not null,
        celebrity_id integer not null,
        role text not null,
        character_name text,
        credited boolean not null default true,
        notes json not null default '{}'
    
        foreign key(movie_id) references movie(id),
        foreign key(celebrity_id) references celebrity(id),
    
        -- Include the character name for people who act in more than one role
        unique(movie_id, celebrity_id, role, character_name)
    );
    

    cast_and_crew . 因为其他参赛者中的大多数都是演员 character_name ,把它变成一个真正的专栏就好了。这个 notes JSON column 为任何其他数据位提供灵活性,而无需添加更多列。

    例如,艾尔弗雷德·希区柯克在 The Birds

    insert into cast_and_crew (movie_id, celebrity_id, role, character_name, credited)
        values(<The Birds>, <Alfred Hitchcock>, 'actor', 'Man Walking Dogs Out of Pet Shop', false);
    

    <The Birds> <Alfred Hitchcock> 是他们各自的身份证。

    再次担任制片人和导演。

    insert into cast_and_crew (movie_id, celebrity_id, role)
        values(<The Birds>, <Alfred Hitchcock>, 'producer');
    
    insert into cast_and_crew (movie_id, celebrity_id, role)
        values(<The Birds>, <Alfred Hitchcock>, 'director');
    

    而阿尔弗雷德·希区柯克的助手佩吉·罗伯逊可能会利用这个机会

    insert into cast_and_crew (movie_id, celebrity_id, role, noes)
        values(<The Birds>, <Peggy Robertson>, 'assistant', '{ "to": <Alfred Hitchcock> }');
    

    可以编写使用此表的代码来根据角色实例化子类。例如,您可以编写一个泛型 CastAndCrew CastAndCrew::Actor 子类将提供 name 方法并要求对其进行定义。 CastAndCrew::Assistant to 字段输入 .

    另一个例子是被誉为“鸟类训练师”的雷·伯维克。你可以放进去 role = 'trainer of the birds' 但是如果你想找所有的驯兽师呢?你可以有详细的和规范化的角色,详细的角色是“鸟的驯兽师”,规范化的角色是“动物驯兽师”。取决于你想完成什么。

    可能会有更多的改进,但它们取决于您对数据的处理方式。