Mysql Sql在创建表集合时的正确做法

Mysql Sql在创建表集合时的正确做法,mysql,sql,Mysql,Sql,我不知道该怎么称呼这个帖子,但我的问题是: 我有两个表格:Online\u Module&Offline\u Module这两个表格在我的程序中用于确定学习模块是在线学习还是在现场学习 现在我还有一个名为Academy的表。学院由许多模块组成。为此,我想创建以下子表:Academy\u has\u Module 问题就在这里。由于在线\u模块和离线\u模块不在同一个表中,因此myAcademy\u has \u模块中的一个值将始终为null 以下是一些显示这些表格组成的图片: 如您所见,其中

我不知道该怎么称呼这个帖子,但我的问题是:

我有两个表格:
Online\u Module
&
Offline\u Module
这两个表格在我的程序中用于确定学习模块是在线学习还是在现场学习

现在我还有一个名为
Academy
的表。
学院由许多模块组成。为此,我想创建以下子表:
Academy\u has\u Module

问题就在这里。由于
在线\u模块
离线\u模块
不在同一个表中,因此my
Academy\u has \u模块
中的一个值将始终为
null

以下是一些显示这些表格组成的图片:

如您所见,其中一个值将始终为
null
。我想知道,在这种情况下,什么是最佳做法?

1)创建一个表模块,保存在线和离线模块的公共字段:

id INT,
description
material
status
category
2) 然后保留脱机/联机模块表(编辑:减去字段-除了id字段-您现在保留在模块表中),但使用模块表作为中间链接,使它们FK引用新模块表

编辑: 现在,不要用太多的东西来压倒你,但有几个问题你必须自己问答,即: -模块只能脱机/联机吗? -如果是,我是否希望在DB中100%强制执行它

因为在我的解决方案中,您可以有一个模块,并由多个脱机/联机模块引用。有很多方法可以解决这个问题,但我认为它们远远超出了你的要求,我只是想让你知道

至于获取信息(可能不是最好的,但这是我目前的水平,如果有人知道得更好,请随意教我一个新技巧:))*注意:难看的编码,太累了,无法使用完整的编码样式:D*:

select *, case 
when OffM.Id is null and OnM.Id is null then 'No module!'
when OffM.Id is not null and OnM.Id is not null then 'Too many modules!'
when OffM.Id is null and OnM.Id is not null then 'Online module!'
when OffM.Id is not null and OnM.Id is null then 'Offline module!'
end --probably a different, better way to compare?
  from Academy_has_Module as AHM
  join Module as M
    on Academy.Module = M.Id
left join OfflineModule as OffM
    on OffM.ModuleID = M.Id
left join OnlineModule as OnM
    on OnM.ModuleID = M.Id
但现在,据我所知,如果您在模块表中添加了ModuleType,ORM框架(老实说,我并没有太多使用它们,所以没有第一手经验)可以使用它来返回正确类的对象。但这将深入到项目中使用的整个体系结构和技术中,超出了这个问题的范围,甚至超出了我的实际经验

EDIT2: 好的,我想到的另一件事是:以某种方式将在线/离线模块表结构更改为相同是否合理?例如,在线模块: -可能有一位导师/负责人作为weel -可以随时开放 -脱机模块没有名称? -在线模块的位置应为ie“在线” 只需将这些表与ModuleType(约束或FK)合并到枚举表中(不确定英语中正确的术语是什么)。也许有点强迫,但是(同样,这很大程度上取决于总体需求,我从未见过在一次迭代中添加一个简单的表,它总是影响一些东西,并在设计中传播)可以使您的生活变得简单。有时候,最好是在每条记录上浪费几个字节的空间,然后试图表现得太可爱,然后在以后的道路上被咬

祝您度过愉快的一天

1)创建一个表格模块,其中包含在线和离线模块的常用字段:

id INT,
description
material
status
category
2) 然后保留脱机/联机模块表(编辑:减去字段-除了id字段-您现在保留在模块表中),但使用模块表作为中间链接,使它们FK引用新模块表

编辑: 现在,不要用太多的东西来压倒你,但有几个问题你必须自己问答,即: -模块只能脱机/联机吗? -如果是,我是否希望在DB中100%强制执行它

因为在我的解决方案中,您可以有一个模块,并由多个脱机/联机模块引用。有很多方法可以解决这个问题,但我认为它们远远超出了你的要求,我只是想让你知道

至于获取信息(可能不是最好的,但这是我目前的水平,如果有人知道得更好,请随意教我一个新技巧:))*注意:难看的编码,太累了,无法使用完整的编码样式:D*:

select *, case 
when OffM.Id is null and OnM.Id is null then 'No module!'
when OffM.Id is not null and OnM.Id is not null then 'Too many modules!'
when OffM.Id is null and OnM.Id is not null then 'Online module!'
when OffM.Id is not null and OnM.Id is null then 'Offline module!'
end --probably a different, better way to compare?
  from Academy_has_Module as AHM
  join Module as M
    on Academy.Module = M.Id
left join OfflineModule as OffM
    on OffM.ModuleID = M.Id
left join OnlineModule as OnM
    on OnM.ModuleID = M.Id
但现在,据我所知,如果您在模块表中添加了ModuleType,ORM框架(老实说,我并没有太多使用它们,所以没有第一手经验)可以使用它来返回正确类的对象。但这将深入到项目中使用的整个体系结构和技术中,超出了这个问题的范围,甚至超出了我的实际经验

EDIT2: 好的,我想到的另一件事是:以某种方式将在线/离线模块表结构更改为相同是否合理?例如,在线模块: -可能有一位导师/负责人作为weel -可以随时开放 -脱机模块没有名称? -在线模块的位置应为ie“在线” 只需将这些表与ModuleType(约束或FK)合并到枚举表中(不确定英语中正确的术语是什么)。也许有点强迫,但是(同样,这很大程度上取决于总体需求,我从未见过在一次迭代中添加一个简单的表,它总是影响一些东西,并在设计中传播)可以使您的生活变得简单。有时候,最好是在每条记录上浪费几个字节的空间,然后试图表现得太可爱,然后在以后的道路上被咬


祝您愉快

这是超类/子类设计(或超级实体/子实体,如果愿意)。要扩展@VladislavZalesak的答案,请将公共属性放入超级实体表中。但不要忘记实施适当的数据完整性检查

create table Module(
    ID          int  not null primary key,
    ModType     char( 1 ) not null,
    Name        varchar( 45 ) not null,
    Description text,
    MaterialID  int,
    StatusID    int,
    CategoryID  int,
    constraint TypeCK check( ModType in( 'O', 'F' ))
);
create unique index ModuleType_UIX on Module( ID, ModType );
现在,如果ID是PK,那么它必须是唯一的。那么,你会问,为什么我们要用ID和Mod创建一个唯一的索引呢