你好我正面对以下......
两个DB表(mysql myisam表 - 没有外键约束)'MASTER'和'CHILD'。 'CHILD'db表中的行使用 parent_id * 列 *在'MASTER'表中引用单行(1:M)。
问题是parent_id列有2个“类型”的值:
我很困惑。这只是一个糟糕的数据库设计吗?通常的做法是使用用于引用另一个表中“父行”的列中的不同值来区分“数据库表中的哪些行表示”。
如果您不感到困惑并且可以提供帮助,请执行以下操作:)
答案 0 :(得分:2)
通常使用可以为空的外键约束来执行此操作。将单个列用于两个不同的事物的想法通常是个坏主意。可空的外键约束强制非空值具有参照完整性,但仍允许子表中的孤立。
不具有外键的问题是有人可以在子表中插入主表中没有相应行的值(或稍后删除主表中引用的行) 。
那是不一个好的设计 - 数据库应该对自己的完整性负责。
答案 1 :(得分:2)
当你在讨论表格中的哪些行时,实际上意味着",你正在跨越逻辑数据建模到概念数据建模,即数据的语义。通常,在一个表中存储关于实际含义的两种不同类型的行是一个坏主意。
从速度的角度来看,这是一个糟糕的主意,因为大多数查询都会涉及额外的磁盘,以清除与当前查询无关的行。
从产生无错误代码的角度来看,这是一个糟糕的主意,因为你忘了清除那些不合适的行,你会得到错误的结果。
从灵活性的角度来看,这是一个坏主意,因为当需求发生变化时,不恰当地绑定在一起的数据更难以改变。
设计糟糕。
话虽如此,在精心设计的数据库中有可选的FK字段。在这种情况下,选择退出关系的行包含NULL,而不是单元格中的零。但是,即使在这种情况下,其余列的语义也不会受到关系是否存在的影响。
答案 2 :(得分:1)
我没有足够的信息来说明这是不是一个糟糕的设计。
对我而言,这听起来像是标准的一对多关系。
您对CHILD
列中引用MASTER
的两个不同值感到不安。这听起来像是向我表示可以为空的外键的通常方式。它表示您可以拥有不属于任何CHILD
行的MASTER
行。任何示例都是学校的数据库,该数据库将一个或多个STUDENT
行分配给SCHOOL
行。
STUDENT
表的引用可以为null;毕竟,我们不会杀死/删除恰好未被分配到学校的STUDENT
,对吗?
我会问为什么没有使用null值。你确定你没有看到你的数据库代表null的方式吗?如果有人发明了他们自己的做法,并且在任性或无知的情况下绕过了零,那就称之为糟糕的设计。
两个表都必须有主键。最好是CHILD引用的MASTER列是MASTER表的主键。如果没有,称之为糟糕的设计。
更新:我可以想到一个可以解释它的历史原因。
在ISAM引擎出现之前,旧版本的MySQL没有强制引用完整性。您的架构可能是在ISAM之前开发的,因此开发人员决定他们必须自己管理参照完整性。如果您已更新为ISAM,则可能未将架构与其一起移植。
如果我对历史的假设不正确,请忽略这个想法。
答案 3 :(得分:0)
这是非常糟糕的设计。你想要的是第三个,链接或加入表有两列:你所谓的子表的id和主表中的id。对于子表中当前具有非零父ID的每一行,此表中都会有一个条目。
更新:可能'非常糟糕'是一个过度语句,因为你可以使用可以为空的外键,正如其他人所说,但它应该取决于空值的频率。如果大多数行的主链接都是非空链接,那么使用可空的FK,否则使用链接表。