mysql - 创建相关表以避免可能的空字段
问题描述
假设我有一个名为movie_celebrity的表,其中包含以下列:
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
)
解决方案
您似乎正在尝试制作一个组合的“演员和工作人员”表。根据您的用途,将它们全部组合在一张桌子上可能是个好主意,或者最好有单独的“演员”和“工作人员”。我会说从一个组合表开始,看看情况如何。如果它不起作用,您可以拆分表并创建一个视图以实现向后兼容。
根据作者的评论,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 列为任何其他数据位提供了灵活性,而无需添加更多列。
例如,阿尔弗雷德·希区柯克在《鸟》中的无名露面……
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>
是他们各自的ID。
然后再次担任制片人和导演。
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');
而阿尔弗雷德希区柯克的助手佩吉罗伯逊可能会像这样利用notes
专栏。
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
在notes
.
另一个例子是被誉为“鸟类训练师”的雷·伯维克。你可以输入,role = 'trainer of the birds'
但如果你想搜索所有的动物训练师怎么办?您可以有逐字和标准化角色,逐字角色是“鸟类训练师”,而标准化角色是“动物训练师”。取决于您要完成的工作。
可能会有更多改进,但它们取决于知道您想对数据做什么。
推荐阅读
- python - 如何在保持 y 值范围的同时结合两个 Seaborn 线图?
- javascript - 将 javascript 用于条纹元素
- angular - 带有使用按钮的播放列表的音频播放器
- timescaledb - 表属性 "_timescaledb_cache" , _timescaledb_catalog, _timescaledb_internal" 这些在做什么?
- python - 如何生成 Google Cloud KMS 密钥并附加云存储桶
- scala - 为什么使用函数 span 时缺少第一个元素?
- api - Zapier 从 Tsheets 数据在 Google 表格中创建多行
- ios - 使用自动布局将子视图添加到另一个子视图
- javascript - Epson Tm-30 epos 使用 javascript 打印 Web 应用程序中的连接超时问题
- javascript - 点击事件在表中被触发两次