我正在使用带有php的mysql数据库来构建Web应用程序。
我有一个子表attachment
,它是许多主表的通用表:teacher
、student
、classRoom
(和其他)。主表数超过 10 个,假设 n 个表。
我的问题是,这是一个好的做法:
-
在数据库中只创建一个名为"附件"的表,并将其与其主节点相关联。
这将导致附件表中有 n 个外键(即:n-1 个未使用的列),这也会导致模型中的 n-1 个属性,而无需在每次创建模型时进行初始化或使用。 -
为每个主表 (master_i) 创建一个名为 (master_i_Attachment) 的表,并将其仅与其主表相关联。但这会导致我的代码中有 n 个附件表和 n 个附件模型。
有什么建议吗?
做的是只有一个包含以下字段的表:id,reference_id(您的父表之一),reference_type(即reference_id属于哪个表),(附件表中的所有其他字段)。
然后,例如,如果要获取特定父类型的附件,则可以对该类型运行 SELECT 查询过滤,例如 WHERE reference_type='classroom'。
或者,如果要获取具有特定 ID 的教室附件:
SELECT * FROM attachment WHERE reference_id=<ID> AND reference_type = 'classroom';
您可能希望在 (reference_id, reference_type) 上有一个复合唯一键,这将确保您不会获得重复的附件(除非您希望给定类型的给定 ID 具有多个附件的可能性,在这种情况下,键不应该是唯一的)。
此解决方案是否适合您的需求取决于您将如何使用数据,即您将最常运行的查询类型。
基于数据库规范化概念,不建议在数据库中使用冗余和未初始化(或 null)值。实际上,规范化试图越来越多地隔离数据(这意味着任何异常都有更多的表)。但是,您可以简单地忽略规则或因性能问题而对数据库进行非规范化。
在您的情况下,我认为最简单(和规范化)的方法是选择编号 #2(每种附件类型的单独表)。但是你可以像Ashalynd所说的那样调整你的设计。在表中放置一个type
列以指定父表。顺便说一句,使用此方法会增加数据库中级联更改的复杂性。