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

ckocjqey  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(265)

假设我有一个名为movie\u名人的表,它有以下列:

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 将为空,仅当类型为actor时,此字段才会被填充。
这真的是个糟糕的设计吗?或者这只是有点低效?
我假设为这两列创建一个单独的表会更好。
编辑(包括架构)
电影表:

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
)
vuktfyat

vuktfyat1#

看来你想做一张“演员和工作人员”的组合表。取决于你用它做什么,把它们都放在一张table上可能是个好主意,或者最好有单独的“演员”和“剧组”。我想从一个组合表开始,看看效果如何。如果不成功,可以拆分表并创建一个向后兼容的视图。
根据作者的评论, movie_celebrity_type_id 是指“作家”或“演员”或“导演”之类的 role 代表“领导”或“支持”。这似乎很奇怪。许多电影没有定义“领导”和“支持”的演员阵容。很多名人都是编剧,演员和制片人。阿尔弗雷德希区柯克就是一个很好的例子。
你的 movie 以及 celebrity table很好,不过我可能会打电话给他们 persons . 我会这样设计连接他们的table:

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列为任何其他数据位提供了灵活性,而无需添加更多的列。
例如,艾尔弗雷德·希区柯克在《鸟》中未经认可的出现。。。

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(, , 'producer');

insert into cast_and_crew (movie_id, celebrity_id, role)
values(, , 'director');

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

insert into cast_and_crew (movie_id, celebrity_id, role, noes)
values(, , 'assistant', '{ "to": }');

可以编写使用此表的代码来根据角色示例化子类。例如,您可以编写一个泛型 `CastAndCrew` 班级。然后 `CastAndCrew::Actor` 子类将提供 `name` 方法并要求对其进行定义。 `CastAndCrew::Assistant` 就会知道找一个 `to` 字段输入 `notes` .
另一个例子是被誉为“鸟类训练师”的雷·伯维克。你可以放进去 `role = 'trainer of the birds'` 但是如果你想找所有的驯兽师呢?你可以有详细的和规范化的角色,详细的角色是“鸟的驯兽师”,规范化的角色是“动物驯兽师”。取决于你想完成什么。
可能会有更多的改进,但它们取决于您对数据的处理方式。

相关问题